From 0fb8020f4037d7716d512dce668f162ff3abaf95 Mon Sep 17 00:00:00 2001 From: Ryszard Glab Date: Fri, 7 May 1999 06:19:59 +0000 Subject: [PATCH] See ChangeLog: 19990507-07:25 --- harbour/source/compiler/harbour.l | 65 ++++++++++++----- harbour/source/compiler/harbour.y | 56 +++++++-------- harbour/source/vm/hvm.c | 2 +- harbour/tests/working/keywords.prg | 112 +++++++++++++++++++++++++++++ 4 files changed, 185 insertions(+), 50 deletions(-) create mode 100644 harbour/tests/working/keywords.prg diff --git a/harbour/source/compiler/harbour.l b/harbour/source/compiler/harbour.l index c013d467e8..7231147335 100644 --- a/harbour/source/compiler/harbour.l +++ b/harbour/source/compiler/harbour.l @@ -1,13 +1,12 @@ %{ - /* * $Id$ * * Harbour lex rules. * Build 21: Spring 99 - * Usage: flex -i -oyylex.c harbour.l + * Usage: flex -i -8 -oyylex.c harbour.l * You may find flex.exe at www.harbour-project.org - */ +*/ #include #include @@ -52,9 +51,7 @@ long lNumber = 0; #define LOOKUP 0 int _iState = LOOKUP; -/* -//Separator {SpaceTab}|("/ *".*"* /")|"//".* -*/ +//Comment1 "/*"((.*)|(\n))"*/" %} @@ -66,14 +63,15 @@ Identifier (([a-zA-Z])|([_a-zA-Z][_a-zA-Z0-9]+)) String (\"(([^\"]*)|([\!]*))\")|(\'(([^\']*)|([\!]*))\') PseudoFunc {Identifier}"("+.*")"+ -Comment1 [\/][\*]([^\*]|[\*][^\/])*[\*][\/] +Comment1 "/*"([^\*]|("*"[^\/]))*"*/" Comment2 [\/][\/].* Comment ({Comment1}|{Comment2}) -Separator {SpaceTab}|{Comment} +LineCont (;.*\n) +Separator {SpaceTab}|{Comment}|{LineCont} %x COMMENT3 DEFINE DEFINE_PARAMS DEFINE_EXPR %x IFDEF IFNDEF STRING1 STRING2 -%x _NEXT +%x NEXT_ BREAK_ %% @@ -141,9 +139,36 @@ Separator {SpaceTab}|{Comment} \n.* _iState=LOOKUP; yyless( 1 ); ++iLine; if( ! _iQuiet ) printf( "\rline: %i", iLine ); return '\n'; ;\n _iState=LOOKUP; ++iLine; if( ! _iQuiet ) printf( "\rline: %i", iLine ); -"begin" return BEGINSEQ; -"break" _iState =BREAK; return BREAK; -"case" _iState =CASE; return CASE; +"begin"{Separator}+"sequ"("ence"|"enc"|"en"|"e")? return BEGINSEQ; +"break" BEGIN BREAK_; +{Separator}*\n { /* at the end of line */ + BEGIN 0; + unput( yytext[ yyleng-1 ] ); + if( _iState == LOOKUP ) + { /* it is first item in the line */ + return BREAK; + } + else + { /* there is another item in line already */ + yylval.string = "BrEaK"; + return IDENTIFIER; + } + } +{Separator}*[^_a-zA-Z] { /* there is no identifier after "break" */ + BEGIN 0; + yylval.string = ((yytext[ yyleng-1 ] =='(')?"BREAK":"BrEaK"); + _iState =IDENTIFIER; + unput( yytext[ yyleng-1 ] ); + return IDENTIFIER; + } +{Separator}*. { /* an identifier follows BREAK statement */ + BEGIN 0; + unput( yytext[ yyleng-1 ] ); + _iState =BREAK; + return BREAK; + } +. { BEGIN 0; unput( yytext[ yyleng-1 ] ); } +"case" return CASE; "do" return DO; "do"{SpaceTab}+"case" return DOCASE; ("do"{SpaceTab}+"while")|"while" return WHILE; @@ -153,12 +178,13 @@ Separator {SpaceTab}|{Comment} "endif" return ENDIF; "endcase" return ENDCASE; "enddo" return ENDDO; +"end"{Separator}+"sequ"("ence"|"enc"|"en"|"e")? return END; "exit"/[\n\;] return EXITLOOP; "exit" return EXIT; "extern"|"external" _iState =EXTERN; return EXTERN; "field"/[^(] _iState =FIELD; return FIELD; "for" _iState = FOR; return FOR; -"func"|"funct"|"functi"|"functio"|"function"/[^(] return FUNCTION; +"func"|"funct"|"functi"|"functio"|"function"/[^(] _iState=FUNCTION; return FUNCTION; ("if"|"iif"){SpaceTab}*/[(] _iState =IF; return IF; "if" _iState =IF; return IF; "in" return IN; @@ -167,8 +193,8 @@ Separator {SpaceTab}|{Comment} "local" _iState =LOCAL; return LOCAL; "loop" return LOOP; "memvar" _iState =MEMVAR; return MEMVAR; -"next" BEGIN _NEXT; -<_NEXT>{Separator}*[\n\;] { /* at the end of line */ +"next" BEGIN NEXT_; +{Separator}*[\n\;] { /* at the end of line */ BEGIN 0; if( _iState == LOOKUP ) { /* it is first item in the line */ @@ -182,20 +208,20 @@ Separator {SpaceTab}|{Comment} return IDENTIFIER; } } -<_NEXT>{Separator}*[^_a-zA-Z\n\;] { /* there is no identifier after "next" */ +{Separator}*[^_a-zA-Z\n\;] { /* there is no identifier after "next" */ BEGIN 0; yylval.string = ((yytext[ yyleng-1 ] =='(')?"NEXT":"nExT"); unput( yytext[ yyleng-1 ] ); _iState =IDENTIFIER; return IDENTIFIER; } -<_NEXT>{Separator}*. { /* an identifier follows NEXT statement */ +{Separator}*. { /* an identifier follows NEXT statement */ BEGIN 0; unput( yytext[ yyleng-1 ] ); _iState =NEXT; return NEXT; } -<_NEXT>. { BEGIN 0; unput( yytext[ yyleng-1 ] ); } +. { BEGIN 0; unput( yytext[ yyleng-1 ] ); } "nil" return NIL; "otherwise" return OTHERWISE; "parameters" _iState =PARAMETERS; return PARAMETERS; @@ -205,7 +231,6 @@ Separator {SpaceTab}|{Comment} "qself"{SpaceTab}*[(]{SpaceTab}*[)] return SELF; "recover" _iState =RECOVER; return RECOVER; "retu"|"retur"|"return" _iState =RETURN; return RETURN; -"sequence" return SEQUENCE; "static" _iState =STATIC; return STATIC; "step"/[^(] return STEP; "to" return TO; @@ -282,6 +307,8 @@ Separator {SpaceTab}|{Comment} {String} yylval.string = strdup( yytext + 1 ); yylval.string[ yyleng - 2 ] = 0; return LITERAL; +{LineCont} { ++iLine; } + {Identifier} { PDEFINE pDef = FindDef( yytext ); char * szText; int c; diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 29242dbaed..6cb6a2733b 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -1,5 +1,4 @@ %{ - /* * $Id$ * @@ -335,9 +334,14 @@ static const char * _szReservedFun[] = { }; #define RESERVED_FUNCTIONS sizeof(_szReservedFun) / sizeof(char *) /* function compares strings upto maximum 4 characters (used in bsearch) */ - +/* Borland C 3.1 reports error when this forward declaration is used + * int sz_compare4( const void *, const void * ); + * + */ /* Compare first 4 characters * If they are the same then compare the whole name + * SECO() is not allowed because of Clipper function SECONDS() + * however SECO32() is a valid name. */ int sz_compare4( const void *pLookup, const void *pReserved ) { @@ -385,7 +389,7 @@ PEXTERN pExterns = 0; %token INC DEC ALIAS DOCASE CASE OTHERWISE ENDCASE ENDDO MEMVAR %token WHILE EXIT LOOP END FOR NEXT TO STEP LE GE FIELD IN PARAMETERS %token PLUSEQ MINUSEQ MULTEQ DIVEQ POWER EXPEQ MODEQ EXITLOOP -%token PRIVATE BEGINSEQ BREAK RECOVER USING SEQUENCE DO WITH SELF +%token PRIVATE BEGINSEQ BREAK RECOVER USING DO WITH SELF /*the lowest precedence*/ /*postincrement and postdecrement*/ @@ -493,6 +497,8 @@ Statement : ExecFlow Crlf {} | ObjectData ArrayIndex '=' Expression Crlf {} | ObjectMethod ArrayIndex '=' Expression Crlf {} + | BREAK Crlf + | BREAK Expression Crlf | RETURN Crlf { GenReturn( Jump( 0 ) ); } | RETURN Expression Crlf { GenPCode1( _RETVALUE ); GenReturn( Jump ( 0 ) ); } | PUBLIC VarList Crlf @@ -887,22 +893,14 @@ ForStatements : ForStat NEXT ForStat : Statements { Line(); } ; -BeginSeq : BEGINSEQ SEQUENCE Crlf - BreakSeq +BeginSeq : BEGINSEQ Crlf RecoverSeq - EndSeq + END - | BEGINSEQ SEQUENCE Crlf Statements - BreakSeq + | BEGINSEQ Crlf + Statements RecoverSeq - EndSeq - ; - -BreakSeq : /* no break */ - | BREAK Crlf - | BREAK Crlf Statements - | BREAK Expression Crlf - | BREAK Expression Crlf Statements + END ; RecoverSeq : /* no recover */ @@ -912,10 +910,6 @@ RecoverSeq : /* no recover */ | RECOVER USING IDENTIFIER Crlf Statements ; -EndSeq : END - | END SEQUENCE - ; - DoProc : DO IDENTIFIER { PushSymbol( $2, 1 ); PushNil(); Do( 0 ); } | DO IDENTIFIER { PushSymbol( $2, 1 ); PushNil(); } WITH ArgList { Do( $5 ); } ; @@ -982,6 +976,8 @@ int harbour_main( int argc, char * argv[] ) char *szPath =""; FILENAME *pFileName =NULL; + printf( "Harbour compiler\nbuild %i Spring 1999\n", BUILD ); + if( argc > 1 ) { /* Command line options */ @@ -1090,9 +1086,6 @@ int harbour_main( int argc, char * argv[] ) iArg++; } - if( ! _iQuiet ) - printf( "Harbour compiler\nbuild %i Spring 1999\n", BUILD ); - if( pFileName ) { if( !pFileName->extension ) @@ -1582,8 +1575,11 @@ void FunDef( char * szFunName, char cScope ) /* stores a Clipper defined functi } pFunction =(char * *)RESERVED_FUNC( szFunName ); - if( pFunction ) + if( pFunction && !(functions.iCount==0 && !_iStartProc) ) { + /* We are ignoring it when it is the name of PRG file and we are + * not creating implicit starting procedure + */ GenError( ERR_FUNC_RESERVED, *pFunction, szFunName ); } @@ -1621,19 +1617,19 @@ void FunDef( char * szFunName, char cScope ) /* stores a Clipper defined functi void GenJava( char *szFileName, char *szName ) { printf( "\ngenerating Java language output...\n" ); - printf( "%s -> not implemented yet!\n", szFileName ); + printf( "%s -> not implemented yet! %s\n", szFileName, szName ); } void GenPascal( char *szFileName, char *szName ) { printf( "\ngenerating Pascal language output...\n" ); - printf( "%s -> not implemented yet!\n", szFileName ); + printf( "%s -> not implemented yet! %s\n", szFileName, szName ); } void GenRC( char *szFileName, char *szName ) { printf( "\ngenerating resources output...\n" ); - printf( "%s -> not implemented yet!\n", szFileName ); + printf( "%s -> not implemented yet! %s\n", szFileName, szName ); } void GenCCode( char *szFileName, char *szName ) /* generates the C language output */ @@ -2477,7 +2473,7 @@ int GetLocalVarPos( char * szVarName ) /* returns the order + 1 of a variable if } /* - * Gets position of passed static variables. + * Gets position of passed static variables. * All static variables are hold in a single array at runtime then positions * are numbered for whole PRG module. */ @@ -3075,7 +3071,7 @@ int FieldsCount() /* * Start of definition of static variable - * We are using here the special function _pInitFunc which will store + * We are using here the special function _pInitFunc which will store * pcode needed to initialize all static variables declared in PRG module. * pOwner member will point to a function where the static variable is * declared: @@ -3105,7 +3101,7 @@ void StaticDefStart( void ) } -/* +/* * End of definition of static variable * Return to previously pcoded function. */ diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 06f2d2d937..f2c7462190 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -165,7 +165,7 @@ BYTE bErrorLevel = 0; /* application exit errorlevel */ stack.Return.wType = IT_NIL; StackInit(); NewDynSym( &symEval ); /* initialize dynamic symbol for evaluating codeblocks */ - InitializeSets(); /* initialize Sets */ + HB_init_set(); /* initialize Sets */ DoInitFunctions( argc, argv ); /* process defined INIT functions */ PushSymbol( pSymStart ); /* pushes first FS_PUBLIC defined symbol to the stack */ diff --git a/harbour/tests/working/keywords.prg b/harbour/tests/working/keywords.prg new file mode 100644 index 0000000000..dd819a4155 --- /dev/null +++ b/harbour/tests/working/keywords.prg @@ -0,0 +1,112 @@ +//DO NOT RUN THIS PROGRAM - ITS PURPOSE IS THE SYNTAX CHECK ONLY! + +STATIC nExt, bEgin, bReak + +Function Main() + + NEXT(nExt) + BEGIN( bEgin +';' + ; ////// + ";" ; /* ;;;;;just trying to be smart;;;;;;; */ + ) + BREAK_(bReak) + +RETURN nil + +/*================================================================ +************************************************ Checking for NEXT +*/ +FUNCTION NeXT( next_next/*next next*/ ) +Local nExt, nExt7, nExtNEXT + + For NExt := 1 To 10 + + OutStd( nExT ) // Actually this needs to use str() + + Next /*next*/ nExt //next +//NEXT + + nExt := 10 //next + + nExt++ /*n_ext*/ //--- + --nExt /*next*/ + nExt7 :=7 + nExtNEXT := nExt //next + + nExt[ nExt ] := NEXT( nExt[nExt+nExt] * nExt *(nExt+nExt*5) ) + + IF( nExt > nExt+4 ) + nExt =nExt +nExt * 5 + ELSEIF( nExt > 0 ) + nExt = nExt * 6 + nExt + ELSE + nExt +=5 + ENDIF + +RETURN( nExt * /*next*/ nExt ) + +/*=================================================================== +* Checking for BEGIN +*/ +FUNCTION BEGIN( BEGIN_BEGIN ) +//LOCAL bEgin, xbEgin , bEginBEGIN , bEgin0, xbEginBEGIN:=100 +LOCAL bEgin +LOCAL xbEgin +LOCAL bEginBEGIN +LOCAL bEgin0, /* BEGIN OF BEGIN */ ; /* begin */ + bEgin1 +LOCAL xbEginBEGIN := 100 + +BEGIN SEQUENCE + bEgin0 :=0 + FOR bEgin:=1 TO 10 + QOUT( bEgin ) + xbEgin :=bEgin + bEginBEGIN :=xbEgin * 10 + bEgin0 +=bEginBEGIN + --xbEginBEGIN + bEgin++ + --bEgin + NEXT bEgin + + bEgin :=BEGIN( xbegin +bEgin +bEginBEGIN -bEgin0 * xbEginBEGIN ) +; + bEgin[ bEgin ] + +END SEQUENCE + +BEGIN /* BEGIN */ SEQU + + BEGIN_BEGIN :=bEgin//begin + +END /* BEGIN */ SEQUENC + +RETURN bEgin ^ 2 + +/*==================================================================== +* Test for BREAK and BEGIN/RECOVER sequence +*/ +FUNCTION BREAK_( break_break ) +LOCAL bReak:=0 + + ++bReak + IF( bReak = 0 ) + Break /*break*/ ( nil ) + BREAK /* break to beggining */ + Break() //this line is not valid in Clipper: syntax error: ')' + ENDIF + + Break /* break in break */ ;;; +; ///////////// + () + +begin sequence + FOR bReak:=1 To 10 + QOut( bReak * bReak ) + NEXT bReak + BREAK + bReak :=IIF( bReak=1, BREAK(0), BREAK(bReak) ) +recover USING bReak + BREAK( Break( break() ) ) +end + +BREAK +RETURN bReak[ bReak ]