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