From a8de6652d68bd1dc0e0db8fb18741d4826d6f3cb Mon Sep 17 00:00:00 2001 From: Ryszard Glab Date: Sat, 12 Aug 2000 13:12:55 +0000 Subject: [PATCH] ChangeLog 2000-08-12 15:20 UTC+0100 --- harbour/ChangeLog | 22 ++++++ harbour/source/compiler/harbour.l | 119 ++++++++++++++++++++++++------ harbour/source/compiler/harbour.y | 5 ++ harbour/source/pp/ppcore.c | 2 +- 4 files changed, 124 insertions(+), 24 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index d095360318..1392abc003 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,25 @@ +2000-08-12 15:20 UTC+0100 Ryszard Glab + + *source/pp/ppcode.c + * fixed '\`' into '`' to stop warning in GCC + + *source/compiler/harbour.l + * fixed handling of TEXT/ENDTEXT - it is not active now + 'if( 0 )' since it requires more support from the preprocessor. + The preprocessor have to set some flag when text block is + processed to suppres errorneous compilation if normal + (not preprocessed) code in case of: + QOUT([some]) ; QOUT([string]) + * added support for nested '[]' string delimiters that can + be created by the preprocessor + * fixed handling of 'FOR(' syntax - it is now fully + Clipper compatible. + + *source/compiler/harbour.y + * fixed handling of FOR (expression):=... TO ... syntax + ( Clipper compiles: FOR (a:=1,b:=2,i):=1 TO 10 ) + although it needs some more work. + 2000-07-29 03:00 UTC+0500 April White + doc/en/ + (re)added hbvm.txt, hbapiitm.txt, hbapirdd.txt, hbmacro.txt, diff --git a/harbour/source/compiler/harbour.l b/harbour/source/compiler/harbour.l index 6bfe94e659..78603929c5 100644 --- a/harbour/source/compiler/harbour.l +++ b/harbour/source/compiler/harbour.l @@ -161,12 +161,24 @@ Separator {SpaceTab} NOTE: Clipper allows for [[nested]] only if it is preprocessed from TEXT/ENDTEXT block - in normal code the preprocesor uses the first closing ] as a string terminator. + However we have to get some information from the preprocessor about + TEXT/ENDTEXT block start/end condition to distinguish code: + TEXT + some string]) ; qout([some more + ENDTEXT + from direct calls for qout function + QOUT([some string]) ; QOUT([some more]) */ - BEGIN STRING4START; - unput( '(' ); + if( 0 /* TODO: hb_ppInsideTextBlock */ ) + { + BEGIN STRING4START; + unput( '(' ); + } + else + yyless( 4 ); /* len of QOUT */ + yylval.string = hb_compIdentifierNew( "QOUT", TRUE ); hb_comp_iState = IDENTIFIER; - return IDENTIFIER; } @@ -204,22 +216,79 @@ Separator {SpaceTab} return LITERAL; } -[^\]\n]*\] { BEGIN 0; - yytext[--yyleng] = '\0'; - yylval.string = hb_compIdentifierNew( yytext, TRUE ); - hb_comp_iState = LITERAL; +.*\n { + /* Preprocessed strings can contain embeded ] chars, for example + #translate TEST_STRING( ) => # + ? TEST_STRING( "['']" ) is preprocessed into ["['']"] so the string + terminator is "] pair + ? TEST_STRING( ['""'] ) is preprocessed into [['""']] so the string + terminator is ]] pair + There is however a single problem: any string with nested [] + created by the preprocessor is compiled correctly in Clipper but + the same string passed directly in the code is compiled until + the first closing bracket is found! We are not following it here + because at this moment there is no possibility to distinguish + strings created by the preprocessor. + */ + char StopChar = yytext[ 0 ]; + int iFirstPos = 0; + BEGIN 0; + + if( (StopChar == '"') || (StopChar == '\'') || (StopChar == '[') ) + { + int i = 0; + if( StopChar == '[' ) + StopChar = ']'; + for( i = 0; i < yyleng-1; ++i ) + { + if( (yytext[ i ] == StopChar) && yytext[ i + 1 ] == ']' ) + { + /* "] or '] terminator was found */ + yyless( i+2 ); + yytext[ i+1 ] = '\0'; + yylval.string = hb_compIdentifierNew( yytext, TRUE ); + hb_comp_iState = LITERAL; - return LITERAL; - } + return LITERAL; + } + else if( (yytext[ i ] == ']') && iFirstPos == 0 ) + iFirstPos = i; + } + if( iFirstPos > 0 ) + { + yyless( iFirstPos+1 ); + yytext[ iFirstPos+1 ] = '\0'; + yylval.string = hb_compIdentifierNew( yytext, TRUE ); + hb_comp_iState = LITERAL; -[^\]\n]*\n { BEGIN 0; - unput( '\n' ); - yytext[--yyleng] = '\0'; - hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_STRING_TERMINATOR, yytext, NULL ); - hb_comp_iState = LOOKUP; + return LITERAL; + } + } + else + { + /* look for the first closing ] character */ + int i; + for( i = 0; i < yyleng - 1; ++i ) + { + if( yytext[ i ] == ']' ) + { + yyless( i+1 ); + yytext[ i ] = '\0'; + yylval.string = hb_compIdentifierNew( yytext, TRUE ); + hb_comp_iState = LITERAL; - return LITERAL; - } + return LITERAL; + } + } + } + /* If we are here then the terminator was not found - report an error */ + unput( '\n' ); + yytext[--yyleng] = '\0'; + hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_STRING_TERMINATOR, yytext, NULL ); + hb_comp_iState = LOOKUP; + + return LITERAL; +} \( { BEGIN STRING4; return( '(' ); } . { BEGIN 0; unput( yytext[ yyleng-1 ] ); } @@ -655,14 +724,18 @@ Separator {SpaceTab} } {Separator}*[\(] { /* function call */ BEGIN 0; - if( hb_comp_iState == LOOKUP ) - { /* Clipper does not like FOR() at the begining of line */ - hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_SYNTAX, yytext, NULL ); - } - yylval.string = hb_compIdentifierNew( "FOR", TRUE ); - hb_comp_iState =IDENTIFIER; unput( yytext[ yyleng-1 ] ); - return IDENTIFIER; + if( hb_comp_iState == LOOKUP ) + { /* Clipper always assume FOR (somevar):=1 TO ... here */ + hb_comp_iState =FOR; + return FOR; + } + else + { + yylval.string = hb_compIdentifierNew( "FOR", TRUE ); + hb_comp_iState =IDENTIFIER; + return IDENTIFIER; + } } .|\n { /* there is no identifier after "FOR" */ BEGIN 0; diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 70d41817ea..a4e42199a9 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -125,6 +125,9 @@ static PTR_LOOPEXIT hb_comp_pLoops = NULL; static HB_RTVAR_PTR hb_comp_rtvars = NULL; char * hb_comp_szAnnounce = NULL; /* ANNOUNCEd procedure */ + +static void hb_compDebugStart( void ) { }; + %} %union /* special structure used by lex and yacc to share info */ @@ -716,6 +719,7 @@ LValue : IdentName { $$ = hb_compExprNewVar( $1 ); } | MacroExpr | ObjectData | VariableAt + | PareExpList { $$ = hb_compExprListStrip( $1, NULL ); } ; /* NOTE: PostOp can be used in one context only - it uses $0 rule @@ -1443,6 +1447,7 @@ EndWhile : END ForNext : FOR LValue ForAssign Expression /* 1 2 3 4 */ { hb_compLinePush(); + hb_compDebugStart(); ++hb_comp_wForCounter; /* 5 */ $$ = hb_compExprGenStatement( hb_compExprAssign( $2, $4 ) ); } diff --git a/harbour/source/pp/ppcore.c b/harbour/source/pp/ppcore.c index cd1c293077..742c31afd5 100644 --- a/harbour/source/pp/ppcore.c +++ b/harbour/source/pp/ppcore.c @@ -2612,7 +2612,7 @@ static int md_strAt( char * szSub, int lSubLen, char * szText, BOOL checkword, B lPos++; continue; } - else if( ( *(szText+lPos) == '\'' || *(szText+lPos) == '\`' ) && ( lPos == 0 || *(szText+lPos-1) != '\\' ) ) + else if( ( *(szText+lPos) == '\'' || *(szText+lPos) == '`' ) && ( lPos == 0 || *(szText+lPos-1) != '\\' ) ) { State = STATE_QUOTE1; lPos++;