From c44897330613c8d2802a5d7f7a657a971ef5593a Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Wed, 15 Nov 2006 13:21:20 +0000 Subject: [PATCH] 2006-11-15 14:20 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbapi.h + added void * pLex; member to HB_MACRO structure - it will be necessary for MT safe macro parser * harbour/include/set.ch * harbour/include/hbexprb.c * harbour/source/macro/macro.l * harbour/source/macro/macro.y * indenting, formatting and converting tabs to spaces * harbour/include/hbpp.h * harbour/source/compiler/ppcomp.c * harbour/source/pp/ppcore.c * harbour/source/pp/ppgen.c * harbour/source/pp/pplib.c * make HB_PP_TOKEN structure public for other code and changed public PP API to not force including static rules by programs which does not need them. + added basic API for using PP as lexer * divided HB_PP_TOKEN_MACRO to HB_PP_TOKEN_MACROVAR and HB_PP_TOKEN_MACROTEXT and mark [][&[.[]]]+ as HB_PP_TOKEN_MACROTEXT not pair HB_PP_TOKEN_KEYWORD and HB_PP_TOKEN_MACRO It allows easier integration PP as (macro)compiler lexer and fixes preprocessing [][&[.[]]]+ in some patterns. * harbour/utils/hbtest/Makefile + added PP library to linked library list * harbour/source/macro/macro.y + added seaport to use PP as lexer. It's disabled by default and can be enabled using by defining HB_PP_MACROLEX. It eliminates using FLEX or SIMPLEX lexer in macro compiler. Now it emulates the behavior of FLEX lexer because I wanted to minimize the modification but in fact because parsed token are freed when macro compiler finish its job then we can resolve RT memory leaks which apear during parsing wrong expressions. It will be enough to drop allocating memory for new terminal symbols and using them as is like in compiler. It will also quite nice simplify include/hbexpr*.c code and will allow to move some functions to COMMON library. I want to make also pure compiler code MT safe so I will have to add passing pointer to a structure with compiler context just like in macro compiler. It means that if we define a structure which will be common to compiler and macro compiler with local (not common) data stored in other structure for which will will keep only a pointer then we will be able to move most of include/hbexpr*.c code to common library. But I do not want to make farther modification without consultation without Ryszard. Also to make PP default lexer some farther modifications should be done in core PP code and include/hbexpr*.c files to not reduce the speed. Now using HB_PP_MACROLEX for sure will have to cause speed reduction in macro compiler. But if we make necessary modifications then we should keep at least the same speed or probably reach noticeable better results. --- harbour/ChangeLog | 60 ++ harbour/include/hbapi.h | 1 + harbour/include/hbexprb.c | 1063 ++++++++++++++---------------- harbour/include/hbpp.h | 163 ++--- harbour/include/set.ch | 2 +- harbour/source/compiler/ppcomp.c | 14 +- harbour/source/macro/macro.l | 21 +- harbour/source/macro/macro.y | 331 +++++++--- harbour/source/pp/ppcore.c | 563 +++++++++------- harbour/source/pp/ppgen.c | 10 +- harbour/source/pp/pplib.c | 30 +- harbour/utils/hbtest/Makefile | 1 + 12 files changed, 1281 insertions(+), 978 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index c7062d9cda..420e8f89a8 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,66 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ + * old PP functions for backward compatibility: + __PPADDRULE(), __PREPROCESS(), __PP_FREE() + Please note that using this function is not MT safe. They should + work like with old PP code. Using any of this function automatically + forces linking __PP_STDRULES + +2006-11-15 14:20 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbapi.h + + added + void * pLex; + member to HB_MACRO structure - it will be necessary for MT safe + macro parser + + * harbour/include/set.ch + * harbour/include/hbexprb.c + * harbour/source/macro/macro.l + * harbour/source/macro/macro.y + * indenting, formatting and converting tabs to spaces + + * harbour/include/hbpp.h + * harbour/source/compiler/ppcomp.c + * harbour/source/pp/ppcore.c + * harbour/source/pp/ppgen.c + * harbour/source/pp/pplib.c + * make HB_PP_TOKEN structure public for other code and changed + public PP API to not force including static rules by programs + which does not need them. + + added basic API for using PP as lexer + * divided HB_PP_TOKEN_MACRO to HB_PP_TOKEN_MACROVAR and + HB_PP_TOKEN_MACROTEXT and mark + [][&[.[]]]+ + as HB_PP_TOKEN_MACROTEXT not pair HB_PP_TOKEN_KEYWORD and + HB_PP_TOKEN_MACRO + It allows easier integration PP as (macro)compiler lexer and + fixes preprocessing [][&[.[]]]+ + in some patterns. + + * harbour/utils/hbtest/Makefile + + added PP library to linked library list + + * harbour/source/macro/macro.y + + added seaport to use PP as lexer. It's disabled by default and + can be enabled using by defining HB_PP_MACROLEX. It eliminates + using FLEX or SIMPLEX lexer in macro compiler. Now it emulates + the behavior of FLEX lexer because I wanted to minimize the + modification but in fact because parsed token are freed when + macro compiler finish its job then we can resolve RT memory + leaks which apear during parsing wrong expressions. It will be + enough to drop allocating memory for new terminal symbols and + using them as is like in compiler. It will also quite nice + simplify include/hbexpr*.c code and will allow to move some + functions to COMMON library. I want to make also pure compiler + code MT safe so I will have to add passing pointer to a structure + with compiler context just like in macro compiler. It means that + if we define a structure which will be common to compiler and macro + compiler with local (not common) data stored in other structure for + which will will keep only a pointer then we will be able to move most + of include/hbexpr*.c code to common library. But I do not want to + make farther modification without consultation without Ryszard. + Also to make PP default lexer some farther modifications should be done in core PP code and include/hbexpr*.c files to not reduce the speed. Now using HB_PP_MACROLEX for sure will have to cause speed reduction in macro compiler. But if we make necessary diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index 3a355b7580..a2e1c6c314 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -804,6 +804,7 @@ typedef struct HB_MACRO_ /* a macro compiled pcode container */ HB_ITEM_PTR pError; /* error object returned from the parser */ ULONG supported; /* various flags for supported capabilities */ int FlexState; /* internal flex state during parsing */ + void * pLex; /* lexer buffer pointer */ HB_PCODE_INFO_PTR pCodeInfo; /* pointer to pcode buffer and info */ void * pParseInfo; /* data needed by the parser - it should be 'void *' to allow different implementation of macr compiler */ USHORT uiNameLen; /* the maximum symbol name length */ diff --git a/harbour/include/hbexprb.c b/harbour/include/hbexprb.c index 0196eb2bce..64019bd9c4 100644 --- a/harbour/include/hbexprb.c +++ b/harbour/include/hbexprb.c @@ -387,53 +387,51 @@ static HB_EXPR_FUNC( hb_compExprUseString ) hb_compErrorLValue( pSelf ); break; case HB_EA_PUSH_PCODE: - { - char *szDupl; - BOOL bUseTextSubst; - BOOL bValidMacro; + { + char * szDupl = hb_strupr( hb_strdup( pSelf->value.asString.string ) ); - szDupl = hb_strupr( hb_strdup( pSelf->value.asString.string ) ); - HB_EXPR_PCODE2( hb_compGenPushString, pSelf->value.asString.string, pSelf->ulLength + 1 ); + HB_EXPR_PCODE2( hb_compGenPushString, pSelf->value.asString.string, pSelf->ulLength + 1 ); #if ! defined( HB_MACRO_SUPPORT ) - if( hb_comp_bTextSubst ) - { + if( hb_comp_bTextSubst ) #endif - bValidMacro = hb_compExprIsValidMacro( szDupl, &bUseTextSubst, HB_MACRO_PARAM ); - if( bUseTextSubst ) + { + BOOL bUseTextSubst; + BOOL bValidMacro = hb_compExprIsValidMacro( szDupl, &bUseTextSubst, HB_MACRO_PARAM ); + if( bUseTextSubst ) + { + if( HB_SUPPORT_HARBOUR ) { - if( HB_SUPPORT_HARBOUR ) - { - if( bValidMacro ) - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROTEXT ); - else - { - hb_compErrorMacro( pSelf->value.asString.string ); - } - } + if( bValidMacro ) + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROTEXT ); else { - /* Clipper always generates macro substitution pcode - * even if it is not a valid expression - */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROTEXT ); - if( !bValidMacro ) - { - hb_compErrorMacro( pSelf->value.asString.string ); - } + hb_compErrorMacro( pSelf->value.asString.string ); + } + } + else + { + /* Clipper always generates macro substitution pcode + * even if it is not a valid expression + */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROTEXT ); + if( !bValidMacro ) + { + hb_compErrorMacro( pSelf->value.asString.string ); } } -#if ! defined( HB_MACRO_SUPPORT ) } -#endif - hb_xfree( szDupl ); } + hb_xfree( szDupl ); break; + } case HB_EA_POP_PCODE: break; + case HB_EA_PUSH_POP: case HB_EA_STATEMENT: hb_compWarnMeaningless( pSelf ); break; + case HB_EA_DELETE: if( pSelf->value.asString.dealloc ) HB_XFREE( pSelf->value.asString.string ); @@ -460,42 +458,39 @@ static HB_EXPR_FUNC( hb_compExprUseCodeblock ) hb_compErrorLValue( pSelf ); break; case HB_EA_PUSH_PCODE: - { + { #if defined(HB_MACRO_SUPPORT) - HB_EXPR_PCODE1( hb_compExprCodeblockPush, pSelf ); + HB_EXPR_PCODE1( hb_compExprCodeblockPush, pSelf ); #else # if defined(SIMPLEX) - HB_EXPR_PCODE2( hb_compExprCodeblockPush, pSelf, TRUE ); + HB_EXPR_PCODE2( hb_compExprCodeblockPush, pSelf, TRUE ); # else - if( !pSelf->value.asCodeblock.isMacro || pSelf->value.asCodeblock.lateEval ) - hb_compExprCodeblockPush( pSelf, TRUE ); - else - { - /* early evaluation of a macro */ - hb_compExprCodeblockEarly( pSelf ); - } + if( !pSelf->value.asCodeblock.isMacro || pSelf->value.asCodeblock.lateEval ) + hb_compExprCodeblockPush( pSelf, TRUE ); + else + /* early evaluation of a macro */ + hb_compExprCodeblockEarly( pSelf ); # endif #endif - } break; + } case HB_EA_POP_PCODE: case HB_EA_PUSH_POP: case HB_EA_STATEMENT: hb_compWarnMeaningless( pSelf ); break; + case HB_EA_DELETE: { HB_EXPR_PTR pExp = pSelf->value.asCodeblock.pExprList; HB_EXPR_PTR pNext; hb_compExprCBVarDel( pSelf->value.asCodeblock.pLocals ); - + if( pSelf->value.asCodeblock.string ) - { HB_XFREE( pSelf->value.asCodeblock.string ); - } - /* Delete all expressions of the block. - */ + + /* Delete all expressions of the block. */ while( pExp ) { pNext = pExp->pNext; @@ -518,80 +513,80 @@ static void hb_compExprCodeblockPush( HB_EXPR_PTR pSelf, HB_MACRO_DECL ) static void hb_compExprCodeblockPush( HB_EXPR_PTR pSelf, BOOL bLateEval ) #endif { - HB_EXPR_PTR pExpr, pNext; - HB_EXPR_PTR * pPrev; + HB_EXPR_PTR pExpr, pNext; + HB_EXPR_PTR * pPrev; - /* Define requested local variables - */ + /* Define requested local variables + */ #if defined( HB_MACRO_SUPPORT ) - HB_EXPR_PCODE0( hb_compCodeBlockStart ); - HB_PCODE_DATA->pLocals = pSelf->value.asCodeblock.pLocals; + HB_EXPR_PCODE0( hb_compCodeBlockStart ); + HB_PCODE_DATA->pLocals = pSelf->value.asCodeblock.pLocals; #else - HB_EXPR_PCODE1( hb_compCodeBlockStart, bLateEval ); + HB_EXPR_PCODE1( hb_compCodeBlockStart, bLateEval ); - { - HB_CBVAR_PTR pVar; + { + HB_CBVAR_PTR pVar; - pVar = pSelf->value.asCodeblock.pLocals; - while( pVar ) - { - hb_compVariableAdd( pVar->szName, pVar->bType ); - pVar =pVar->pNext; - } - } - - HB_EXPR_PCODE0( hb_compLinePushIfDebugger ); + pVar = pSelf->value.asCodeblock.pLocals; + while( pVar ) + { + hb_compVariableAdd( pVar->szName, pVar->bType ); + pVar =pVar->pNext; + } + } + + HB_EXPR_PCODE0( hb_compLinePushIfDebugger ); #endif - pExpr = pSelf->value.asCodeblock.pExprList; - pPrev = &pSelf->value.asCodeblock.pExprList; - while( pExpr ) - { - if( pExpr->ExprType == HB_ET_MACRO ) - { - /* Clipper allows for list expressions in a codeblock - * macro := "1,2" - * EVAL( {|| ¯o} ) + pExpr = pSelf->value.asCodeblock.pExprList; + pPrev = &pSelf->value.asCodeblock.pExprList; + while( pExpr ) + { + if( pExpr->ExprType == HB_ET_MACRO ) + { + /* Clipper allows for list expressions in a codeblock + * macro := "1,2" + * EVAL( {|| ¯o} ) */ - pExpr->value.asMacro.SubType |= HB_ET_MACRO_PARE; - } + pExpr->value.asMacro.SubType |= HB_ET_MACRO_PARE; + } - /* store next expression in case the current will be reduced - * NOTE: During reduction the expression can be replaced by the - * new one - this will break the linked list of expressions. - */ - pNext = pExpr->pNext; /* store next expression in case the current will be reduced */ - pExpr = HB_EXPR_USE( pExpr, HB_EA_REDUCE ); - /* Generate push/pop pcodes for all expresions except the last one - * The value of the last expression is used as a return value - * of a codeblock evaluation - */ - /* NOTE: This will genereate warnings if constant value is - * used as an expression - some operators will generate it too - * e.g. - * EVAL( {|| 3+5, func()} ) - */ - *pPrev = pExpr; /* store a new expression into the previous one */ - pExpr->pNext = pNext; /* restore the link to next expression */ + /* store next expression in case the current will be reduced + * NOTE: During reduction the expression can be replaced by the + * new one - this will break the linked list of expressions. + */ + pNext = pExpr->pNext; /* store next expression in case the current will be reduced */ + pExpr = HB_EXPR_USE( pExpr, HB_EA_REDUCE ); + /* Generate push/pop pcodes for all expresions except the last one + * The value of the last expression is used as a return value + * of a codeblock evaluation + */ + /* NOTE: This will genereate warnings if constant value is + * used as an expression - some operators will generate it too + * e.g. + * EVAL( {|| 3+5, func()} ) + */ + *pPrev = pExpr; /* store a new expression into the previous one */ + pExpr->pNext = pNext; /* restore the link to next expression */ #if defined( HB_MACRO_SUPPORT ) - if( pNext ) - HB_EXPR_USE( pExpr, HB_EA_PUSH_POP ); - else - HB_EXPR_USE( pExpr, HB_EA_PUSH_PCODE ); + if( pNext ) + HB_EXPR_USE( pExpr, HB_EA_PUSH_POP ); + else + HB_EXPR_USE( pExpr, HB_EA_PUSH_PCODE ); #else - if( pNext && bLateEval ) - HB_EXPR_USE( pExpr, HB_EA_PUSH_POP ); - else - HB_EXPR_USE( pExpr, HB_EA_PUSH_PCODE ); + if( pNext && bLateEval ) + HB_EXPR_USE( pExpr, HB_EA_PUSH_POP ); + else + HB_EXPR_USE( pExpr, HB_EA_PUSH_PCODE ); #endif - pPrev = &pExpr->pNext; - pExpr = pNext; - } + pPrev = &pExpr->pNext; + pExpr = pNext; + } #if defined( HB_MACRO_SUPPORT ) - HB_EXPR_PCODE0( hb_compCodeBlockEnd ); + HB_EXPR_PCODE0( hb_compCodeBlockEnd ); #else - if( bLateEval ) + if( bLateEval ) HB_EXPR_PCODE0( hb_compCodeBlockEnd ); - else + else HB_EXPR_PCODE0( hb_compCodeBlockRewind ); #endif } @@ -602,46 +597,45 @@ static void hb_compExprCodeblockPush( HB_EXPR_PTR pSelf, BOOL bLateEval ) #if !defined(HB_MACRO_SUPPORT) static void hb_compExprCodeblockEarly( HB_EXPR_PTR pSelf ) { - HB_EXPR_PTR pExpr; - - /* check first expression */ - pExpr = pSelf->value.asCodeblock.pExprList; - if( pExpr->ExprType == HB_ET_MACRO && pExpr->value.asMacro.cMacroOp ) - { - /* simple macro variable expansion: &variable - * 'szMacro' is a variable name - * {|| &variable} => &( '{||' + variable +'}' ) - */ - HB_EXPR_PTR pVar, pNew; + HB_EXPR_PTR pExpr; - pVar = hb_compExprNewVar( pExpr->value.asMacro.szMacro ); - pNew = hb_compExprNewString( "{||", 3 ); - pNew = hb_compExprSetOperand( hb_compExprNewPlus( pNew ), pVar ); - pNew = hb_compExprSetOperand( hb_compExprNewPlus( pNew ), hb_compExprNewString( "}", 1 ) ); - pNew = hb_compExprNewMacro( pNew, 0, NULL ); - HB_EXPR_USE( pNew, HB_EA_PUSH_PCODE ); - hb_compExprDelete( pNew ); - } - else - { - /* everything else is macro compiled at runtime - * {|| &variable+1} => &( '{|| &variable+1}' ) - */ - HB_EXPR_PTR pNew; - char *cStr; + /* check first expression */ + pExpr = pSelf->value.asCodeblock.pExprList; + if( pExpr->ExprType == HB_ET_MACRO && pExpr->value.asMacro.cMacroOp ) + { + /* simple macro variable expansion: &variable + * 'szMacro' is a variable name + * {|| &variable} => &( '{||' + variable +'}' ) + */ + HB_EXPR_PTR pVar, pNew; + + pVar = hb_compExprNewVar( pExpr->value.asMacro.szMacro ); + pNew = hb_compExprNewString( "{||", 3 ); + pNew = hb_compExprSetOperand( hb_compExprNewPlus( pNew ), pVar ); + pNew = hb_compExprSetOperand( hb_compExprNewPlus( pNew ), hb_compExprNewString( "}", 1 ) ); + pNew = hb_compExprNewMacro( pNew, 0, NULL ); + HB_EXPR_USE( pNew, HB_EA_PUSH_PCODE ); + hb_compExprDelete( pNew ); + } + else + { + /* everything else is macro compiled at runtime + * {|| &variable+1} => &( '{|| &variable+1}' ) + */ + HB_EXPR_PTR pNew; + char *cStr; hb_compExprCodeblockPush( pSelf, FALSE ); - cStr = pSelf->value.asCodeblock.string; - pNew = hb_compExprNewMacro( hb_compExprNewString(cStr, strlen(cStr)), 0, NULL ); - HB_EXPR_USE( pNew, HB_EA_PUSH_PCODE ); - hb_compExprDelete( pNew ); - HB_EXPR_PCODE0( hb_compCodeBlockStop ); - } - + cStr = pSelf->value.asCodeblock.string; + pNew = hb_compExprNewMacro( hb_compExprNewString(cStr, strlen(cStr)), 0, NULL ); + HB_EXPR_USE( pNew, HB_EA_PUSH_PCODE ); + hb_compExprDelete( pNew ); + HB_EXPR_PCODE0( hb_compCodeBlockStop ); + } } -#endif /*HB_MACRO_SUPPORT*/ -#endif /*SIMPLEX*/ +#endif /*HB_MACRO_SUPPORT*/ +#endif /*SIMPLEX*/ /* actions for HB_ET_LOGICAL expression */ @@ -829,7 +823,6 @@ static HB_EXPR_FUNC( hb_compExprUseArray ) } } break; - } return pSelf; @@ -843,19 +836,25 @@ static HB_EXPR_FUNC( hb_compExprUseVarRef ) { case HB_EA_REDUCE: break; + case HB_EA_ARRAY_AT: hb_compErrorType( pSelf ); break; + case HB_EA_ARRAY_INDEX: break; + case HB_EA_LVALUE: hb_compErrorLValue( pSelf ); break; + case HB_EA_PUSH_PCODE: HB_EXPR_PCODE1( hb_compGenPushVarRef, pSelf->value.asSymbol ); break; + case HB_EA_POP_PCODE: break; + case HB_EA_PUSH_POP: case HB_EA_STATEMENT: hb_compWarnMeaningless( pSelf ); @@ -877,20 +876,26 @@ static HB_EXPR_FUNC( hb_compExprUseFunRef ) { case HB_EA_REDUCE: break; + case HB_EA_ARRAY_AT: hb_compErrorType( pSelf ); break; + case HB_EA_ARRAY_INDEX: break; + case HB_EA_LVALUE: hb_compErrorLValue( pSelf ); break; + case HB_EA_PUSH_PCODE: HB_EXPR_PCODE1( hb_compGenPushFunCall, pSelf->value.asSymbol ); HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_FUNCPTR ); break; + case HB_EA_POP_PCODE: break; + case HB_EA_PUSH_POP: case HB_EA_STATEMENT: hb_compWarnMeaningless( pSelf ); @@ -1472,7 +1477,6 @@ static HB_EXPR_FUNC( hb_compExprUseMacro ) * be compiled after text susbstitution */ #if ! defined( HB_MACRO_SUPPORT ) - BOOL bUseTextSubst; char *szDupl; szDupl = hb_strupr( hb_strdup( pSelf->value.asMacro.szMacro ) ); @@ -1536,13 +1540,10 @@ static HB_EXPR_FUNC( hb_compExprUseMacro ) HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_COMPFLAG_RT_MACRO ); #else HB_EXPR_GENPCODE1( hb_compGenPData1, - ( - ( hb_comp_Supported & HB_COMPFLAG_HARBOUR ? HB_SM_HARBOUR : 0 ) | - ( hb_comp_Supported & HB_COMPFLAG_XBASE ? HB_SM_XBASE : 0 ) | - ( hb_comp_bShortCuts ? HB_SM_SHORTCUTS : 0 ) | - ( hb_comp_Supported & HB_COMPFLAG_RT_MACRO ? HB_SM_RT_MACRO : 0 ) - ) - ); + ( hb_comp_Supported & HB_COMPFLAG_HARBOUR ? HB_SM_HARBOUR : 0 ) | + ( hb_comp_Supported & HB_COMPFLAG_XBASE ? HB_SM_XBASE : 0 ) | + ( hb_comp_bShortCuts ? HB_SM_SHORTCUTS : 0 ) | + ( hb_comp_Supported & HB_COMPFLAG_RT_MACRO ? HB_SM_RT_MACRO : 0 ) ); #endif } @@ -1638,57 +1639,55 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall ) switch( iMessage ) { case HB_EA_REDUCE: + /* Reduce the expressions on the list of arguments + */ + if( pSelf->value.asFunCall.pParms ) + pSelf->value.asFunCall.pParms = HB_EXPR_USE( pSelf->value.asFunCall.pParms, HB_EA_REDUCE ); + + if( pSelf->value.asFunCall.pFunName->ExprType == HB_ET_FUNNAME ) { - /* Reduce the expressions on the list of arguments - */ - if( pSelf->value.asFunCall.pParms ) - pSelf->value.asFunCall.pParms = HB_EXPR_USE( pSelf->value.asFunCall.pParms, HB_EA_REDUCE ); + HB_EXPR_PTR pName = pSelf->value.asFunCall.pFunName; + HB_EXPR_PTR pParms = pSelf->value.asFunCall.pParms; + USHORT usCount = 0; - if( pSelf->value.asFunCall.pFunName->ExprType == HB_ET_FUNNAME ) + if( pParms ) { - HB_EXPR_PTR pName = pSelf->value.asFunCall.pFunName; - HB_EXPR_PTR pParms = pSelf->value.asFunCall.pParms; - USHORT usCount = 0; + usCount = ( USHORT ) hb_compExprListLen( pSelf->value.asFunCall.pParms ); - if( pParms ) + if( usCount == 1 && pParms->value.asList.pExprList->ExprType == HB_ET_NONE ) { - usCount = ( USHORT ) hb_compExprListLen( pSelf->value.asFunCall.pParms ); + --usCount; + } + } - if( usCount == 1 && pParms->value.asList.pExprList->ExprType == HB_ET_NONE ) - { - --usCount; - } - } + #ifndef HB_MACRO_SUPPORT + hb_compFunCallCheck( pName->value.asSymbol, usCount ); + #endif - #ifndef HB_MACRO_SUPPORT - hb_compFunCallCheck( pName->value.asSymbol, usCount ); - #endif - - if( ( strcmp( "AT", pName->value.asSymbol ) == 0 ) && usCount == 2 ) - { - hb_compExprReduceAT( pSelf, HB_MACRO_PARAM ); - } - else if( ( strcmp( "CHR", pName->value.asSymbol ) == 0 ) && usCount ) - { - hb_compExprReduceCHR( pSelf, HB_MACRO_PARAM ); - } - else if( ( strcmp( "LEN", pName->value.asSymbol ) == 0 ) && usCount ) - { - if( HB_COMP_ISSUPPORTED(HB_COMPFLAG_HARBOUR) ) - hb_compExprReduceLEN( pSelf, HB_MACRO_PARAM ); - } - else if( ( strcmp( "ASC", pName->value.asSymbol ) == 0 ) && usCount ) - { - if( HB_COMP_ISSUPPORTED(HB_COMPFLAG_HARBOUR) ) - hb_compExprReduceASC( pSelf, HB_MACRO_PARAM ); - } - else if( ( ( strcmp( "STOD", pName->value.asSymbol ) == 0 ) || - ( strcmp( "HB_STOD", pName->value.asSymbol ) == 0 ) ) && usCount < 2 ) - { - if( HB_COMP_ISSUPPORTED(HB_COMPFLAG_HARBOUR) ) - hb_compExprReduceSTOD( pSelf, usCount, HB_MACRO_PARAM ); - } - } + if( ( strcmp( "AT", pName->value.asSymbol ) == 0 ) && usCount == 2 ) + { + hb_compExprReduceAT( pSelf, HB_MACRO_PARAM ); + } + else if( ( strcmp( "CHR", pName->value.asSymbol ) == 0 ) && usCount ) + { + hb_compExprReduceCHR( pSelf, HB_MACRO_PARAM ); + } + else if( ( strcmp( "LEN", pName->value.asSymbol ) == 0 ) && usCount ) + { + if( HB_COMP_ISSUPPORTED(HB_COMPFLAG_HARBOUR) ) + hb_compExprReduceLEN( pSelf, HB_MACRO_PARAM ); + } + else if( ( strcmp( "ASC", pName->value.asSymbol ) == 0 ) && usCount ) + { + if( HB_COMP_ISSUPPORTED(HB_COMPFLAG_HARBOUR) ) + hb_compExprReduceASC( pSelf, HB_MACRO_PARAM ); + } + else if( ( ( strcmp( "STOD", pName->value.asSymbol ) == 0 ) || + ( strcmp( "HB_STOD", pName->value.asSymbol ) == 0 ) ) && usCount < 2 ) + { + if( HB_COMP_ISSUPPORTED(HB_COMPFLAG_HARBOUR) ) + hb_compExprReduceSTOD( pSelf, usCount, HB_MACRO_PARAM ); + } } break; @@ -1701,120 +1700,118 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall ) break; case HB_EA_PUSH_PCODE: + { + BOOL fMacroList = FALSE; + USHORT usCount; + + HB_EXPR_USE( pSelf->value.asFunCall.pFunName, HB_EA_PUSH_PCODE ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_PUSHNIL ); + + if( pSelf->value.asFunCall.pParms ) { - BOOL fMacroList = FALSE; - USHORT usCount; - - HB_EXPR_USE( pSelf->value.asFunCall.pFunName, HB_EA_PUSH_PCODE ); - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_PUSHNIL ); - - if( pSelf->value.asFunCall.pParms ) + /* NOTE: pParms will be NULL in 'DO procname' (if there is + * no WITH keyword) + */ + usCount = ( USHORT ) hb_compExprListLen( pSelf->value.asFunCall.pParms ); + if( usCount == 1 && pSelf->value.asFunCall.pParms->value.asList.pExprList->ExprType == HB_ET_NONE ) + --usCount; + if( usCount ) { - /* NOTE: pParms will be NULL in 'DO procname' (if there is - * no WITH keyword) - */ - usCount = ( USHORT ) hb_compExprListLen( pSelf->value.asFunCall.pParms ); - if( usCount == 1 && pSelf->value.asFunCall.pParms->value.asList.pExprList->ExprType == HB_ET_NONE ) - --usCount; - if( usCount ) + if( HB_SUPPORT_XBASE ) { - if( HB_SUPPORT_XBASE ) + /* check if ¯o is used as a function call argument */ + HB_EXPR_PTR pExpr = pSelf->value.asFunCall.pParms->value.asList.pExprList; + while( pExpr ) { - /* check if ¯o is used as a function call argument */ - HB_EXPR_PTR pExpr = pSelf->value.asFunCall.pParms->value.asList.pExprList; - while( pExpr ) + if( pExpr->ExprType == HB_ET_MACRO ) { - if( pExpr->ExprType == HB_ET_MACRO ) - { - /* ¯o was passed - handle it differently then in a normal statement */ - pExpr->value.asMacro.SubType |= HB_ET_MACRO_LIST; - pExpr->value.asMacro.pFunCall = pSelf; - fMacroList = TRUE; - } - pExpr = pExpr->pNext; + /* ¯o was passed - handle it differently then in a normal statement */ + pExpr->value.asMacro.SubType |= HB_ET_MACRO_LIST; + pExpr->value.asMacro.pFunCall = pSelf; + fMacroList = TRUE; } + pExpr = pExpr->pNext; } - if( fMacroList ) - { - pSelf->value.asFunCall.pParms->ExprType = HB_ET_MACROARGLIST; - usCount = hb_compExprMacroListLen( pSelf->value.asFunCall.pParms ); - HB_EXPR_USE( pSelf->value.asFunCall.pParms, HB_EA_PUSH_PCODE ); - pSelf->value.asFunCall.pParms->ExprType = HB_ET_ARGLIST; - } - else - HB_EXPR_USE( pSelf->value.asFunCall.pParms, HB_EA_PUSH_PCODE ); } + if( fMacroList ) + { + pSelf->value.asFunCall.pParms->ExprType = HB_ET_MACROARGLIST; + usCount = hb_compExprMacroListLen( pSelf->value.asFunCall.pParms ); + HB_EXPR_USE( pSelf->value.asFunCall.pParms, HB_EA_PUSH_PCODE ); + pSelf->value.asFunCall.pParms->ExprType = HB_ET_ARGLIST; + } + else + HB_EXPR_USE( pSelf->value.asFunCall.pParms, HB_EA_PUSH_PCODE ); } - else - usCount = 0; - - if( fMacroList ) - HB_EXPR_GENPCODE3( hb_compGenPCode3, HB_P_MACROFUNC, HB_LOBYTE( usCount ), HB_HIBYTE( usCount ), TRUE ); - else if( usCount > 255 ) - HB_EXPR_GENPCODE3( hb_compGenPCode3, HB_P_FUNCTION, HB_LOBYTE( usCount ), HB_HIBYTE( usCount ), TRUE ); - else - HB_EXPR_GENPCODE2( hb_compGenPCode2, HB_P_FUNCTIONSHORT, ( BYTE ) usCount, TRUE ); } - break; + else + usCount = 0; + if( fMacroList ) + HB_EXPR_GENPCODE3( hb_compGenPCode3, HB_P_MACROFUNC, HB_LOBYTE( usCount ), HB_HIBYTE( usCount ), TRUE ); + else if( usCount > 255 ) + HB_EXPR_GENPCODE3( hb_compGenPCode3, HB_P_FUNCTION, HB_LOBYTE( usCount ), HB_HIBYTE( usCount ), TRUE ); + else + HB_EXPR_GENPCODE2( hb_compGenPCode2, HB_P_FUNCTIONSHORT, ( BYTE ) usCount, TRUE ); + break; + } case HB_EA_POP_PCODE: break; case HB_EA_PUSH_POP: case HB_EA_STATEMENT: + { + BOOL fMacroList = FALSE; + USHORT usCount; + + HB_EXPR_USE( pSelf->value.asFunCall.pFunName, HB_EA_PUSH_PCODE ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_PUSHNIL ); + + if( pSelf->value.asFunCall.pParms ) { - BOOL fMacroList = FALSE; - USHORT usCount; - - HB_EXPR_USE( pSelf->value.asFunCall.pFunName, HB_EA_PUSH_PCODE ); - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_PUSHNIL ); - - if( pSelf->value.asFunCall.pParms ) + usCount = ( USHORT ) hb_compExprListLen( pSelf->value.asFunCall.pParms ); + if( usCount == 1 && pSelf->value.asFunCall.pParms->value.asList.pExprList->ExprType == HB_ET_NONE ) + --usCount; + if( usCount ) { - usCount = ( USHORT ) hb_compExprListLen( pSelf->value.asFunCall.pParms ); - if( usCount == 1 && pSelf->value.asFunCall.pParms->value.asList.pExprList->ExprType == HB_ET_NONE ) - --usCount; - if( usCount ) + if( HB_SUPPORT_XBASE ) { - if( HB_SUPPORT_XBASE ) + /* check if ¯o is used as a function call argument */ + HB_EXPR_PTR pExpr = pSelf->value.asFunCall.pParms->value.asList.pExprList; + while( pExpr ) { - /* check if ¯o is used as a function call argument */ - HB_EXPR_PTR pExpr = pSelf->value.asFunCall.pParms->value.asList.pExprList; - while( pExpr ) + if( pExpr->ExprType == HB_ET_MACRO ) { - if( pExpr->ExprType == HB_ET_MACRO ) - { - /* ¯o was passed - handle it differently then in a normal statement */ - pExpr->value.asMacro.SubType |= HB_ET_MACRO_LIST; - pExpr->value.asMacro.pFunCall = pSelf; - fMacroList = TRUE; - } - pExpr = pExpr->pNext; + /* ¯o was passed - handle it differently then in a normal statement */ + pExpr->value.asMacro.SubType |= HB_ET_MACRO_LIST; + pExpr->value.asMacro.pFunCall = pSelf; + fMacroList = TRUE; } + pExpr = pExpr->pNext; } - if( fMacroList ) - { - pSelf->value.asFunCall.pParms->ExprType = HB_ET_MACROARGLIST; - usCount = hb_compExprMacroListLen( pSelf->value.asFunCall.pParms ); - HB_EXPR_USE( pSelf->value.asFunCall.pParms, HB_EA_PUSH_PCODE ); - pSelf->value.asFunCall.pParms->ExprType = HB_ET_ARGLIST; - } - else - HB_EXPR_USE( pSelf->value.asFunCall.pParms, HB_EA_PUSH_PCODE ); } + if( fMacroList ) + { + pSelf->value.asFunCall.pParms->ExprType = HB_ET_MACROARGLIST; + usCount = hb_compExprMacroListLen( pSelf->value.asFunCall.pParms ); + HB_EXPR_USE( pSelf->value.asFunCall.pParms, HB_EA_PUSH_PCODE ); + pSelf->value.asFunCall.pParms->ExprType = HB_ET_ARGLIST; + } + else + HB_EXPR_USE( pSelf->value.asFunCall.pParms, HB_EA_PUSH_PCODE ); } - else - usCount = 0; - - if( fMacroList ) - HB_EXPR_GENPCODE3( hb_compGenPCode3, HB_P_MACRODO, HB_LOBYTE( usCount ), HB_HIBYTE( usCount ), TRUE ); - else if( usCount > 255 ) - HB_EXPR_GENPCODE3( hb_compGenPCode3, HB_P_DO, HB_LOBYTE( usCount ), HB_HIBYTE( usCount ), TRUE ); - else - HB_EXPR_GENPCODE2( hb_compGenPCode2, HB_P_DOSHORT, ( BYTE ) usCount, TRUE ); } - break; + else + usCount = 0; + if( fMacroList ) + HB_EXPR_GENPCODE3( hb_compGenPCode3, HB_P_MACRODO, HB_LOBYTE( usCount ), HB_HIBYTE( usCount ), TRUE ); + else if( usCount > 255 ) + HB_EXPR_GENPCODE3( hb_compGenPCode3, HB_P_DO, HB_LOBYTE( usCount ), HB_HIBYTE( usCount ), TRUE ); + else + HB_EXPR_GENPCODE2( hb_compGenPCode2, HB_P_DOSHORT, ( BYTE ) usCount, TRUE ); + break; + } case HB_EA_DELETE: if( pSelf->value.asFunCall.pParms ) HB_EXPR_PCODE1( hb_compExprDelete, pSelf->value.asFunCall.pParms ); @@ -1837,128 +1834,125 @@ static HB_EXPR_FUNC( hb_compExprUseAliasVar ) break; case HB_EA_PUSH_PCODE: + { + HB_EXPR_PTR pAlias = pSelf->value.asAlias.pAlias; + BOOL bReduced = FALSE; + + if( pAlias->ExprType == HB_ET_LIST ) { - HB_EXPR_PTR pAlias = pSelf->value.asAlias.pAlias; - BOOL bReduced = FALSE; + /* ( expr1, expr2, ... )->variable + */ + pSelf->value.asAlias.pAlias = HB_EXPR_USE( pSelf->value.asAlias.pAlias, HB_EA_REDUCE ); + bReduced = TRUE; + } - if( pAlias->ExprType == HB_ET_LIST ) - { - /* ( expr1, expr2, ... )->variable - */ - pSelf->value.asAlias.pAlias = HB_EXPR_USE( pSelf->value.asAlias.pAlias, HB_EA_REDUCE ); - bReduced = TRUE; - } - - if( pAlias->ExprType == HB_ET_MACRO || pSelf->value.asAlias.pVar->ExprType == HB_ET_MACRO ) - { - /* Macro operator is used on the left or right side of an alias - * operator - handle it with a special care - */ - HB_EXPR_PCODE2( hb_compExprUseAliasMacro, pSelf, HB_EA_PUSH_PCODE ); - } - else if( pAlias->ExprType == HB_ET_ALIAS ) - { - /* - * myalias->var - * FIELD->var - * MEMVAR->var - * - * NOTE: TRUE = push also alias - */ - HB_EXPR_PCODE4( hb_compGenPushAliasedVar, pSelf->value.asAlias.pVar->value.asSymbol, TRUE, pAlias->value.asSymbol, 0 ); - } - else if( pAlias->ExprType == HB_ET_NUMERIC ) - { - /* numeric alias - * 2->var - * - * NOTE: only integer (long) values are allowed - */ - if( pAlias->value.asNum.NumType == HB_ET_LONG ) - HB_EXPR_PCODE4( hb_compGenPushAliasedVar, pSelf->value.asAlias.pVar->value.asSymbol, TRUE, NULL, pAlias->value.asNum.lVal ); - else - hb_compErrorAlias( pAlias ); - } - else if( bReduced ) - { - /* - * ( expression )->var - * - * NOTE: FALSE = don't push alias value - */ - HB_EXPR_USE( pAlias, HB_EA_PUSH_PCODE ); - HB_EXPR_PCODE4( hb_compGenPushAliasedVar, pSelf->value.asAlias.pVar->value.asSymbol, FALSE, NULL, 0 ); - } + if( pAlias->ExprType == HB_ET_MACRO || pSelf->value.asAlias.pVar->ExprType == HB_ET_MACRO ) + { + /* Macro operator is used on the left or right side of an alias + * operator - handle it with a special care + */ + HB_EXPR_PCODE2( hb_compExprUseAliasMacro, pSelf, HB_EA_PUSH_PCODE ); + } + else if( pAlias->ExprType == HB_ET_ALIAS ) + { + /* + * myalias->var + * FIELD->var + * MEMVAR->var + * + * NOTE: TRUE = push also alias + */ + HB_EXPR_PCODE4( hb_compGenPushAliasedVar, pSelf->value.asAlias.pVar->value.asSymbol, TRUE, pAlias->value.asSymbol, 0 ); + } + else if( pAlias->ExprType == HB_ET_NUMERIC ) + { + /* numeric alias + * 2->var + * + * NOTE: only integer (long) values are allowed + */ + if( pAlias->value.asNum.NumType == HB_ET_LONG ) + HB_EXPR_PCODE4( hb_compGenPushAliasedVar, pSelf->value.asAlias.pVar->value.asSymbol, TRUE, NULL, pAlias->value.asNum.lVal ); else hb_compErrorAlias( pAlias ); } + else if( bReduced ) + { + /* + * ( expression )->var + * + * NOTE: FALSE = don't push alias value + */ + HB_EXPR_USE( pAlias, HB_EA_PUSH_PCODE ); + HB_EXPR_PCODE4( hb_compGenPushAliasedVar, pSelf->value.asAlias.pVar->value.asSymbol, FALSE, NULL, 0 ); + } + else + hb_compErrorAlias( pAlias ); break; - + } case HB_EA_POP_PCODE: + { + HB_EXPR_PTR pAlias = pSelf->value.asAlias.pAlias; + BOOL bReduced = FALSE; + + if( pAlias->ExprType == HB_ET_LIST ) { - HB_EXPR_PTR pAlias = pSelf->value.asAlias.pAlias; - BOOL bReduced = FALSE; + pSelf->value.asAlias.pAlias = HB_EXPR_USE( pSelf->value.asAlias.pAlias, HB_EA_REDUCE ); + bReduced = TRUE; + } - if( pAlias->ExprType == HB_ET_LIST ) - { - pSelf->value.asAlias.pAlias = HB_EXPR_USE( pSelf->value.asAlias.pAlias, HB_EA_REDUCE ); - bReduced = TRUE; - } - - if( pAlias->ExprType == HB_ET_MACRO || pSelf->value.asAlias.pVar->ExprType == HB_ET_MACRO ) - { - /* Macro operator is used on the left or right side of an alias - * operator - handle it with a special care - * (we need convert to a string the whole expression) - */ - HB_EXPR_PCODE2( hb_compExprUseAliasMacro, pSelf, HB_EA_POP_PCODE ); - } - else if( pAlias->ExprType == HB_ET_ALIAS ) - { - /* - * myalias->var - * FIELD->var - * MEMVAR->var - */ - HB_EXPR_PCODE4( hb_compGenPopAliasedVar, pSelf->value.asAlias.pVar->value.asSymbol, TRUE, pAlias->value.asSymbol, 0 ); - } - else if( pAlias->ExprType == HB_ET_NUMERIC ) - { - /* numeric alias - * 2->var - * - * NOTE: only integer (long) values are allowed - */ - if( pAlias->value.asNum.NumType == HB_ET_LONG ) - HB_EXPR_PCODE4( hb_compGenPopAliasedVar, pSelf->value.asAlias.pVar->value.asSymbol, TRUE, NULL, pAlias->value.asNum.lVal ); - else - hb_compErrorAlias( pAlias ); - } - else if( bReduced ) - { - /* - * ( expression )->var - * - * NOTE: FALSE = don't push alias value - */ - if( pAlias->ExprType == HB_ET_NONE ) - { - /* empty expression -> ()->var - */ - hb_compErrorAlias( pAlias ); - } - else - { - HB_EXPR_USE( pAlias, HB_EA_PUSH_PCODE ); - HB_EXPR_PCODE4( hb_compGenPopAliasedVar, pSelf->value.asAlias.pVar->value.asSymbol, FALSE, NULL, 0 ); - } - } + if( pAlias->ExprType == HB_ET_MACRO || pSelf->value.asAlias.pVar->ExprType == HB_ET_MACRO ) + { + /* Macro operator is used on the left or right side of an alias + * operator - handle it with a special care + * (we need convert to a string the whole expression) + */ + HB_EXPR_PCODE2( hb_compExprUseAliasMacro, pSelf, HB_EA_POP_PCODE ); + } + else if( pAlias->ExprType == HB_ET_ALIAS ) + { + /* + * myalias->var + * FIELD->var + * MEMVAR->var + */ + HB_EXPR_PCODE4( hb_compGenPopAliasedVar, pSelf->value.asAlias.pVar->value.asSymbol, TRUE, pAlias->value.asSymbol, 0 ); + } + else if( pAlias->ExprType == HB_ET_NUMERIC ) + { + /* numeric alias + * 2->var + * + * NOTE: only integer (long) values are allowed + */ + if( pAlias->value.asNum.NumType == HB_ET_LONG ) + HB_EXPR_PCODE4( hb_compGenPopAliasedVar, pSelf->value.asAlias.pVar->value.asSymbol, TRUE, NULL, pAlias->value.asNum.lVal ); else hb_compErrorAlias( pAlias ); } + else if( bReduced ) + { + /* + * ( expression )->var + * + * NOTE: FALSE = don't push alias value + */ + if( pAlias->ExprType == HB_ET_NONE ) + { + /* empty expression -> ()->var + */ + hb_compErrorAlias( pAlias ); + } + else + { + HB_EXPR_USE( pAlias, HB_EA_PUSH_PCODE ); + HB_EXPR_PCODE4( hb_compGenPopAliasedVar, pSelf->value.asAlias.pVar->value.asSymbol, FALSE, NULL, 0 ); + } + } + else + hb_compErrorAlias( pAlias ); break; - - + } case HB_EA_PUSH_POP: case HB_EA_STATEMENT: HB_EXPR_USE( pSelf, HB_EA_PUSH_PCODE ); @@ -1984,30 +1978,30 @@ static HB_EXPR_FUNC( hb_compExprUseAliasExpr ) case HB_EA_ARRAY_AT: case HB_EA_ARRAY_INDEX: break; + case HB_EA_LVALUE: hb_compErrorLValue( pSelf ); break; + case HB_EA_PUSH_PCODE: - { - /* save currently selected workarea - */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_PUSHALIAS ); - /* push the expression that will return a new workarea - */ - HB_EXPR_USE( pSelf->value.asAlias.pAlias, HB_EA_PUSH_PCODE ); - /* pop the value from the stack and select it as current workarea - */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_POPALIAS ); - /* evaluate any expression - */ - HB_EXPR_USE( pSelf->value.asAlias.pExpList, HB_EA_PUSH_PCODE ); - /* swap the two last items on the eval stack: one item is a - * value returned by evaluated expression and the second item - * is previously selected workarea. After swaping select again - * the restored workarea. - */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_SWAPALIAS ); - } + /* save currently selected workarea + */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_PUSHALIAS ); + /* push the expression that will return a new workarea + */ + HB_EXPR_USE( pSelf->value.asAlias.pAlias, HB_EA_PUSH_PCODE ); + /* pop the value from the stack and select it as current workarea + */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_POPALIAS ); + /* evaluate any expression + */ + HB_EXPR_USE( pSelf->value.asAlias.pExpList, HB_EA_PUSH_PCODE ); + /* swap the two last items on the eval stack: one item is a + * value returned by evaluated expression and the second item + * is previously selected workarea. After swaping select again + * the restored workarea. + */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_SWAPALIAS ); break; case HB_EA_POP_PCODE: @@ -2016,25 +2010,24 @@ static HB_EXPR_FUNC( hb_compExprUseAliasExpr ) case HB_EA_PUSH_POP: case HB_EA_STATEMENT: - { - /* save currently selected workarea - */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_PUSHALIAS ); - /* push the expression that will return a new workarea - */ - HB_EXPR_USE( pSelf->value.asAlias.pAlias, HB_EA_PUSH_PCODE ); - /* pop the value from the stack and select it as current workarea - */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_POPALIAS ); - /* evaluate any expression - it will not leave any return - * value on the eval stack - */ - HB_EXPR_USE( pSelf->value.asAlias.pExpList, HB_EA_PUSH_POP ); - /* Pop and select again the restored workarea. - */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_POPALIAS ); - } + /* save currently selected workarea + */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_PUSHALIAS ); + /* push the expression that will return a new workarea + */ + HB_EXPR_USE( pSelf->value.asAlias.pAlias, HB_EA_PUSH_PCODE ); + /* pop the value from the stack and select it as current workarea + */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_POPALIAS ); + /* evaluate any expression - it will not leave any return + * value on the eval stack + */ + HB_EXPR_USE( pSelf->value.asAlias.pExpList, HB_EA_PUSH_POP ); + /* Pop and select again the restored workarea. + */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_POPALIAS ); break; + case HB_EA_DELETE: HB_EXPR_PCODE1( hb_compExprDelete, pSelf->value.asAlias.pAlias ); HB_EXPR_PCODE1( hb_compExprDelete, pSelf->value.asAlias.pExpList ); @@ -2052,13 +2045,16 @@ static HB_EXPR_FUNC( hb_compExprUseAlias ) case HB_EA_ARRAY_INDEX: case HB_EA_LVALUE: break; + case HB_EA_PUSH_PCODE: HB_EXPR_PCODE3( hb_compGenPushSymbol, pSelf->value.asSymbol, FALSE, TRUE ); break; + case HB_EA_POP_PCODE: case HB_EA_PUSH_POP: case HB_EA_STATEMENT: break; + case HB_EA_DELETE: #if defined( HB_MACRO_SUPPORT ) HB_XFREE( pSelf->value.asSymbol ); @@ -2077,9 +2073,11 @@ static HB_EXPR_FUNC( hb_compExprUseFunName ) case HB_EA_ARRAY_INDEX: case HB_EA_LVALUE: break; + case HB_EA_PUSH_PCODE: HB_EXPR_PCODE1( hb_compGenPushFunCall, pSelf->value.asSymbol ); break; + case HB_EA_POP_PCODE: case HB_EA_PUSH_POP: case HB_EA_STATEMENT: @@ -2530,9 +2528,7 @@ static HB_EXPR_FUNC( hb_compExprUsePlusEq ) break; case HB_EA_PUSH_PCODE: - { - HB_EXPR_PCODE2( hb_compExprPushOperEq, pSelf, HB_P_PLUS ); - } + HB_EXPR_PCODE2( hb_compExprPushOperEq, pSelf, HB_P_PLUS ); break; case HB_EA_POP_PCODE: @@ -2572,9 +2568,7 @@ static HB_EXPR_FUNC( hb_compExprUseMinusEq ) break; case HB_EA_PUSH_PCODE: - { - HB_EXPR_PCODE2( hb_compExprPushOperEq, pSelf, HB_P_MINUS ); - } + HB_EXPR_PCODE2( hb_compExprPushOperEq, pSelf, HB_P_MINUS ); break; case HB_EA_POP_PCODE: @@ -2614,9 +2608,7 @@ static HB_EXPR_FUNC( hb_compExprUseMultEq ) break; case HB_EA_PUSH_PCODE: - { - HB_EXPR_PCODE2( hb_compExprPushOperEq, pSelf, HB_P_MULT ); - } + HB_EXPR_PCODE2( hb_compExprPushOperEq, pSelf, HB_P_MULT ); break; case HB_EA_POP_PCODE: @@ -2656,9 +2648,7 @@ static HB_EXPR_FUNC( hb_compExprUseDivEq ) break; case HB_EA_PUSH_PCODE: - { - HB_EXPR_PCODE2( hb_compExprPushOperEq, pSelf, HB_P_DIVIDE ); - } + HB_EXPR_PCODE2( hb_compExprPushOperEq, pSelf, HB_P_DIVIDE ); break; case HB_EA_POP_PCODE: @@ -2698,9 +2688,7 @@ static HB_EXPR_FUNC( hb_compExprUseModEq ) break; case HB_EA_PUSH_PCODE: - { - HB_EXPR_PCODE2( hb_compExprPushOperEq, pSelf, HB_P_MODULUS ); - } + HB_EXPR_PCODE2( hb_compExprPushOperEq, pSelf, HB_P_MODULUS ); break; case HB_EA_POP_PCODE: @@ -2740,9 +2728,7 @@ static HB_EXPR_FUNC( hb_compExprUseExpEq ) break; case HB_EA_PUSH_PCODE: - { - HB_EXPR_PCODE2( hb_compExprPushOperEq, pSelf, HB_P_POWER ); - } + HB_EXPR_PCODE2( hb_compExprPushOperEq, pSelf, HB_P_POWER ); break; case HB_EA_POP_PCODE: @@ -3088,26 +3074,24 @@ static HB_EXPR_FUNC( hb_compExprUseEqual ) break; case HB_EA_STATEMENT: + /* '=' used standalone in a statement - assign a value + * it assigns a value and removes it from the stack + * */ + if( pSelf->value.asOperator.pLeft->ExprType == HB_ET_SEND ) { - /* '=' used standalone in a statement - assign a value - * it assigns a value and removes it from the stack - * */ - if( pSelf->value.asOperator.pLeft->ExprType == HB_ET_SEND ) - { - /* Send messages are implemented as function calls - */ - HB_EXPR_PTR pObj = pSelf->value.asOperator.pLeft; - pObj->value.asMessage.pParms = pSelf->value.asOperator.pRight; - HB_EXPR_USE( pObj, HB_EA_POP_PCODE ); - pObj->value.asMessage.pParms = NULL; /* to suppress duplicated releasing */ - /* Remove the return value */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_POP ); - } - else - { - HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); - HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_POP_PCODE ); - } + /* Send messages are implemented as function calls + */ + HB_EXPR_PTR pObj = pSelf->value.asOperator.pLeft; + pObj->value.asMessage.pParms = pSelf->value.asOperator.pRight; + HB_EXPR_USE( pObj, HB_EA_POP_PCODE ); + pObj->value.asMessage.pParms = NULL; /* to suppress duplicated releasing */ + /* Remove the return value */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_POP ); + } + else + { + HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); + HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_POP_PCODE ); } break; @@ -3141,11 +3125,9 @@ static HB_EXPR_FUNC( hb_compExprUseEQ ) hb_compErrorLValue( pSelf ); break; case HB_EA_PUSH_PCODE: - { - HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); - HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_EXACTLYEQUAL ); - } + HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); + HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_EXACTLYEQUAL ); break; case HB_EA_POP_PCODE: @@ -3199,11 +3181,9 @@ static HB_EXPR_FUNC( hb_compExprUseLT ) hb_compErrorLValue( pSelf ); break; case HB_EA_PUSH_PCODE: - { - HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); - HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_LESS ); - } + HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); + HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_LESS ); break; case HB_EA_POP_PCODE: @@ -3257,11 +3237,9 @@ static HB_EXPR_FUNC( hb_compExprUseGT ) hb_compErrorLValue( pSelf ); break; case HB_EA_PUSH_PCODE: - { - HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); - HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_GREATER ); - } + HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); + HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_GREATER ); break; case HB_EA_POP_PCODE: @@ -3316,11 +3294,9 @@ static HB_EXPR_FUNC( hb_compExprUseLE ) break; case HB_EA_PUSH_PCODE: - { - HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); - HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_LESSEQUAL ); - } + HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); + HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_LESSEQUAL ); break; case HB_EA_POP_PCODE: @@ -3375,11 +3351,9 @@ static HB_EXPR_FUNC( hb_compExprUseGE ) break; case HB_EA_PUSH_PCODE: - { - HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); - HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_GREATEREQUAL ); - } + HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); + HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_GREATEREQUAL ); break; case HB_EA_POP_PCODE: @@ -3434,11 +3408,9 @@ static HB_EXPR_FUNC( hb_compExprUseNE ) break; case HB_EA_PUSH_PCODE: - { - HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); - HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_NOTEQUAL ); - } + HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); + HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_NOTEQUAL ); break; case HB_EA_POP_PCODE: @@ -3493,12 +3465,11 @@ static HB_EXPR_FUNC( hb_compExprUseIN ) case HB_EA_LVALUE: hb_compErrorLValue( pSelf ); break; + case HB_EA_PUSH_PCODE: - { - HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); - HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_INSTRING ); - } + HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); + HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_INSTRING ); break; case HB_EA_POP_PCODE: @@ -3553,11 +3524,9 @@ static HB_EXPR_FUNC( hb_compExprUsePlus ) break; case HB_EA_PUSH_PCODE: - { - HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); - HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_PLUS ); - } + HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); + HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_PLUS ); break; case HB_EA_POP_PCODE: @@ -3610,12 +3579,11 @@ static HB_EXPR_FUNC( hb_compExprUseMinus ) case HB_EA_LVALUE: hb_compErrorLValue( pSelf ); break; + case HB_EA_PUSH_PCODE: - { - HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); - HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MINUS ); - } + HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); + HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MINUS ); break; case HB_EA_POP_PCODE: @@ -3668,12 +3636,11 @@ static HB_EXPR_FUNC( hb_compExprUseMult ) case HB_EA_LVALUE: hb_compErrorLValue( pSelf ); break; + case HB_EA_PUSH_PCODE: - { - HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); - HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MULT ); - } + HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); + HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MULT ); break; case HB_EA_POP_PCODE: @@ -3726,12 +3693,11 @@ static HB_EXPR_FUNC( hb_compExprUseDiv ) case HB_EA_LVALUE: hb_compErrorLValue( pSelf ); break; + case HB_EA_PUSH_PCODE: - { - HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); - HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_DIVIDE ); - } + HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); + HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_DIVIDE ); break; case HB_EA_POP_PCODE: @@ -3784,12 +3750,11 @@ static HB_EXPR_FUNC( hb_compExprUseMod ) case HB_EA_LVALUE: hb_compErrorLValue( pSelf ); break; + case HB_EA_PUSH_PCODE: - { - HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); - HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MODULUS ); - } + HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); + HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MODULUS ); break; case HB_EA_POP_PCODE: @@ -3839,12 +3804,11 @@ static HB_EXPR_FUNC( hb_compExprUsePower ) case HB_EA_LVALUE: hb_compErrorLValue( pSelf ); break; + case HB_EA_PUSH_PCODE: - { - HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); - HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_POWER ); - } + HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); + HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_POWER ); break; case HB_EA_POP_PCODE: @@ -3869,6 +3833,7 @@ static HB_EXPR_FUNC( hb_compExprUsePower ) case HB_EA_STATEMENT: hb_compErrorSyntax( pSelf ); break; + case HB_EA_DELETE: HB_EXPR_PCODE1( hb_compExprDelOperator, pSelf ); break; @@ -3881,25 +3846,24 @@ static HB_EXPR_FUNC( hb_compExprUseNegate ) switch( iMessage ) { case HB_EA_REDUCE: + { + HB_EXPR_PTR pExpr; + + pSelf->value.asOperator.pLeft = hb_compExprListStrip( HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_REDUCE ), HB_MACRO_PARAM ); + pExpr = pSelf->value.asOperator.pLeft; + + if( pExpr->ExprType == HB_ET_NUMERIC ) { - HB_EXPR_PTR pExpr; - - pSelf->value.asOperator.pLeft = hb_compExprListStrip( HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_REDUCE ), HB_MACRO_PARAM ); - pExpr = pSelf->value.asOperator.pLeft; - - if( pExpr->ExprType == HB_ET_NUMERIC ) - { - if( pExpr->value.asNum.NumType == HB_ET_DOUBLE ) - pExpr->value.asNum.dVal = - pExpr->value.asNum.dVal; - else - pExpr->value.asNum.lVal = - pExpr->value.asNum.lVal; - pSelf->ExprType = HB_ET_NONE; /* do not delete operator parameter - we are still using it */ - HB_EXPR_PCODE1( hb_compExprDelete, pSelf ); - pSelf = pExpr; - } + if( pExpr->value.asNum.NumType == HB_ET_DOUBLE ) + pExpr->value.asNum.dVal = - pExpr->value.asNum.dVal; + else + pExpr->value.asNum.lVal = - pExpr->value.asNum.lVal; + pSelf->ExprType = HB_ET_NONE; /* do not delete operator parameter - we are still using it */ + HB_EXPR_PCODE1( hb_compExprDelete, pSelf ); + pSelf = pExpr; } break; - + } case HB_EA_ARRAY_AT: hb_compErrorType( pSelf ); break; @@ -3910,11 +3874,10 @@ static HB_EXPR_FUNC( hb_compExprUseNegate ) case HB_EA_LVALUE: hb_compErrorLValue( pSelf ); break; + case HB_EA_PUSH_PCODE: - { - HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_NEGATE ); - } + HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_NEGATE ); break; case HB_EA_POP_PCODE: diff --git a/harbour/include/hbpp.h b/harbour/include/hbpp.h index c45bf5cc8c..6d6a3501b1 100644 --- a/harbour/include/hbpp.h +++ b/harbour/include/hbpp.h @@ -113,44 +113,6 @@ typedef HB_PP_SWITCH_FUNC_( HB_PP_SWITCH_FUNC ); typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC; -#ifdef _HB_PP_INTERNAL - -/* default maximum number of translations */ -#define HB_PP_MAX_CYCLES 4096 -/* maximum number of single token translations, in Clipper it's 18 + number - of used rules, we will use also constant but increased by total number - of rules of given type: define, [x]translate, [x]command */ -#define HB_PP_MAX_REPATS 128 - -/* Clipper allows only 16 nested includes */ -#define HB_PP_MAX_INCLUDED_FILES 64 - - -/* comparision modes */ -#define HB_PP_CMP_ADDR 0 /* compare token addresses */ -#define HB_PP_CMP_STD 1 /* standard comparison, ignore the case of the characters */ -#define HB_PP_CMP_DBASE 2 /* dbase keyword comparison (accepts at least four character shortcuts) ignore the case of the characters */ -#define HB_PP_CMP_CASE 3 /* case sensitive comparison */ - -#define HB_PP_CMP_MODE(t) ( (t) & 0xff ) -#define HB_PP_STD_RULE 0x8000 - - -/* conditional compilation */ -#define HB_PP_COND_ELSE 1 /* preprocessing and output stopped until corresponding #else */ -#define HB_PP_COND_DISABLE 2 /* preprocessing and output stopped until corresponding #endif(s) */ - -/* operation precedence for #if calculation */ -#define HB_PP_PREC_NUL 0 -#define HB_PP_PREC_NOT 1 -#define HB_PP_PREC_LOG 2 -#define HB_PP_PREC_REL 3 -#define HB_PP_PREC_BIT 4 -#define HB_PP_PREC_PLUS 5 -#define HB_PP_PREC_MULT 6 -#define HB_PP_PREC_NEG 7 - - /* preprocessor tokens */ #define HB_PP_TOKEN_NUL 0 @@ -173,17 +135,18 @@ typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC; /* keywords, pseudo keywords and PP only tokens */ #define HB_PP_TOKEN_KEYWORD 21 -#define HB_PP_TOKEN_MACRO 22 -#define HB_PP_TOKEN_TEXT 23 -#define HB_PP_TOKEN_OTHER 24 /* non keyword, text, or operator character */ -#define HB_PP_TOKEN_BACKSLASH 25 /* "\\" */ -#define HB_PP_TOKEN_PIPE 26 /* "|" */ -#define HB_PP_TOKEN_DOT 27 /* "." */ -#define HB_PP_TOKEN_COMMA 28 /* "," */ -#define HB_PP_TOKEN_EOC 29 /* ";" */ -#define HB_PP_TOKEN_EOL 30 /* "\n" */ -#define HB_PP_TOKEN_HASH 31 /* "\n" */ -#define HB_PP_TOKEN_DIRECTIVE 32 /* direct # directive first token */ +#define HB_PP_TOKEN_MACROVAR 22 +#define HB_PP_TOKEN_MACROTEXT 23 +#define HB_PP_TOKEN_TEXT 24 +#define HB_PP_TOKEN_OTHER 25 /* non keyword, text, or operator character */ +#define HB_PP_TOKEN_BACKSLASH 26 /* "\\" */ +#define HB_PP_TOKEN_PIPE 27 /* "|" */ +#define HB_PP_TOKEN_DOT 28 /* "." */ +#define HB_PP_TOKEN_COMMA 29 /* "," */ +#define HB_PP_TOKEN_EOC 30 /* ";" */ +#define HB_PP_TOKEN_EOL 31 /* "\n" */ +#define HB_PP_TOKEN_HASH 32 /* "#" */ +#define HB_PP_TOKEN_DIRECTIVE 33 /* direct # directive first token */ /* constant values */ #define HB_PP_TOKEN_STRING 41 @@ -231,18 +194,69 @@ typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC; #define HB_PP_TOKEN_MOD 84 #define HB_PP_TOKEN_POWER 85 +#define HB_PP_TOKEN_TYPE(t) ( (t) & 0xff ) + +typedef struct _HB_PP_TOKEN +{ + struct _HB_PP_TOKEN * pNext; /* next token pointer */ + struct _HB_PP_TOKEN * pMTokens; /* restrict or optional marker token(s) */ + + char * value; /* token value */ + USHORT len; /* token value length */ + USHORT spaces; /* leading spaces for stringify */ + USHORT type; /* token type, see HB_PP_TOKEN_* */ + USHORT index; /* index to match marker or 0 */ +} +HB_PP_TOKEN, * PHB_PP_TOKEN; + + +#ifdef _HB_PP_INTERNAL + +/* default maximum number of translations */ +#define HB_PP_MAX_CYCLES 4096 +/* maximum number of single token translations, in Clipper it's 18 + number + of used rules, we will use also constant but increased by total number + of rules of given type: define, [x]translate, [x]command */ +#define HB_PP_MAX_REPATS 128 + +/* Clipper allows only 16 nested includes */ +#define HB_PP_MAX_INCLUDED_FILES 64 + + +/* comparision modes */ +#define HB_PP_CMP_ADDR 0 /* compare token addresses */ +#define HB_PP_CMP_STD 1 /* standard comparison, ignore the case of the characters */ +#define HB_PP_CMP_DBASE 2 /* dbase keyword comparison (accepts at least four character shortcuts) ignore the case of the characters */ +#define HB_PP_CMP_CASE 3 /* case sensitive comparison */ + +#define HB_PP_CMP_MODE(t) ( (t) & 0xff ) +#define HB_PP_STD_RULE 0x8000 + + +/* conditional compilation */ +#define HB_PP_COND_ELSE 1 /* preprocessing and output stopped until corresponding #else */ +#define HB_PP_COND_DISABLE 2 /* preprocessing and output stopped until corresponding #endif(s) */ + +/* operation precedence for #if calculation */ +#define HB_PP_PREC_NUL 0 +#define HB_PP_PREC_NOT 1 +#define HB_PP_PREC_LOG 2 +#define HB_PP_PREC_REL 3 +#define HB_PP_PREC_BIT 4 +#define HB_PP_PREC_PLUS 5 +#define HB_PP_PREC_MULT 6 +#define HB_PP_PREC_NEG 7 /* bitfields */ -//#define HB_PP_TOKEN_UNARY 0x0100 -//#define HB_PP_TOKEN_BINARY 0x0200 -//#define HB_PP_TOKEN_JOINABLE 0x0400 +/* #define HB_PP_TOKEN_UNARY 0x0100 */ +/* #define HB_PP_TOKEN_BINARY 0x0200 */ +/* #define HB_PP_TOKEN_JOINABLE 0x0400 */ #define HB_PP_TOKEN_MATCHMARKER 0x2000 #define HB_PP_TOKEN_STATIC 0x4000 #define HB_PP_TOKEN_PREDEFINED 0x8000 #define HB_PP_TOKEN_SETTYPE(t,n) do{ (t)->type = ( (t)->type & 0xff00 ) | (n); } while(0) -#define HB_PP_TOKEN_TYPE(t) ( (t) & 0xff ) #define HB_PP_TOKEN_ALLOC(t) ( ( (t) & HB_PP_TOKEN_STATIC ) == 0 ) #define HB_PP_TOKEN_ISPREDEF(t) ( ( (t)->type & HB_PP_TOKEN_PREDEFINED ) != 0 ) @@ -283,7 +297,8 @@ typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC; #define HB_PP_TOKEN_CANJOIN(t) ( ! HB_PP_TOKEN_CLOSE_BR(t) && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_KEYWORD && \ - HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACRO && \ + HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACROVAR && \ + HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACROTEXT && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_TEXT && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_STRING && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_NUMBER && \ @@ -362,7 +377,8 @@ typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC; #endif #define HB_PP_TOKEN_ISEXPVAL(t) ( HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_KEYWORD || \ - HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_MACRO || \ + HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_MACROVAR || \ + HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_MACROTEXT || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_STRING || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_NUMBER || \ HB_PP_TOKEN_TYPE(t) == HB_PP_TOKEN_DATE ) @@ -375,7 +391,8 @@ typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC; are checking for HB_PP_TOKEN_NUL in this macro */ #define HB_PP_TOKEN_CANQUOTE(t) ( HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_NUL && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_KEYWORD && \ - HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACRO && \ + HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACROVAR && \ + HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACROTEXT && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_RIGHT_PB && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_RIGHT_SB && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_RIGHT_CB ) @@ -386,7 +403,8 @@ typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC; similar extensions in the future */ #define HB_PP_TOKEN_CANQUOTE(t) ( HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_NUL && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_KEYWORD && \ - HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACRO && \ + HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACROVAR && \ + HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_MACROTEXT && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_RIGHT_PB && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_RIGHT_SB && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_RIGHT_CB && \ @@ -417,19 +435,6 @@ typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC; ( (c) >= 'a' && (c) <= 'z' ) || (c) == '_' ) #define HB_PP_ISNEXTIDCHAR(c) ( HB_PP_ISFIRSTIDCHAR(c) || HB_PP_ISDIGIT(c) ) -typedef struct _HB_PP_TOKEN -{ - struct _HB_PP_TOKEN * pNext; /* next token pointer */ - struct _HB_PP_TOKEN * pMTokens; /* restrict or optional marker token(s) */ - - char * value; /* token value */ - USHORT len; /* token value length */ - USHORT spaces; /* leading spaces for stringify */ - USHORT type; /* token type, see HB_PP_TOKEN_* */ - USHORT index; /* index to match marker or 0 */ -} -HB_PP_TOKEN, * PHB_PP_TOKEN; - typedef struct _HB_PP_RESULT { struct _HB_PP_RESULT * pNext; @@ -594,7 +599,6 @@ HB_PP_STATE, * PHB_PP_STATE; extern void hb_pp_initRules( PHB_PP_RULE * pRulesPtr, int * piRules, const HB_PP_DEFRULE pDefRules[], int iDefRules ); -extern void hb_pp_initStaticRules( PHB_PP_STATE pState ); #else @@ -604,13 +608,16 @@ typedef void * PHB_PP_STATE; /* public functions */ extern PHB_PP_STATE hb_pp_new( void ); -extern void hb_pp_init( PHB_PP_STATE pState, char * szFileName, BOOL fQuiet, - PHB_PP_OPEN_FUNC pOpenFunc, PHB_PP_CLOSE_FUNC pCloseFunc, - PHB_PP_ERROR_FUNC pErrorFunc, PHB_PP_DISP_FUNC pDispFunc, - PHB_PP_DUMP_FUNC pDumpFunc, PHB_PP_INLINE_FUNC pInLineFunc, - PHB_PP_SWITCH_FUNC pSwitchFunc ); extern void hb_pp_free( PHB_PP_STATE pState ); extern void hb_pp_reset( PHB_PP_STATE pState ); +extern void hb_pp_init( PHB_PP_STATE pState, BOOL fQuiet, + PHB_PP_OPEN_FUNC pOpenFunc, PHB_PP_CLOSE_FUNC pCloseFunc, + PHB_PP_ERROR_FUNC pErrorFunc, PHB_PP_DISP_FUNC pDispFunc, + PHB_PP_DUMP_FUNC pDumpFunc, PHB_PP_INLINE_FUNC pInLineFunc, + PHB_PP_SWITCH_FUNC pSwitchFunc ); +extern void hb_pp_initDynDefines( PHB_PP_STATE pState ); +extern void hb_pp_readRules( PHB_PP_STATE pState, char * szRulesFile ); +extern void hb_pp_setStdRules( PHB_PP_STATE pState ); extern void hb_pp_setStdBase( PHB_PP_STATE pState ); extern void hb_pp_setStream( PHB_PP_STATE pState, int iMode ); extern void hb_pp_addSearchPath( PHB_PP_STATE pState, const char * szPath, BOOL fReplace ); @@ -624,6 +631,10 @@ extern char * hb_pp_parseLine( PHB_PP_STATE pState, char * pLine, ULONG * pulLen extern void hb_pp_addDefine( PHB_PP_STATE pState, char * szDefName, char * szDefValue ); extern void hb_pp_delDefine( PHB_PP_STATE pState, char * szDefName ); +extern void hb_pp_tokenUpper( PHB_PP_TOKEN pToken ); +extern PHB_PP_STATE hb_pp_lexNew( char * pString, ULONG ulLen ); +extern PHB_PP_TOKEN hb_pp_lex( PHB_PP_STATE pState ); + HB_EXTERN_END #endif /* HB_PP_H_ */ diff --git a/harbour/include/set.ch b/harbour/include/set.ch index df8e2deb9a..cbbfd34bf3 100644 --- a/harbour/include/set.ch +++ b/harbour/include/set.ch @@ -124,7 +124,7 @@ #define _SET_FORCEOPT 107 /* Harbour extension */ #define _SET_DBFLOCKSCHEME 108 /* Harbour extension */ #define _SET_DEFEXTENSIONS 109 /* Harbour extension */ - + #define HB_SET_BASE 100 #define HB_SET_COUNT 10 diff --git a/harbour/source/compiler/ppcomp.c b/harbour/source/compiler/ppcomp.c index 2e29a3d796..dec2dc90a5 100644 --- a/harbour/source/compiler/ppcomp.c +++ b/harbour/source/compiler/ppcomp.c @@ -277,12 +277,24 @@ void hb_pp_SetRules( BOOL fQuiet, int argc, char * argv[] ) s_pp_state = hb_pp_new(); if( s_pp_state ) { - hb_pp_init( s_pp_state, szStdCh, fQuiet, + hb_pp_init( s_pp_state, fQuiet, hb_pp_IncludeOpen, hb_pp_IncludeClose, hb_pp_ErrorGen, NULL, hb_pp_PragmaDump, HB_COMP_ISSUPPORTED( HB_COMPFLAG_HB_INLINE_PP ) ? hb_pp_hb_inLine : NULL, hb_pp_CompilerSwitch ); + if( !szStdCh ) + hb_pp_setStdRules( s_pp_state ); + else if( *szStdCh ) + hb_pp_readRules( s_pp_state, szStdCh ); + else + { + printf( "Standard command definitions excluded.\n" ); + fflush( stdout ); + } + + hb_pp_initDynDefines( s_pp_state ); + /* Add /D and /undef: command line or envvar defines */ hb_compChkDefines( argc, argv ); diff --git a/harbour/source/macro/macro.l b/harbour/source/macro/macro.l index 00e23f2197..56e5786c9f 100644 --- a/harbour/source/macro/macro.l +++ b/harbour/source/macro/macro.l @@ -235,15 +235,15 @@ MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+ [\=\+\-\*\/\%\$\,\|\#\&\.\:\<\>\@] { pMacro->FlexState = SEPARATOR; return yytext[ 0 ]; } [\]\}\)] { pMacro->FlexState = LOOKUP; return yytext[ 0 ]; } -[\x00-\x1F] return yytext[ 0 ]; /* see below */ -[\~\`\?\_\\] return yytext[ 0 ]; /* see below */ -[\x7F-\xFF] { - /* This have to be the last rule - any nonstandard and unhandled - * characters should go to grammar analyser instead of printing it - * on stdout. - */ - return yytext[ 0 ]; - } +[\x00-\x1F] return yytext[ 0 ]; /* see below */ +[\~\`\?\_\\] return yytext[ 0 ]; /* see below */ +[\x7F-\xFF] { + /* This have to be the last rule - any nonstandard and + * unhandled characters should go to grammar analyser + * instead of printing it on stdout. + */ + return yytext[ 0 ]; + } %{ /* ************************************************************************ */ @@ -261,13 +261,12 @@ MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+ yylval_ptr->valDouble.dNumber = dNumber; yylval_ptr->valDouble.bDec = iDec; yylval_ptr->valDouble.bWidth = iWidth; - yylval_ptr->valDouble.szValue = yytext; return NUM_DOUBLE; } else { yylval_ptr->valLong.lNumber = lNumber; - yylval_ptr->valLong.szValue = yytext; + yylval_ptr->valLong.bWidth = iWidth; return NUM_LONG; } } diff --git a/harbour/source/macro/macro.y b/harbour/source/macro/macro.y index 068434bd27..b1ea17feba 100644 --- a/harbour/source/macro/macro.y +++ b/harbour/source/macro/macro.y @@ -65,6 +65,7 @@ #include "hbmacro.h" #include "hbcomp.h" #include "hbdate.h" +#include "hbpp.h" /* Compile using: bison -d -p hb_comp macro.y */ @@ -103,7 +104,7 @@ #undef YYLEX_PARAM #define YYLEX_PARAM ( (HB_MACRO_PTR)YYPARSE_PARAM ) /* additional parameter passed to yylex */ -extern int yyparse( void * ); /* to make happy some purist compiler */ +extern int yyparse( void * ); /* to make happy some purist compiler */ extern void * hb_compFlexNew( HB_MACRO_PTR ); extern void hb_compFlexDelete( void * ); @@ -119,7 +120,9 @@ extern void yyerror( char * ); /* parsing error management function */ #define HB_MACRO_IFENABLED( pSet, pExpr, flag ) \ if( HB_MACRO_DATA->supported & (flag) ) \ - { pSet = (pExpr); }\ + { \ + pSet = (pExpr); \ + }\ else \ { \ YYABORT; \ @@ -129,29 +132,26 @@ extern void yyerror( char * ); /* parsing error management function */ %union /* special structure used by lex and yacc to share info */ { - char * string; /* to hold a string returned by lex */ - int iNumber; /* to hold a temporary integer number */ - HB_LONG lNumber; /* to hold a temporary long number */ + char * string; /* to hold a string returned by lex */ + int iNumber; /* to hold a temporary integer number */ + HB_LONG lNumber; /* to hold a temporary long number */ + void * pVoid; /* to hold any memory structure we may need */ + HB_EXPR_PTR asExpr; struct { - int iNumber; /* to hold a number returned by lex */ - char * szValue; + int iNumber; /* to hold a number returned by lex */ } valInteger; struct { - HB_LONG lNumber; /* to hold a long number returned by lex */ - char * szValue; + HB_LONG lNumber; /* to hold a long number returned by lex */ + UCHAR bWidth; /* to hold the width of the value */ } valLong; struct { - double dNumber; /* to hold a double number returned by lex */ - /* NOTE: Intentionally using "unsigned char" instead of "BYTE" */ - unsigned char bWidth; /* to hold the width of the value */ - unsigned char bDec; /* to hold the number of decimal points in the value */ - char * szValue; + double dNumber; /* to hold a double number returned by lex */ + UCHAR bWidth; /* to hold the width of the value */ + UCHAR bDec; /* to hold the number of decimal points in the value */ } valDouble; - HB_EXPR_PTR asExpr; - void * pVoid; /* to hold any memory structure we may need */ }; %{ @@ -176,9 +176,9 @@ int yylex( YYSTYPE *, HB_MACRO_PTR ); /*the lowest precedence*/ /*postincrement and postdecrement*/ -%left POST +%left POST /*assigment - from right to left*/ -%right INASSIGN +%right INASSIGN %right PLUSEQ MINUSEQ %right MULTEQ DIVEQ MODEQ %right EXPEQ @@ -192,7 +192,7 @@ int yylex( YYSTYPE *, HB_MACRO_PTR ); %right '+' '-' %right '*' '/' '%' %right POWER -%right UNARY +%right UNARY /*preincrement and predecrement*/ %right PRE /*special operators*/ @@ -260,17 +260,17 @@ Main : Expression '\n' { hb_compExprGenPop( $1, HB_MACRO_PARAM ); hb_compGenPCode1( HB_P_ENDPROC, HB_MACRO_PARAM ); } - | Expression error { - HB_TRACE(HB_TR_DEBUG, ("macro -> invalid expression: %s", HB_MACRO_DATA->string)); - hb_macroError( EG_SYNTAX, HB_MACRO_PARAM ); - YYABORT; - } + | Expression error { + HB_TRACE(HB_TR_DEBUG, ("macro -> invalid expression: %s", HB_MACRO_DATA->string)); + hb_macroError( EG_SYNTAX, HB_MACRO_PARAM ); + YYABORT; + } | error { - HB_TRACE(HB_TR_DEBUG, ("macro -> invalid syntax: %s", HB_MACRO_DATA->string)); - hb_macroError( EG_SYNTAX, HB_MACRO_PARAM ); - YYABORT; - } -; + HB_TRACE(HB_TR_DEBUG, ("macro -> invalid syntax: %s", HB_MACRO_DATA->string)); + hb_macroError( EG_SYNTAX, HB_MACRO_PARAM ); + YYABORT; + } + ; /* Numeric values */ @@ -278,55 +278,55 @@ NumValue : NUM_DOUBLE { $$ = hb_compExprNewDouble( $1.dNumber, $1.bWidth, | NUM_LONG { $$ = hb_compExprNewLong( $1.lNumber ); } ; -DateValue : NUM_DATE { $$ = hb_compExprNewDate( $1.lNumber ); } +DateValue : NUM_DATE { $$ = hb_compExprNewDate( $1.lNumber ); } ; -NumAlias : NUM_LONG ALIASOP { $$ = hb_compExprNewLong( $1.lNumber ); } -; +NumAlias : NUM_LONG ALIASOP { $$ = hb_compExprNewLong( $1.lNumber ); } + ; /* NIL value */ -NilValue : NIL { $$ = hb_compExprNewNil(); } -; +NilValue : NIL { $$ = hb_compExprNewNil(); } + ; /* Literal string value */ -LiteralValue : LITERAL { $$ = hb_compExprNewString( $1, strlen($1) ); } -; +LiteralValue : LITERAL { $$ = hb_compExprNewString( $1, strlen($1) ); } + ; /* Logical value */ -Logical : TRUEVALUE { $$ = hb_compExprNewLogical( TRUE ); } - | FALSEVALUE { $$ = hb_compExprNewLogical( FALSE ); } +Logical : TRUEVALUE { $$ = hb_compExprNewLogical( TRUE ); } + | FALSEVALUE { $$ = hb_compExprNewLogical( FALSE ); } ; /* SELF value and expressions */ -SelfValue : SELF { $$ = hb_compExprNewSelf(); } -; +SelfValue : SELF { $$ = hb_compExprNewSelf(); } + ; /* Literal array */ -Array : '{' ElemList '}' { $$ = hb_compExprNewArray( $2, HB_MACRO_PARAM ); } +Array : '{' ElemList '}' { $$ = hb_compExprNewArray( $2, HB_MACRO_PARAM ); } ; /* Literal array access */ -ArrayAt : Array ArrayIndex { $$ = $2; } -; +ArrayAt : Array ArrayIndex { $$ = $2; } + ; /* Variables */ -Variable : IDENTIFIER { $$ = hb_compExprNewVar( $1 ); } -; +Variable : IDENTIFIER { $$ = hb_compExprNewVar( $1 ); } + ; -VarAlias : IDENTIFIER ALIASOP { $$ = hb_compExprNewAlias( $1 ); } -; +VarAlias : IDENTIFIER ALIASOP { $$ = hb_compExprNewAlias( $1 ); } + ; /* Macro variables - this can signal compilation errors */ -MacroVar : MACROVAR { $$ = hb_compExprNewMacro( NULL, '&', $1 ); - HB_MACRO_CHECK( $$ ); +MacroVar : MACROVAR { $$ = hb_compExprNewMacro( NULL, '&', $1 ); + HB_MACRO_CHECK( $$ ); } | MACROTEXT { ULONG ulLen = strlen( $1 ); char * szVarName = hb_macroTextSubst( $1, &ulLen ); @@ -346,18 +346,18 @@ MacroVar : MACROVAR { $$ = hb_compExprNewMacro( NULL, '&', $1 ); YYABORT; } } -; + ; MacroVarAlias : MacroVar ALIASOP { $$ = $1; } -; + ; /* Macro expressions */ -MacroExpr : '&' PareExpList { $$ = hb_compExprNewMacro( $2, 0, NULL ); } -; +MacroExpr : '&' PareExpList { $$ = hb_compExprNewMacro( $2, 0, NULL ); } + ; -MacroExprAlias : MacroExpr ALIASOP { $$ = $1; } -; +MacroExprAlias : MacroExpr ALIASOP { $$ = $1; } + ; /* Aliased variables */ @@ -429,7 +429,7 @@ FunCall : IDENTIFIER '(' ArgList ')' { $$ = hb_compExprNewFunCall( hb_compE | MacroVar '(' ArgList ')' { $$ = hb_compExprNewFunCall( $1, $3, HB_MACRO_PARAM ); HB_MACRO_CHECK( $$ ); } -; + ; ArgList : Argument { $$ = hb_compExprNewArgList( $1 ); } | ArgList ',' Argument { $$ = hb_compExprAddListExpr( $1, $3 ); } @@ -468,7 +468,7 @@ ObjectData : NumValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, /* Object's method */ ObjectMethod : ObjectData '(' ArgList ')' { $$ = hb_compExprNewMethodCall( $1, $3 ); } - ; + ; SimpleExpression : NumValue @@ -498,11 +498,11 @@ SimpleExpression : | ExprMath { $$ = $1; } | ExprBool { $$ = $1; } | ExprRelation { $$ = $1; } -; + ; Expression : SimpleExpression { $$ = $1; HB_MACRO_CHECK( $$ ); } | PareExpList { $$ = $1; HB_MACRO_CHECK( $$ ); } -; + ; RootParamList : EmptyExpression ',' { if( !(HB_MACRO_DATA->Flags & HB_MACRO_GEN_LIST) ) @@ -513,18 +513,19 @@ RootParamList : EmptyExpression ',' { } } EmptyExpression { - HB_MACRO_DATA->iListElements = 1; - $$ = hb_compExprAddListExpr( ( HB_MACRO_DATA->Flags & HB_MACRO_GEN_PARE ) ? hb_compExprNewList( $1 ) : hb_compExprNewArgList( $1 ), $4 ); + HB_MACRO_DATA->iListElements = 1; + $$ = hb_compExprAddListExpr( ( HB_MACRO_DATA->Flags & HB_MACRO_GEN_PARE ) ? hb_compExprNewList( $1 ) : hb_compExprNewArgList( $1 ), $4 ); } ; -AsParamList : RootParamList { $$ = $1; } - | AsParamList ',' EmptyExpression { HB_MACRO_DATA->iListElements++; $$ = hb_compExprAddListExpr( $1, $3 ); } -; +AsParamList : RootParamList { $$ = $1; } + | AsParamList ',' EmptyExpression { HB_MACRO_DATA->iListElements++; + $$ = hb_compExprAddListExpr( $1, $3 ); } + ; EmptyExpression: /* nothing => nil */ { $$ = hb_compExprNewEmpty(); } - | Expression -; + | Expression + ; /* NOTE: PostOp can be used in one context only - it uses $0 rule * (the rule that stands before PostOp) @@ -779,8 +780,8 @@ BlockExpList : Expression { $$ = hb_compExprAddCodeblockExpr( $0, $1, HB_MACRO_PARAM ); } | BlockVarList ',' IDENTIFIER { $$ = hb_compExprCBVarAdd( $0, $3, HB_MACRO_PARAM ); HB_MACRO_CHECK( $$ ); } @@ -788,24 +789,24 @@ BlockVarList : IDENTIFIER { $$ = hb_compExprCBVarAdd( $0 ExpList : '(' EmptyExpression { $$ = hb_compExprNewList( $2 ); } | ExpList ',' EmptyExpression { $$ = hb_compExprAddListExpr( $1, $3 ); } -; + ; PareExpList : ExpList ')' { $$ = $1; } -; + ; -PareExpListAlias : PareExpList ALIASOP { $$ = $1; } -; +PareExpListAlias : PareExpList ALIASOP { $$ = $1; } + ; -IfInline : IIF '(' Expression ',' EmptyExpression ',' - { $$ = hb_compExprAddListExpr( hb_compExprNewList( $3 ), $5 ); } - EmptyExpression ')' - { $$ = hb_compExprNewIIF( hb_compExprAddListExpr( $7, $8 ) ); } +IfInline : IIF '(' Expression ',' EmptyExpression ',' + { $$ = hb_compExprAddListExpr( hb_compExprNewList( $3 ), $5 ); } + EmptyExpression ')' + { $$ = hb_compExprNewIIF( hb_compExprAddListExpr( $7, $8 ) ); } - | IF '(' Expression ',' EmptyExpression ',' - { $$ = hb_compExprAddListExpr( hb_compExprNewList( $3 ), $5 ); } - EmptyExpression ')' - { $$ = hb_compExprNewIIF( hb_compExprAddListExpr( $7, $8 ) ); } - ; + | IF '(' Expression ',' EmptyExpression ',' + { $$ = hb_compExprAddListExpr( hb_compExprNewList( $3 ), $5 ); } + EmptyExpression ')' + { $$ = hb_compExprNewIIF( hb_compExprAddListExpr( $7, $8 ) ); } + ; %% @@ -819,6 +820,17 @@ IfInline : IIF '(' Expression ',' EmptyExpression ',' ** ------------------------------------------------------------------------ ** */ +void yyerror( char * s ) +{ + HB_SYMBOL_UNUSED( s ); +} + +/* ************************************************************************* */ + +/* #define HB_PP_MACROLEX */ + +#ifndef HB_PP_MACROLEX + int hb_macroYYParse( HB_MACRO_PTR pMacro ) { int iResult; @@ -836,10 +848,161 @@ int hb_macroYYParse( HB_MACRO_PTR pMacro ) return iResult; } -/* ************************************************************************* */ +#else -void yyerror( char * s ) +int hb_macroYYParse( HB_MACRO_PTR pMacro ) { - HB_SYMBOL_UNUSED( s ); + int iResult; + + pMacro->pLex = ( void * ) hb_pp_lexNew( pMacro->string, pMacro->length ); + if( pMacro->pLex ) + { + pMacro->status = HB_MACRO_CONT; + /* NOTE: bison requires (void *) pointer */ + iResult = yyparse( ( void * ) pMacro ); + hb_pp_free( ( PHB_PP_STATE ) pMacro->pLex ); + pMacro->pLex = NULL; + } + else + iResult = HB_MACRO_FAILURE; + + return iResult; } +int hb_complex( YYSTYPE *yylval_ptr, HB_MACRO_PTR pMacro ) +{ + PHB_PP_TOKEN pToken = hb_pp_lex( ( PHB_PP_STATE ) pMacro->pLex ); + + if( !pToken ) + return 0; + + switch( HB_PP_TOKEN_TYPE( pToken->type ) ) + { + case HB_PP_TOKEN_KEYWORD: + if( pToken->len >= 4 && pToken->len <= 6 && + ( hb_strnicmp( "_FILED", pToken->value, pToken->len ) == 0 || + hb_strnicmp( "FILED", pToken->value, pToken->len ) == 0 ) ) + return FIELD; + else if( pToken->len == 3 && hb_stricmp( "IIF", pToken->value ) == 0 ) + return IIF; + else if( pToken->len == 2 && hb_stricmp( "IF", pToken->value ) == 0 ) + return IIF; + else if( pToken->len == 3 && hb_stricmp( "NIL", pToken->value ) == 0 ) + return NIL; + + hb_pp_tokenUpper( pToken ); + yylval_ptr->string = hb_strdup( pToken->value ); + return IDENTIFIER; + + case HB_PP_TOKEN_MACROVAR: + hb_pp_tokenUpper( pToken ); + yylval_ptr->string = hb_strdup( pToken->value ); + return MACROVAR; + + case HB_PP_TOKEN_MACROTEXT: + hb_pp_tokenUpper( pToken ); + yylval_ptr->string = hb_strdup( pToken->value ); + return MACROTEXT; + + case HB_PP_TOKEN_NUMBER: + { + HB_LONG lNumber; + double dNumber; + int iDec, iWidth; + + if( hb_compStrToNum( pToken->value, &lNumber, &dNumber, &iDec, &iWidth ) ) + { + yylval_ptr->valDouble.dNumber = dNumber; + yylval_ptr->valDouble.bDec = ( UCHAR ) iDec; + yylval_ptr->valDouble.bWidth = ( UCHAR ) iWidth; + return NUM_DOUBLE; + } + else + { + yylval_ptr->valLong.lNumber = lNumber; + yylval_ptr->valLong.bWidth = ( UCHAR ) iWidth; + return NUM_LONG; + } + } + case HB_PP_TOKEN_DATE: + if( pToken->len == 10 ) + { + int year, month, day; + hb_dateStrGet( pToken->value + 2, &year, &month, &day ); + yylval_ptr->valLong.lNumber = hb_dateEncode( year, month, day ); + } + else + yylval_ptr->valLong.lNumber = 0; + return NUM_DATE; + + case HB_PP_TOKEN_STRING: + yylval_ptr->string = hb_strdup( pToken->value ); + return LITERAL; + + case HB_PP_TOKEN_LOGICAL: + return pToken->value[ 1 ] == 'Y' ? TRUEVALUE : FALSEVALUE; + + case HB_PP_TOKEN_HASH: + case HB_PP_TOKEN_DIRECTIVE: + return NE1; + + case HB_PP_TOKEN_NE: + return NE2; + + case HB_PP_TOKEN_ASSIGN: + return INASSIGN; + + case HB_PP_TOKEN_EQUAL: + return EQ; + + case HB_PP_TOKEN_INC: + return INC; + + case HB_PP_TOKEN_DEC: + return DEC; + + case HB_PP_TOKEN_ALIAS: + return ALIASOP; + + case HB_PP_TOKEN_LE: + return LE; + + case HB_PP_TOKEN_GE: + return GE; + + case HB_PP_TOKEN_PLUSEQ: + return PLUSEQ; + + case HB_PP_TOKEN_MINUSEQ: + return MINUSEQ; + + case HB_PP_TOKEN_MULTEQ: + return MULTEQ; + + case HB_PP_TOKEN_DIVEQ: + return DIVEQ; + + case HB_PP_TOKEN_MODEQ: + return MODEQ; + + case HB_PP_TOKEN_EXPEQ: + return EXPEQ; + + case HB_PP_TOKEN_POWER: + return POWER; + + case HB_PP_TOKEN_AND: + return AND; + + case HB_PP_TOKEN_OR: + return OR; + + case HB_PP_TOKEN_NOT: + return NOT; + + default: + return pToken->value[ 0 ]; + } +} + +#endif /* HB_PP_MACROLEX */ diff --git a/harbour/source/pp/ppcore.c b/harbour/source/pp/ppcore.c index b171e73841..9216801765 100644 --- a/harbour/source/pp/ppcore.c +++ b/harbour/source/pp/ppcore.c @@ -1009,9 +1009,27 @@ static void hb_pp_getLine( PHB_PP_STATE pState ) } else { - if( pState->pInLineFunc && - pState->iInLineState == HB_PP_INLINE_OFF && - ul == 9 && hb_strnicmp( "hb_inLine", pBuffer, 9 ) == 0 ) + if( ul < ulLen && pBuffer[ ul ] == '&' ) + { + /* + * [][&[.[]]]+ is a single + * token in Clipper and this fact is important in later + * preprocessing so we have to replicate it + */ + while( ulLen - ul > 1 && pBuffer[ ul ] == '&' && + HB_PP_ISFIRSTIDCHAR( pBuffer[ ul + 1 ] ) ) + { + while( ++ul < ulLen && HB_PP_ISNEXTIDCHAR( pBuffer[ ul ] ) ); + if( ul < ulLen && pBuffer[ ul ] == '.' ) + while( ++ul < ulLen && HB_PP_ISNEXTIDCHAR( pBuffer[ ul ] ) ); + } + if( ul < ulLen && pBuffer[ ul ] == '&' ) + ++ul; + hb_pp_tokenAddNext( pState, pBuffer, ul, HB_PP_TOKEN_MACROTEXT ); + } + else if( pState->pInLineFunc && + pState->iInLineState == HB_PP_INLINE_OFF && + ul == 9 && hb_strnicmp( "hb_inLine", pBuffer, 9 ) == 0 ) { if( pState->fCanNextLine ) hb_pp_tokenAddCmdSep( pState ); @@ -1090,21 +1108,28 @@ static void hb_pp_getLine( PHB_PP_STATE pState ) } else if( ch == '&' && ulLen > 1 && HB_PP_ISFIRSTIDCHAR( pBuffer[ 1 ] ) ) { + int iParts = 0; /* - * [&[.[]]]+ is a single token in Clipper + * [][&[.[]]]+ is a single token in Clipper * and this fact is important in later preprocessing so we have * to replicate it */ while( ulLen - ul > 1 && pBuffer[ ul ] == '&' && HB_PP_ISFIRSTIDCHAR( pBuffer[ ul + 1 ] ) ) { + ++iParts; while( ++ul < ulLen && HB_PP_ISNEXTIDCHAR( pBuffer[ ul ] ) ); if( ul < ulLen && pBuffer[ ul ] == '.' ) - while( ++ul < ulLen && HB_PP_ISNEXTIDCHAR( pBuffer[ ul ] ) ); + while( ++ul < ulLen && HB_PP_ISNEXTIDCHAR( pBuffer[ ul ] ) ) + ++iParts; } if( ul < ulLen && pBuffer[ ul ] == '&' ) + { + ++iParts; ++ul; - hb_pp_tokenAddNext( pState, pBuffer, ul, HB_PP_TOKEN_MACRO ); + } + hb_pp_tokenAddNext( pState, pBuffer, ul, iParts == 1 ? + HB_PP_TOKEN_MACROVAR : HB_PP_TOKEN_MACROTEXT ); } else if( ch == '{' && !pState->fCanNextLine && ( pState->iInLineState == HB_PP_INLINE_BODY || @@ -3013,12 +3038,14 @@ static BOOL hb_pp_tokenMatch( PHB_PP_TOKEN pMatch, PHB_PP_TOKEN * pTokenPtr, else if( HB_PP_TOKEN_TYPE( pRestrict->type ) == HB_PP_TOKEN_AMPERSAND && ( !pRestrict->pNext || HB_PP_TOKEN_TYPE( pRestrict->pNext->type ) == HB_PP_TOKEN_COMMA ) && - ( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACRO || + ( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROVAR || + HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROTEXT || ( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_AMPERSAND && pToken->pNext && HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_PB ) ) ) { - if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACRO ) + if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROVAR || + HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROTEXT ) { * pTokenPtr = pToken->pNext; } @@ -3288,16 +3315,14 @@ static PHB_PP_TOKEN * hb_pp_matchResultLstAdd( PHB_PP_STATE pState, if( !fBlock ) hb_pp_tokenAdd( &pResultPtr, "}", 1, 0, HB_PP_TOKEN_RIGHT_CB | HB_PP_TOKEN_STATIC ); } - else if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACRO && + else if( ( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROVAR || + HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROTEXT ) && ( fStop ? pToken->pNext : pToken->pNext->pNext ) == pNext ) { - USHORT len = 0; - while( ++len < pToken->len && - HB_PP_ISNEXTIDCHAR( pToken->value[ len ] ) ); - if( len == pToken->len || - ( len == pToken->len - 1 && pToken->value[ len ] == '.' ) ) + if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROVAR ) { - hb_pp_tokenAdd( &pResultPtr, pToken->value + 1, len - 1, + hb_pp_tokenAdd( &pResultPtr, pToken->value + 1, pToken->len - + ( pToken->value[ pToken->len - 1 ] == '.' ? 2 : 1 ), fFirst ? spaces : pToken->spaces, HB_PP_TOKEN_KEYWORD ); } @@ -4290,7 +4315,132 @@ static PHB_PP_TOKEN hb_pp_getToken( PHB_PP_STATE pState ) return pState->pTokenOut; } -static void hb_pp_initDynDefines( PHB_PP_STATE pState ) +/* + * exported functions + */ + +/* + * internal function to initialize predefined PP rules + */ +void hb_pp_initRules( PHB_PP_RULE * pRulesPtr, int * piRules, + const HB_PP_DEFRULE pDefRules[], int iDefRules ) +{ + PHB_PP_DEFRULE pDefRule; + PHB_PP_MARKER pMarkers; + PHB_PP_RULE pRule; + + hb_pp_ruleListFree( pRulesPtr ); + * piRules = iDefRules; + + while( --iDefRules >= 0 ) + { + pDefRule = ( PHB_PP_DEFRULE ) pDefRules + iDefRules; + if( pDefRule->markers > 0 ) + { + USHORT marker; + ULONG ulBit; + + pMarkers = ( PHB_PP_MARKER ) hb_xgrab( pDefRule->markers * sizeof( HB_PP_MARKER ) ); + memset( pMarkers, '\0', pDefRule->markers * sizeof( HB_PP_MARKER ) ); + for( marker = 0, ulBit = 1; marker < pDefRule->markers; ++marker, ulBit <<= 1 ) + { + if( pDefRule->repeatbits & ulBit ) + pMarkers[ marker ].canrepeat = TRUE; + } + } + else + pMarkers = NULL; + pRule = hb_pp_ruleNew( pDefRule->pMatch, pDefRule->pResult, + pDefRule->mode, pDefRule->markers, pMarkers ); + pRule->pPrev = * pRulesPtr; + * pRulesPtr = pRule; + } +} + + +/* + * create new PP context + */ +PHB_PP_STATE hb_pp_new( void ) +{ + return hb_pp_stateNew(); +} + +/* + * free PP context + */ +void hb_pp_free( PHB_PP_STATE pState ) +{ + hb_pp_stateFree( pState ); +} + +/* + * initialize PP context + */ +void hb_pp_init( PHB_PP_STATE pState, BOOL fQuiet, + PHB_PP_OPEN_FUNC pOpenFunc, PHB_PP_CLOSE_FUNC pCloseFunc, + PHB_PP_ERROR_FUNC pErrorFunc, PHB_PP_DISP_FUNC pDispFunc, + PHB_PP_DUMP_FUNC pDumpFunc, PHB_PP_INLINE_FUNC pInLineFunc, + PHB_PP_SWITCH_FUNC pSwitchFunc ) +{ + pState->fQuiet = fQuiet; + pState->pOpenFunc = pOpenFunc; + pState->pCloseFunc = pCloseFunc; + pState->pErrorFunc = pErrorFunc; + pState->pDispFunc = pDispFunc; + pState->pDumpFunc = pDumpFunc; + pState->pInLineFunc = pInLineFunc; + pState->pSwitchFunc = pSwitchFunc; +} + +/* + * reset PP context, used for multiple .prg file compilation + * with DO ... or *.clp files + */ +void hb_pp_reset( PHB_PP_STATE pState ) +{ + pState->fError = FALSE; + + hb_pp_InFileFree( pState ); + hb_pp_OutFileFree( pState ); + + hb_pp_ruleNonStdFree( &pState->pDefinitions ); + hb_pp_ruleNonStdFree( &pState->pTranslations ); + hb_pp_ruleNonStdFree( &pState->pCommands ); +} + +/* + * add search path for included files + */ +void hb_pp_addSearchPath( PHB_PP_STATE pState, const char * szPath, BOOL fReplace ) +{ + if( fReplace && pState->pIncludePath ) + { + hb_fsFreeSearchPath( pState->pIncludePath ); + pState->pIncludePath = NULL; + } + + if( szPath && * szPath ) + { + hb_fsAddSearchPath( szPath, &pState->pIncludePath ); + } +} + +/* + * mark current rules as standard ones + */ +void hb_pp_setStdBase( PHB_PP_STATE pState ) +{ + pState->fError = FALSE; + hb_pp_ruleSetStd( pState->pDefinitions ); + hb_pp_ruleSetStd( pState->pTranslations ); + hb_pp_ruleSetStd( pState->pCommands ); +} + +/* + * initialize dynamic definitions + */ +void hb_pp_initDynDefines( PHB_PP_STATE pState ) { char szDefine[ 65 ]; char szResult[ 65 ]; @@ -4369,198 +4519,37 @@ static void hb_pp_initDynDefines( PHB_PP_STATE pState ) #endif } - /* - * exported functions + * read preprocess rules from file */ - -/* - * internal function to initialize predefined PP rules - */ -void hb_pp_initRules( PHB_PP_RULE * pRulesPtr, int * piRules, - const HB_PP_DEFRULE pDefRules[], int iDefRules ) +void hb_pp_readRules( PHB_PP_STATE pState, char * szRulesFile ) { - PHB_PP_DEFRULE pDefRule; - PHB_PP_MARKER pMarkers; - PHB_PP_RULE pRule; + char szFileName[ _POSIX_PATH_MAX + 1 ]; + PHB_PP_FILE pFile = pState->pFile; + PHB_FNAME pFileName; - hb_pp_ruleListFree( pRulesPtr ); - * piRules = iDefRules; + pFileName = hb_fsFNameSplit( szRulesFile ); + if( !pFileName->szExtension ) + pFileName->szExtension = ".ch"; + hb_fsFNameMerge( szFileName, pFileName ); + hb_xfree( pFileName ); - while( --iDefRules >= 0 ) + pState->pFile = hb_pp_FileNew( pState, szFileName, FALSE, NULL, pState->pOpenFunc ); + if( !pState->pFile ) { - pDefRule = ( PHB_PP_DEFRULE ) pDefRules + iDefRules; - if( pDefRule->markers > 0 ) - { - USHORT marker; - ULONG ulBit; - - pMarkers = ( PHB_PP_MARKER ) hb_xgrab( pDefRule->markers * sizeof( HB_PP_MARKER ) ); - memset( pMarkers, '\0', pDefRule->markers * sizeof( HB_PP_MARKER ) ); - for( marker = 0, ulBit = 1; marker < pDefRule->markers; ++marker, ulBit <<= 1 ) - { - if( pDefRule->repeatbits & ulBit ) - pMarkers[ marker ].canrepeat = TRUE; - } - } - else - pMarkers = NULL; - pRule = hb_pp_ruleNew( pDefRule->pMatch, pDefRule->pResult, - pDefRule->mode, pDefRule->markers, pMarkers ); - pRule->pPrev = * pRulesPtr; - * pRulesPtr = pRule; + pState->pFile = pFile; + hb_pp_error( pState, 'F', HB_PP_ERR_CANNOT_OPEN_RULES, szFileName ); } -} - - -/* - * create new PP context - */ -PHB_PP_STATE hb_pp_new( void ) -{ - return hb_pp_stateNew(); -} - -/* - * mark current rules as standard ones - */ -void hb_pp_setStdBase( PHB_PP_STATE pState ) -{ - pState->fError = FALSE; - hb_pp_ruleSetStd( pState->pDefinitions ); - hb_pp_ruleSetStd( pState->pTranslations ); - hb_pp_ruleSetStd( pState->pCommands ); -} - -/* - * set stream mode - */ -void hb_pp_setStream( PHB_PP_STATE pState, int iMode ) -{ - pState->fError = FALSE; - switch( iMode ) + else { - case HB_PP_STREAM_DUMP_C: - pState->iDumpLine = pState->pFile ? pState->pFile->iCurrentLine : 0; - if( ! pState->pDumpBuffer ) - pState->pDumpBuffer = hb_membufNew(); - pState->iStreamDump = iMode; - break; - - case HB_PP_STREAM_INLINE_C: - pState->iDumpLine = pState->pFile ? pState->pFile->iCurrentLine : 0; - case HB_PP_STREAM_CLIPPER: - case HB_PP_STREAM_PRG: - case HB_PP_STREAM_C: - if( ! pState->pStreamBuffer ) - pState->pStreamBuffer = hb_membufNew(); - case HB_PP_STREAM_OFF: - case HB_PP_STREAM_COMMENT: - pState->iStreamDump = iMode; - break; - - default: - pState->fError = TRUE; - } -} - -/* - * initialize PP context - */ -void hb_pp_init( PHB_PP_STATE pState, char * szStdCh, BOOL fQuiet, - PHB_PP_OPEN_FUNC pOpenFunc, PHB_PP_CLOSE_FUNC pCloseFunc, - PHB_PP_ERROR_FUNC pErrorFunc, PHB_PP_DISP_FUNC pDispFunc, - PHB_PP_DUMP_FUNC pDumpFunc, PHB_PP_INLINE_FUNC pInLineFunc, - PHB_PP_SWITCH_FUNC pSwitchFunc ) -{ - pState->fQuiet = fQuiet; - pState->pOpenFunc = pOpenFunc; - pState->pCloseFunc = pCloseFunc; - pState->pErrorFunc = pErrorFunc; - pState->pDispFunc = pDispFunc; - pState->pDumpFunc = pDumpFunc; - pState->pInLineFunc = pInLineFunc; - pState->pSwitchFunc = pSwitchFunc; - - if( !szStdCh ) - { - hb_pp_initStaticRules( pState ); - } - else if( * szStdCh ) - { - char szFileName[ _POSIX_PATH_MAX + 1 ]; - PHB_PP_FILE pFile = pState->pFile; - PHB_FNAME pFileName; - - pFileName = hb_fsFNameSplit( szStdCh ); - if( !pFileName->szExtension ) - pFileName->szExtension = ".ch"; - hb_fsFNameMerge( szFileName, pFileName ); - hb_xfree( pFileName ); - - pState->pFile = hb_pp_FileNew( pState, szFileName, FALSE, NULL, pState->pOpenFunc ); - if( !pState->pFile ) + pState->iFiles++; + while( hb_pp_getToken( pState ) ); + if( pState->pFile ) { - pState->pFile = pFile; - hb_pp_error( pState, 'F', HB_PP_ERR_CANNOT_OPEN_RULES, szFileName ); - } - else - { - pState->iFiles++; - while( hb_pp_getToken( pState ) ); - if( pState->pFile ) - hb_pp_FileFree( pState->pFile, pState->pCloseFunc ); - pState->pFile = pFile; + hb_pp_FileFree( pState->pFile, pState->pCloseFunc ); pState->iFiles--; } - } - else if( !pState->fQuiet ) - { - hb_pp_disp( pState, "Standard command definitions excluded.\n" ); - } - - hb_pp_initDynDefines( pState ); - hb_pp_setStdBase( pState ); -} - -/* - * free PP context - */ -void hb_pp_free( PHB_PP_STATE pState ) -{ - hb_pp_stateFree( pState ); -} - -/* - * reset PP context, used for multiple .prg file compilation - * with DO ... or *.clp files - */ -void hb_pp_reset( PHB_PP_STATE pState ) -{ - pState->fError = FALSE; - - hb_pp_InFileFree( pState ); - hb_pp_OutFileFree( pState ); - - hb_pp_ruleNonStdFree( &pState->pDefinitions ); - hb_pp_ruleNonStdFree( &pState->pTranslations ); - hb_pp_ruleNonStdFree( &pState->pCommands ); -} - -/* - * add search path for included files - */ -void hb_pp_addSearchPath( PHB_PP_STATE pState, const char * szPath, BOOL fReplace ) -{ - if( fReplace && pState->pIncludePath ) - { - hb_fsFreeSearchPath( pState->pIncludePath ); - pState->pIncludePath = NULL; - } - - if( szPath && * szPath ) - { - hb_fsAddSearchPath( szPath, &pState->pIncludePath ); + pState->pFile = pFile; } } @@ -4638,6 +4627,98 @@ char * hb_pp_outFileName( PHB_PP_STATE pState ) return pState->szOutFileName; } +/* + * add new define value + */ +void hb_pp_addDefine( PHB_PP_STATE pState, char * szDefName, char * szDefValue ) +{ + PHB_PP_TOKEN pMatch, pResult, pToken; + PHB_PP_FILE pFile; + + pState->fError = FALSE; + + pFile = hb_pp_FileBufNew( szDefName, strlen( szDefName ) ); + pFile->pPrev = pState->pFile; + pState->pFile = pFile; + pState->iFiles++; + hb_pp_getLine( pState ); + pMatch = pState->pFile->pTokenList; + pState->pFile->pTokenList = NULL; + pToken = hb_pp_tokenResultEnd( &pMatch, TRUE ); + hb_pp_tokenListFree( &pToken ); + + if( szDefValue && !pState->fError ) + { + pFile->pLineBuf = szDefValue; + pFile->ulLineBufLen = strlen( szDefValue ); + hb_pp_getLine( pState ); + pResult = pState->pFile->pTokenList; + pState->pFile->pTokenList = NULL; + pToken = hb_pp_tokenResultEnd( &pResult, TRUE ); + hb_pp_tokenListFree( &pToken ); + } + else + pResult = NULL; + + if( pState->fError || !pMatch ) + { + hb_pp_tokenListFree( &pMatch ); + hb_pp_tokenListFree( &pResult ); + } + else + { + hb_pp_defineAdd( pState, HB_PP_CMP_CASE, 0, NULL, pMatch, pResult ); + } + pState->pFile = pFile->pPrev; + hb_pp_FileFree( pFile, NULL ); + pState->iFiles--; +} + +/* + * delete define value + */ +void hb_pp_delDefine( PHB_PP_STATE pState, char * szDefName ) +{ + PHB_PP_TOKEN pToken; + + pToken = hb_pp_tokenNew( szDefName, strlen( szDefName ), + 0, HB_PP_TOKEN_KEYWORD ); + hb_pp_defineDel( pState, pToken ); + hb_pp_tokenFree( pToken ); +} + +/* + * set stream mode + */ +void hb_pp_setStream( PHB_PP_STATE pState, int iMode ) +{ + pState->fError = FALSE; + switch( iMode ) + { + case HB_PP_STREAM_DUMP_C: + pState->iDumpLine = pState->pFile ? pState->pFile->iCurrentLine : 0; + if( ! pState->pDumpBuffer ) + pState->pDumpBuffer = hb_membufNew(); + pState->iStreamDump = iMode; + break; + + case HB_PP_STREAM_INLINE_C: + pState->iDumpLine = pState->pFile ? pState->pFile->iCurrentLine : 0; + case HB_PP_STREAM_CLIPPER: + case HB_PP_STREAM_PRG: + case HB_PP_STREAM_C: + if( ! pState->pStreamBuffer ) + pState->pStreamBuffer = hb_membufNew(); + case HB_PP_STREAM_OFF: + case HB_PP_STREAM_COMMENT: + pState->iStreamDump = iMode; + break; + + default: + pState->fError = TRUE; + } +} + /* * return next preprocessed line */ @@ -4767,61 +4848,63 @@ char * hb_pp_parseLine( PHB_PP_STATE pState, char * pLine, ULONG * pulLen ) } /* - * add new define value + * create new PP context for macro compiler */ -void hb_pp_addDefine( PHB_PP_STATE pState, char * szDefName, char * szDefValue ) +PHB_PP_STATE hb_pp_lexNew( char * pMacroString, ULONG ulLen ) { - PHB_PP_TOKEN pMatch, pResult, pToken; - PHB_PP_FILE pFile; + PHB_PP_STATE pState = hb_pp_new(); - pState->fError = FALSE; - - pFile = hb_pp_FileBufNew( szDefName, strlen( szDefName ) ); - pFile->pPrev = pState->pFile; - pState->pFile = pFile; - pState->iFiles++; + pState->fQuiet = TRUE; + pState->pFile = hb_pp_FileBufNew( pMacroString, ulLen ); hb_pp_getLine( pState ); - pMatch = pState->pFile->pTokenList; + pState->pTokenOut = pState->pFile->pTokenList; pState->pFile->pTokenList = NULL; - pToken = hb_pp_tokenResultEnd( &pMatch, TRUE ); - hb_pp_tokenListFree( &pToken ); - - if( szDefValue && !pState->fError ) + hb_pp_FileFree( pState->pFile, NULL ); + pState->pFile = NULL; + if( pState->fError ) { - pFile->pLineBuf = szDefValue; - pFile->ulLineBufLen = strlen( szDefValue ); - hb_pp_getLine( pState ); - pResult = pState->pFile->pTokenList; - pState->pFile->pTokenList = NULL; - pToken = hb_pp_tokenResultEnd( &pResult, TRUE ); - hb_pp_tokenListFree( &pToken ); + hb_pp_free( pState ); + pState = NULL; } else - pResult = NULL; + pState->pNextTokenPtr = &pState->pTokenOut; - if( pState->fError || !pMatch ) - { - hb_pp_tokenListFree( &pMatch ); - hb_pp_tokenListFree( &pResult ); - } - else - { - hb_pp_defineAdd( pState, HB_PP_CMP_CASE, 0, NULL, pMatch, pResult ); - } - pState->pFile = pFile->pPrev; - hb_pp_FileFree( pFile, NULL ); - pState->iFiles--; + return pState; +} + +PHB_PP_TOKEN hb_pp_lex( PHB_PP_STATE pState ) +{ + PHB_PP_TOKEN pToken = * pState->pNextTokenPtr; + + if( pToken ) + pState->pNextTokenPtr = &pToken->pNext; + + return pToken; } /* - * delete define value + * convert token letters to upper cases + * strip leading '&' and trailing '.' (if any) from macrovar token */ -void hb_pp_delDefine( PHB_PP_STATE pState, char * szDefName ) +void hb_pp_tokenUpper( PHB_PP_TOKEN pToken ) { - PHB_PP_TOKEN pToken; - - pToken = hb_pp_tokenNew( szDefName, strlen( szDefName ), - 0, HB_PP_TOKEN_KEYWORD ); - hb_pp_defineDel( pState, pToken ); - hb_pp_tokenFree( pToken ); + if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROVAR ) + { + char * value; + if( pToken->value[ pToken->len - 1 ] == '.' ) + pToken->len--; + value = ( char * ) hb_xgrab( pToken->len ); + memcpy( value, pToken->value + 1, pToken->len - 1 ); + value[ pToken->len ] = '\0'; + if( HB_PP_TOKEN_ALLOC( pToken->type ) ) + hb_xfree( pToken->value ); + pToken->value = value; + } + else if( !HB_PP_TOKEN_ALLOC( pToken->type ) ) + { + char * value = ( char * ) hb_xgrab( pToken->len + 1 ); + memcpy( value, pToken->value, pToken->len + 1 ); + pToken->value = value; + } + hb_strupr( pToken->value ); } diff --git a/harbour/source/pp/ppgen.c b/harbour/source/pp/ppgen.c index b7ebca43d8..362a194dce 100644 --- a/harbour/source/pp/ppgen.c +++ b/harbour/source/pp/ppgen.c @@ -62,12 +62,6 @@ void * hb_xrealloc( void * pMem, ULONG ulSize ) { return realloc( pMem, ulSize ) void hb_xfree( void * pMem ) { free( pMem ); } -void hb_pp_initStaticRules( PHB_PP_STATE pState ) -{ - HB_SYMBOL_UNUSED( pState ); -} - - /* * functions to create .c files with rules defined in given PP context */ @@ -223,7 +217,7 @@ static void hb_pp_generateRules( FILE * fout, PHB_PP_STATE pState ) if( pState->pCommands ) iCmds = hb_pp_writeRules( fout, pState->pCommands, "cmd" ); - fprintf( fout, "\nvoid hb_pp_initStaticRules( PHB_PP_STATE pState )\n{\n" ); + fprintf( fout, "\nvoid hb_pp_setStdRules( PHB_PP_STATE pState )\n{\n" ); hb_pp_generateInitFunc( fout, iDefs, "Definitions", "def" ); hb_pp_generateInitFunc( fout, iTrans, "Translations", "trs" ); hb_pp_generateInitFunc( fout, iCmds, "Commands", "cmd" ); @@ -368,7 +362,7 @@ int main( int argc, char * argv[] ) if( szFile ) { - hb_pp_init( pState, NULL, fQuiet, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); + hb_pp_init( pState, fQuiet, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); hb_pp_inFile( pState, szFile, NULL ); if( fWrite ) { diff --git a/harbour/source/pp/pplib.c b/harbour/source/pp/pplib.c index 92e693b6c8..59cbe00739 100644 --- a/harbour/source/pp/pplib.c +++ b/harbour/source/pp/pplib.c @@ -84,15 +84,21 @@ static void hb_pp_Disp( const char * szMessage ) HB_SYMBOL_UNUSED( szMessage ); } -static PHB_PP_STATE hb_pp_stateNew( char * szStdCh ) +static PHB_PP_STATE hb_pp_stateNew( BOOL fInit ) { PHB_PP_STATE pState = hb_pp_new(); if( pState ) { - hb_pp_init( pState, szStdCh, TRUE, NULL, NULL, + hb_pp_init( pState, TRUE, NULL, NULL, hb_pp_ErrorMessage, hb_pp_Disp, NULL, NULL, NULL ); - + + if( fInit ) + { + hb_pp_setStdRules( pState ); + hb_pp_initDynDefines( pState ); + hb_pp_setStdBase( pState ); + } if( ! s_pp_state ) s_pp_state = pState; } @@ -124,7 +130,7 @@ static PHB_PP_STATE hb_pp_stateParam( int * piParam ) { * piParam = 1; if( !s_pp_state ) - return hb_pp_stateNew( NULL ); + return hb_pp_stateNew( TRUE ); else return s_pp_state; } @@ -141,11 +147,21 @@ HB_FUNC( __PP_INIT ) PHB_PP_STATE pState; hb_pp_stateFree( s_pp_state ); - pState = hb_pp_stateNew( hb_parc( 2 ) ); + pState = hb_pp_stateNew( FALSE ); if( pState ) { - if( ISCHAR( 1 ) ) - hb_pp_addSearchPath( pState, hb_parc( 1 ), TRUE ); + char * szPath = hb_parc( 1 ), * szStdCh = hb_parc( 2 ); + + if( szPath ) + hb_pp_addSearchPath( pState, szPath, TRUE ); + + if( szStdCh ) + hb_pp_readRules( pState, szStdCh ); + else + hb_pp_setStdRules( pState ); + hb_pp_initDynDefines( pState ); + hb_pp_setStdBase( pState ); + hb_retptr( pState ); } else diff --git a/harbour/utils/hbtest/Makefile b/harbour/utils/hbtest/Makefile index e8b43854ab..fb7c0cd562 100644 --- a/harbour/utils/hbtest/Makefile +++ b/harbour/utils/hbtest/Makefile @@ -33,6 +33,7 @@ LIBS=\ rtl \ vm \ macro \ + pp \ common \ include $(TOP)$(ROOT)config/bin.cf