From c3dd8519a5d5adb4998ec810f438e0783cf042d3 Mon Sep 17 00:00:00 2001 From: Ryszard Glab Date: Tue, 8 Feb 2000 16:41:27 +0000 Subject: [PATCH] ChangeLog 20000208-17:55 GMT+1 --- harbour/ChangeLog | 24 ++++ harbour/source/compiler/harbour.l | 158 +++++++++++++++++++++-- harbour/source/compiler/harbour.y | 25 ++-- harbour/source/rtl/gt/gtstd.c | 7 ++ harbour/source/rtl/wait.prg | 17 ++- harbour/tests/keywords.prg | 202 +++++++++++++++++++++++++++++- 6 files changed, 400 insertions(+), 33 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 84c9545161..6efd2fb2f9 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,27 @@ +20000208-17:55 GMT+1 Ryszard Glab + + *source/compiler/harbour.y + *source/compiler/harbour.l + * fixed syntax for the following keywords: + OTHERWISE + PROCEDURE + RECOVER + RETURN + STATIC + USING + * added error generation in case repeated OTHERWISE clauses are + used in DO CASE statement + + *tests/keywords.prg + * added some more test code + + *source/rtl/wait.prg + * fixed code to stop generation of error 'unreachable code' + + *source/rtl/gt/gtstd.c + * added dummy function hb_gt_ReadKey() if compiled for U*ix + (I don't know why it worked previously without this function) + 20000208-12:00 GMT+1 Antonio Linares * tests/bld_b32.bat * updated to use latest Borland makefile changes diff --git a/harbour/source/compiler/harbour.l b/harbour/source/compiler/harbour.l index fb967ec27c..d16c42b46f 100644 --- a/harbour/source/compiler/harbour.l +++ b/harbour/source/compiler/harbour.l @@ -111,8 +111,8 @@ Separator {SpaceTab} %x STRING1 STRING2 STRING3 %x NEXT_ BREAK_ CASE_ DO_ WHILE_ WITH_ END_ EXIT_ EXTERNAL_ FIELD_ %x FOR_ FUNCTION_ IIF_ IF_ IN_ INIT_ LOCAL_ LOOP_ DECLARE_ -%x MEMVAR_ PARAM_ PRIVATE_ PUBLIC_ -%x INVALIDNUM_ +%x MEMVAR_ PARAM_ PRIVATE_ PUBLIC_ STATIC_ RETURN_ RECOVER_ +%x INVALIDNUM_ OTHERWISE_ PROCEDURE_ %s INDEX %% @@ -916,13 +916,40 @@ Separator {SpaceTab} /* ************************************************************************ */ %} "nil" hb_comp_iState =LITERAL; return NIL; -"otherwise" return OTHERWISE; +%{ +/* ************************************************************************ */ +%} +"othe"|"other"|"otherw"|"otherwi"|"otherwis"|"otherwise" { + yylval.string = hb_strupr( hb_strdup( yytext ) ); + BEGIN OTHERWISE_; + } +{Separator}*[\n\;] { /* end of line */ + unput( yytext[ yyleng-1 ] ); + if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; + if( hb_comp_iState == LOOKUP ) + { /* it is the first item in the line */ + hb_xfree( (void *) yylval.string ); + hb_comp_iState = OTHERWISE; + return OTHERWISE; + } + else + { /* there is another item in line already */ + hb_comp_iState =IDENTIFIER; + return IDENTIFIER; + } + } +{Separator}*. { + unput( yytext[ yyleng-1 ] ); + if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; + hb_comp_iState = IDENTIFIER; + return IDENTIFIER; + } %{ /* ************************************************************************ */ %} "para"|"param"|"parame"|"paramet"|"paramete"|"parameter"|"parameters" { - BEGIN PARAM_; yylval.string = hb_strupr( hb_strdup( yytext ) ); + BEGIN PARAM_; } {Separator}+[_a-zA-Z] { /* an identifier after PARAMETERS */ unput( yytext[ yyleng-1 ] ); @@ -975,7 +1002,16 @@ Separator {SpaceTab} %{ /* ************************************************************************ */ %} -"proc"|"procedure" return PROCEDURE; +"proc"|"proce"|"proced"|"procedu"|"procedur"|"procedure" BEGIN PROCEDURE_; +{Separator}+[_a-zA-Z] { + BEGIN 0; /* we can don't care about INDEX_STATE here */ + unput( yytext[ yyleng-1 ] ); + hb_comp_iState = PROCEDURE; + return PROCEDURE; + } +{Separator}*[^_a-zA-Z] { /* Clipper needs PROCEDURE in one context only */ + hb_compGenError( hb_comp_szErrors, 'E', ERR_SYNTAX, ((yytext[ yyleng-1 ]=='\n')?"PROCEDURE":yytext), NULL ); + } %{ /* ************************************************************************ */ %} @@ -1007,12 +1043,116 @@ Separator {SpaceTab} /* ************************************************************************ */ %} "qself"{SpaceTab}*[(]{SpaceTab}*[)] return SELF; -"recover" hb_comp_iState = RECOVER; return RECOVER; -"retu"|"retur"|"return" hb_comp_iState = RETURN; return RETURN; -"static" hb_comp_iState = STATIC; return STATIC; +%{ +/* ************************************************************************ */ +%} +"reco"|"recov"|"recove"|"recover" { + yylval.string = hb_strupr( hb_strdup( yytext ) ); + BEGIN RECOVER_; + } +{Separator}*[\n] { /* end of line */ + unput( yytext[ yyleng-1 ] ); + if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; + if( hb_comp_iState == LOOKUP ) + { /* it is first item in the line */ + hb_xfree( (void *) yylval.string ); + hb_comp_iState = RECOVER; + return RECOVER; + } + else + { /* there is another item in line already */ + hb_comp_iState =IDENTIFIER; + return IDENTIFIER; + } + } +{Separator}+("using"|"usin") { /* USING */ + if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; + hb_xfree( (void *) yylval.string ); + hb_comp_iState = RECOVERUSING; + return RECOVERUSING; + } +{Separator}*. { /* all other cases */ + unput( yytext[ yyleng-1 ] ); + if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; + hb_comp_iState =IDENTIFIER; + return IDENTIFIER; + } +%{ +/* ************************************************************************ */ +%} +"retu"|"retur"|"return" { + yylval.string = hb_strupr( hb_strdup( yytext ) ); + BEGIN RETURN_; + } +{Separator}+[\[\"\'\.\!\&\{\;_a-zA-Z0-9] { /* an identifier after RETURN, macro, or .NOT., or string, or EOL */ + unput( yytext[ yyleng-1 ] ); + if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; + if( hb_comp_iState == LOOKUP ) + { /* it is the first item in the line */ + hb_xfree( (void *) yylval.string ); + hb_comp_iState = RETURN; + return RETURN; + } + else + { /* there is another item in line already */ + hb_comp_iState =IDENTIFIER; + return IDENTIFIER; + } + } +{Separator}*[\n\(] { /* '(' after RETURN or end of line */ + unput( yytext[ yyleng-1 ] ); + if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; + if( hb_comp_iState == LOOKUP ) + { /* it is the first item in the line */ + hb_xfree( (void *) yylval.string ); + hb_comp_iState = RETURN; + return RETURN; + } + else + { /* there is another item in line already */ + hb_comp_iState =IDENTIFIER; + return IDENTIFIER; + } + } +{Separator}*. { /* any character after RETURN */ + unput( yytext[ yyleng-1 ] ); + if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; + hb_comp_iState =IDENTIFIER; + return IDENTIFIER; + } +%{ +/* ************************************************************************ */ +%} +"stat"|"stati"|"static" { + yylval.string = hb_strupr( hb_strdup( yytext ) ); + BEGIN STATIC_; + } +{Separator}+[_a-zA-Z] { /* an identifier after STATIC */ + unput( yytext[ yyleng-1 ] ); + if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; + if( hb_comp_iState == LOOKUP ) + { /* it is first item in the line */ + hb_xfree( (void *) yylval.string ); + hb_comp_iState = STATIC; + return STATIC; + } + else + { /* there is another item in line already */ + hb_comp_iState = IDENTIFIER; + return IDENTIFIER; + } + } +{Separator}*[^a-zA-Z] { /* any character (not identifier) after STATIC */ + unput( yytext[ yyleng-1 ] ); + if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; + hb_comp_iState =IDENTIFIER; + return IDENTIFIER; + } +%{ +/* ************************************************************************ */ +%} "step" return STEP; "to" return TO; -"using" return USING; %{ /* ************************************************************************ */ %} diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index ca09ff6a6d..ae0ddb613b 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -164,7 +164,8 @@ static char * hb_comp_szAnnounce = NULL; /* ANNOUNCEd procedure */ %token INC DEC ALIASOP 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 DO WITH SELF LINE MACROVAR MACROTEXT +%token PRIVATE BEGINSEQ BREAK RECOVER RECOVERUSING DO WITH SELF LINE +%token MACROVAR MACROTEXT %token AS_NUMERIC AS_CHARACTER AS_LOGICAL AS_DATE AS_ARRAY AS_BLOCK AS_OBJECT DECLARE_FUN /*the lowest precedence*/ @@ -308,7 +309,7 @@ Statement : ExecFlow CrlfStmnt { } | DoProc CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); } | BREAK CrlfStmnt { hb_compGenBreak(); hb_compGenPCode3( HB_P_DO, 0, 0 ); hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE; } - | BREAK { hb_compLinePushIfInside(); } Expression Crlf { hb_compGenBreak(); hb_compExprDelete( hb_compExprGenPush( $3 ) ); + | BREAK { hb_compLinePushIfInside(); } Expression Crlf { hb_compGenBreak(); hb_compExprDelete( hb_compExprGenPush( $3 ) ); hb_compGenPCode3( HB_P_DO, 1, 0 ); hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE; } @@ -342,11 +343,11 @@ Statement : ExecFlow CrlfStmnt { } hb_comp_bDontGenLineNum = TRUE; hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE; } - | PUBLIC { hb_compLinePushIfInside(); hb_comp_iVarScope = VS_PUBLIC; } - ExtVarList + | PUBLIC { hb_compLinePushIfInside(); hb_comp_iVarScope = VS_PUBLIC; } + ExtVarList { hb_compRTVariableGen( "__MVPUBLIC" ); } CrlfStmnt - | PRIVATE { hb_compLinePushIfInside(); hb_comp_iVarScope = VS_PRIVATE; } - ExtVarList + | PRIVATE { hb_compLinePushIfInside(); hb_comp_iVarScope = VS_PRIVATE; } + ExtVarList { hb_compRTVariableGen( "__MVPRIVATE" ); } CrlfStmnt | EXITLOOP CrlfStmnt { hb_compLoopExit(); hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE; } @@ -1240,6 +1241,8 @@ Cases : CASE Expression Crlf Otherwise : OTHERWISE Crlf { hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE; hb_compLinePush(); } EmptyStats + | Otherwise OTHERWISE { hb_compGenError( hb_comp_szErrors, 'E', ERR_MAYHEM_IN_CASE, NULL, NULL ); } Crlf + EmptyStats ; DoWhile : WhileBegin Expression Crlf @@ -1257,7 +1260,7 @@ DoWhile : WhileBegin Expression Crlf { hb_compGenJumpHere( $4 ); --hb_comp_wWhileCounter; hb_compLoopEnd(); - hb_comp_functions.pLast->bFlags &= ~ ( FUN_WITH_RETURN | FUN_BREAK_CODE ); + hb_comp_functions.pLast->bFlags &= ~ FUN_WITH_RETURN; } ; @@ -1371,13 +1374,13 @@ RecoverEmpty : RECOVER } ; -RecoverUsing : RECOVER USING IdentName +RecoverUsing : RECOVERUSING IdentName { hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE; $$ = hb_comp_functions.pLast->lPCodePos; --hb_comp_wSeqCounter; hb_compGenPCode1( HB_P_SEQRECOVER ); - hb_compGenPopVar( $3 ); + hb_compGenPopVar( $2 ); } ; @@ -1389,7 +1392,7 @@ RecoverUsing : RECOVER USING IdentName */ DoName : IdentName { $$ = hb_compExprNewFunName( $1 ); } | MacroVar { $$ = $1; } - | MacroExpr { $$ = $1; } + | MacroExpr { $$ = $1; } ; DoProc : DO DoName @@ -1840,9 +1843,9 @@ static void hb_compVariableDim( char * szName, HB_EXPR_PTR pInitValue ) HB_EXPR_PTR pVar = hb_compExprNewVar( szName ); HB_EXPR_PTR pAssign; + hb_compStaticDefStart(); /* switch to statics pcode buffer */ /* create a static variable */ hb_compVariableAdd( szName, 'A' ); - hb_compStaticDefStart(); /* switch to statics pcode buffer */ /* create an array */ hb_compExprGenPush( pInitValue ); hb_compGenPCode3( HB_P_ARRAYDIM, HB_LOBYTE( uCount ), HB_HIBYTE( uCount ) ); diff --git a/harbour/source/rtl/gt/gtstd.c b/harbour/source/rtl/gt/gtstd.c index 52f5c59e6a..003ba9272b 100644 --- a/harbour/source/rtl/gt/gtstd.c +++ b/harbour/source/rtl/gt/gtstd.c @@ -234,3 +234,10 @@ void hb_gt_SetBlink( BOOL bBlink ) s_bBlink = bBlink; } + +#if defined(OS_UNIX_COMPATIBLE) +int hb_gt_ReadKey( void ) +{ + return 0; +} +#endif \ No newline at end of file diff --git a/harbour/source/rtl/wait.prg b/harbour/source/rtl/wait.prg index 5bc5b1229b..b1b7726bd9 100644 --- a/harbour/source/rtl/wait.prg +++ b/harbour/source/rtl/wait.prg @@ -85,17 +85,16 @@ FUNCTION __Wait( cString ) IF ( bBlock := SetKey( nKey ) ) != NIL Eval( bBlock, ProcName( 1 ), ProcLine( 1 ), "" ) - LOOP - ENDIF - - IF nKey >= 32 .and. nKey <= 255 - ?? Chr( nKey ) ELSE - nKey := 0 + IF nKey >= 32 .and. nKey <= 255 + ?? Chr( nKey ) + ELSE + nKey := 0 + ENDIF + + EXIT ENDIF - - EXIT - + ENDDO RETURN Chr( nKey ) diff --git a/harbour/tests/keywords.prg b/harbour/tests/keywords.prg index cc54ad4bf9..4314b255f3 100644 --- a/harbour/tests/keywords.prg +++ b/harbour/tests/keywords.prg @@ -9,7 +9,7 @@ EXTERNAL __case, __begin STATIC nExt, bEgin, bReak, cAse, do, wHile, wIth, eXit, eXternal, fIeld -STATIC for, in, include, init, loop, local +STATIC for, in, include, init, loop, local, using, static, return, recover Function Main() @@ -62,7 +62,15 @@ Function Main() LOOP( loop ) -RETURN nil + USING( using ) + + STATIC( STATIC ) + + return :=return( return ) + + RECOVER( recover ) + +RETURN( return ) /*================================================================ * * * * * ** Checking for NEXT @@ -529,7 +537,7 @@ FIEL fiel FIELD( FIEL(0) ) DO field - DO field WITH field + DO field WITH field //field cannot be passed by a reference WHILE field fiel :=field +1 ENDDO @@ -607,7 +615,7 @@ FIELD field IN field EVAL( {|in| in}, in ) DO in - DO in WITH in + DO in WITH in //field cannot be passed be a reference RETURN in @@ -748,3 +756,189 @@ FUNCTION loop( loop ) DO loop WITH loop RETURN loop + + +/*==================================================================== +* Test for USING +*/ +FUNCTION using +LOCAL using +PRIVATE &using + + EVAL( using ) + + FOR using:=1 TO 10 + ? using + BREAK using + NEXT + + DO WHILE using > 0 + ++using + using-- + ENDDO + + BEGIN SEQUENCE + ? USIN + RECOVER USIN using + ? using + END + +RETURN using + + +/*==================================================================== +* Test for STATIC +*/ +FUNCTION STATIC +STAT stat +STATI stati +STATIC static +PRIVATE &STATIC + + EVAL( STATIC ) + + FOR static:=1 TO 10 + ? static + static( static ) + BREAK static + NEXT + + IF static + BREAK stat + ENDIF + + DO WHILE static + ++static + static -=2 + break stat + ENDDO + + BEGIN SEQUENCE + ? static + RECOVER USIN static + ? static + END + +RETURN static + + +/*==================================================================== +* Test for RETURN +*/ +FUNCTION RETURN +STAT return +PRIVATE &return + + EVAL( return ) + + FOR return:=1 TO 10 + ? return + return ( return ) + BREAK return + NEXT + + IF return + RETU return + ENDIF + + return := return( return ) + + DO WHILE return + ++return + return -=2 + break return + ENDDO + + BEGIN SEQUENCE + ? return + RECOVER USIN return + ? return + END + +RETURN( return ) + 2 + + +/*==================================================================== +* Test for RECOVER +*/ +FUNCTION RECOVER +STAT RECOVER +PRIVATE &RECOVER + + EVAL( RECOVER ) + + FOR RECOVER:=1 TO 10 + ? RECOVER + RECOVER ( RECOVER ) + BREAK RECOVER + NEXT + + IF RECOVER + RETU RECOVER + ENDIF + + RECOVER := RECOVER( RECOVER ) + + DO WHILE RECOVER + ++RECOVER + RECOVER -=2 + break RECOVER + ENDDO + + BEGIN SEQUENCE + ? RECOVER + RECOVER + ? RECOVER + END + + BEGIN SEQUENCE + ? RECOVER + RECOVER USIN RECOVER + ? RECOVER + END + +RETURN( RECOVER ) +2 + + +/*==================================================================== +* Test for OTHERWISE +*/ +FUNCTION OTHERWISE +STAT OTHERWISE +PRIVATE &OTHERWISE + + EVAL( OTHERWISE ) + + FOR OTHERWISE:=1 TO 10 + ? OTHERWISE + OTHERWISE ( OTHERWISE ) + BREAK OTHERWISE + NEXT + + IF OTHERWISE + RETU OTHERWISE + ENDIF + + OTHERWISE := OTHERWISE( OTHERWISE ) + + OTHERWISE++ + + DO WHILE OTHERWISE + ++OTHERWISE + OTHERWISE -=2 + break OTHERWISE + ENDDO + + DO CASE + CASE OTHERWISE + ? OTHERWISE + CASE !OTHERWISE + ? OTHERWISE + OTHE + ? OTHERWISE +1 +// OTHER //Mayhem in CASE +// ? OTHERWISE +2 + END + + +RETURN( OTHERWISE ) +2