From cb87fbf546b3a0e14e70d9dcdf03579944de1053 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Wed, 26 Jul 2006 19:59:02 +0000 Subject: [PATCH] 2006-07-26 22:00 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbapi.h * harbour/include/hbexpra.c * harbour/include/hbexprb.c * harbour/include/hbexprop.h * harbour/include/hbpcode.h * harbour/include/hbxvm.h * harbour/source/common/expropt1.c * harbour/source/compiler/genc.c * harbour/source/compiler/gencc.c * harbour/source/compiler/gencli.c * harbour/source/compiler/hbdead.c * harbour/source/compiler/hbfix.c * harbour/source/compiler/hblbl.c * harbour/source/compiler/hbpcode.c * harbour/source/compiler/hbstripl.c * harbour/source/vm/hvm.c * harbour/source/vm/macro.c * changed support for XBASE++ extended syntax in expressions like: v:="1,2,3" x := a[ &v ] a := { &v } f( &v ) Now all data is stored on HV * stack without any external registers which have to be saved/restored or updated in chosen operation. This modification was necessary to make HV * reentrant safe and it also eliminated some small overhead caused by old code. I hope I haven't break anything in compiler - Ryszard please fix me if I made sth wrong. * harbour/source/vm/hvm.c * harbour/source/compiler/harbour.y * revert FOR/NEXT stop condition to be Clipper compatible PCODE table has been updated and all .prg code which used modified PCODEs has to be recompiled --- harbour/ChangeLog | 37 +++++ harbour/include/hbapi.h | 6 +- harbour/include/hbexpra.c | 3 +- harbour/include/hbexprb.c | 244 ++++++++++++++++++++--------- harbour/include/hbexprop.h | 15 +- harbour/include/hbpcode.h | 6 +- harbour/include/hbxvm.h | 5 +- harbour/source/common/expropt1.c | 45 +++++- harbour/source/compiler/genc.c | 54 ++++--- harbour/source/compiler/gencc.c | 59 +++---- harbour/source/compiler/gencli.c | 56 ++++--- harbour/source/compiler/harbour.y | 8 - harbour/source/compiler/hbdead.c | 6 +- harbour/source/compiler/hbfix.c | 6 +- harbour/source/compiler/hblbl.c | 6 +- harbour/source/compiler/hbpcode.c | 12 +- harbour/source/compiler/hbstripl.c | 6 +- harbour/source/vm/hvm.c | 230 +++++++++++++-------------- harbour/source/vm/macro.c | 23 +-- 19 files changed, 487 insertions(+), 340 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index ef7f05f754..1f0665258e 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,43 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ +2006-07-26 22:00 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbapi.h + * harbour/include/hbexpra.c + * harbour/include/hbexprb.c + * harbour/include/hbexprop.h + * harbour/include/hbpcode.h + * harbour/include/hbxvm.h + * harbour/source/common/expropt1.c + * harbour/source/compiler/genc.c + * harbour/source/compiler/gencc.c + * harbour/source/compiler/gencli.c + * harbour/source/compiler/hbdead.c + * harbour/source/compiler/hbfix.c + * harbour/source/compiler/hblbl.c + * harbour/source/compiler/hbpcode.c + * harbour/source/compiler/hbstripl.c + * harbour/source/vm/hvm.c + * harbour/source/vm/macro.c + * changed support for XBASE++ extended syntax in expressions like: + v:="1,2,3" + x := a[ &v ] + a := { &v } + f( &v ) + Now all data is stored on HV * stack without any external registers + which have to be saved/restored or updated in chosen operation. + This modification was necessary to make HV * reentrant safe and it + also eliminated some small overhead caused by old code. + I hope I haven't break anything in compiler - Ryszard please fix me + if I made sth wrong. + + * harbour/source/vm/hvm.c + * harbour/source/compiler/harbour.y + * revert FOR/NEXT stop condition to be Clipper compatible + + PCODE table has been updated and all .prg code which used modified PCODEs + has to be recompiled + 2006-07-25 22:50 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbapirdd.h * harbour/source/rdd/dbcmd.c diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index 8a04b8181d..0b826d6c50 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -63,8 +63,6 @@ HB_EXTERN_BEGIN -#define HB_MAX_MACRO_ARGS 16 - /* this definition signals that number of decimal places for double value * was not specified at compile time (the value is a result of optimization * performed by the compiler) @@ -792,8 +790,8 @@ typedef struct HB_MACRO_ /* a macro compiled pcode container */ 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 */ BOOL bShortCuts; /* are we using logical shorcuts (in OR/AND) */ - int exprType; /* type of successfully compiled expression */ - int iListElements; + int exprType; /* type of successfully compiled expression */ + int iListElements; } HB_MACRO, * HB_MACRO_PTR; extern void hb_macroGetValue( HB_ITEM_PTR pItem, BYTE iContext, BYTE flags ); /* retrieve results of a macro expansion */ diff --git a/harbour/include/hbexpra.c b/harbour/include/hbexpra.c index 144276e7ed..dd64bf551b 100644 --- a/harbour/include/hbexpra.c +++ b/harbour/include/hbexpra.c @@ -73,7 +73,7 @@ * HB_ET_NIL is used for an ordinary values and post- operators * HB_ET_NONE is used for invalid syntax, e.g. var := var1 += 2 */ -static BYTE s_PrecedTable[] = { +static BYTE s_PrecedTable[ HB_EXPR_COUNT ] = { HB_ET_NIL, /* HB_ET_NONE = 0, */ HB_ET_NIL, /* HB_ET_NIL, */ HB_ET_NIL, /* HB_ET_NUMERIC, */ @@ -89,6 +89,7 @@ static BYTE s_PrecedTable[] = { HB_ET_NIL, /* HB_ET_IIF, */ HB_ET_NIL, /* HB_ET_LIST, */ HB_ET_NIL, /* HB_ET_ARGLIST, */ + HB_ET_NIL, /* HB_ET_MACROARGLIST,*/ HB_ET_NIL, /* HB_ET_ARRAYAT, */ HB_ET_NIL, /* HB_ET_MACRO, */ HB_ET_NIL, /* HB_ET_FUNCALL, */ diff --git a/harbour/include/hbexprb.c b/harbour/include/hbexprb.c index 591e9d78c8..f71b45cf81 100644 --- a/harbour/include/hbexprb.c +++ b/harbour/include/hbexprb.c @@ -135,6 +135,7 @@ static HB_EXPR_FUNC( hb_compExprUseFunRef ); static HB_EXPR_FUNC( hb_compExprUseIIF ); static HB_EXPR_FUNC( hb_compExprUseList ); static HB_EXPR_FUNC( hb_compExprUseArgList ); +static HB_EXPR_FUNC( hb_compExprUseMacroArgList ); static HB_EXPR_FUNC( hb_compExprUseArrayAt ); static HB_EXPR_FUNC( hb_compExprUseMacro ); static HB_EXPR_FUNC( hb_compExprUseFunCall ); @@ -186,7 +187,7 @@ static HB_EXPR_FUNC( hb_compExprUseNegate ); #endif #endif -HB_EXPR_FUNC_PTR hb_comp_ExprTable[] = { +HB_EXPR_FUNC_PTR hb_comp_ExprTable[ HB_EXPR_COUNT ] = { hb_compExprUseDummy, hb_compExprUseNil, hb_compExprUseNumeric, @@ -202,6 +203,7 @@ HB_EXPR_FUNC_PTR hb_comp_ExprTable[] = { hb_compExprUseIIF, hb_compExprUseList, hb_compExprUseArgList, + hb_compExprUseMacroArgList, hb_compExprUseArrayAt, hb_compExprUseMacro, hb_compExprUseFunCall, @@ -733,9 +735,10 @@ static HB_EXPR_FUNC( hb_compExprUseArray ) HB_EXPR_GENPCODE3( hb_compGenPCode3, HB_P_ARRAYGEN, 0, 0, ( BOOL ) 1 ); else { - BOOL bMacroList = FALSE; + BOOL fMacroList = FALSE; + USHORT usItems = 0, usGroups = 0; - /* Find out if macro is used as one of the elements- if so generate a prefix HB_P_MACROLIST. */ + /* Find out if macro is used as one of the elements- if so generate code for HB_P_MACROARRAYGEN. */ if( HB_SUPPORT_XBASE ) { while( pElem ) @@ -743,28 +746,51 @@ static HB_EXPR_FUNC( hb_compExprUseArray ) if( pElem->ExprType == HB_ET_MACRO ) { pElem->value.asMacro.SubType |= HB_ET_MACRO_LIST; - bMacroList = TRUE; + fMacroList = TRUE; } pElem = pElem->pNext; } } - if( bMacroList ) - { - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROLIST ); - } pElem = pSelf->value.asList.pExprList; while( pElem ) { + if( fMacroList ) + { + if( pElem->ExprType == HB_ET_MACRO && + ( pElem->value.asMacro.SubType | HB_ET_MACRO_LIST ) ) + { + if( usItems ) + { + HB_EXPR_PCODE1( hb_compGenPushLong, usItems ); + usItems = 0; + ++usGroups; + } + ++usGroups; + } + else + { + ++usItems; + } + } HB_EXPR_USE( pElem, HB_EA_PUSH_PCODE ); pElem = pElem->pNext; } - if( bMacroList ) + if( usItems ) { - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROLISTEND ); + HB_EXPR_PCODE1( hb_compGenPushLong, usItems ); + ++usGroups; + } + if( fMacroList ) + { + HB_EXPR_GENPCODE3( hb_compGenPCode3, HB_P_MACROARRAYGEN, + HB_LOBYTE( usGroups ), HB_HIBYTE( usGroups ), TRUE ); + } + else + { + HB_EXPR_GENPCODE3( hb_compGenPCode3, HB_P_ARRAYGEN, + HB_LOBYTE( pSelf->ulLength ), HB_HIBYTE( pSelf->ulLength ), TRUE ); } - - HB_EXPR_GENPCODE3( hb_compGenPCode3, HB_P_ARRAYGEN, HB_LOBYTE( pSelf->ulLength ), HB_HIBYTE( pSelf->ulLength ), ( BOOL ) 1 ); } } break; @@ -1186,6 +1212,75 @@ static HB_EXPR_FUNC( hb_compExprUseArgList ) return pSelf; } +/* NOTE: In PUSH operation it leaves all expressions on the eval stack, + * the expresions are divided into macro compiled blocks + */ +static HB_EXPR_FUNC( hb_compExprUseMacroArgList ) +{ + switch( iMessage ) + { + case HB_EA_REDUCE: + HB_EXPR_PCODE1( hb_compExprReduceList, pSelf ); + break; + + case HB_EA_ARRAY_AT: + case HB_EA_ARRAY_INDEX: + case HB_EA_LVALUE: + break; + + case HB_EA_PUSH_PCODE: + { + HB_EXPR_PTR pExpr = pSelf->value.asList.pExprList; + USHORT usItems = 0, usGroups = 0; + + while( pExpr ) + { + if( pExpr->ExprType == HB_ET_MACRO && + ( pExpr->value.asMacro.SubType | HB_ET_MACRO_LIST ) ) + { + if( usItems ) + { + HB_EXPR_PCODE1( hb_compGenPushLong, usItems ); + usItems = 0; + ++usGroups; + } + ++usGroups; + } + else + ++usItems; + HB_EXPR_USE( pExpr, HB_EA_PUSH_PCODE ); + pExpr = pExpr->pNext; + } + if( usItems ) + { + HB_EXPR_PCODE1( hb_compGenPushLong, usItems ); + ++usGroups; + } + } + break; + + case HB_EA_POP_PCODE: + case HB_EA_PUSH_POP: + case HB_EA_STATEMENT: + break; + + case HB_EA_DELETE: + if( pSelf->value.asList.pExprList ) + { + HB_EXPR_PTR pTmp, pExpr = pSelf->value.asList.pExprList; + while( pExpr ) + { + pTmp = pExpr->pNext; /* store next expression */ + HB_EXPR_PCODE1( hb_compExprDelete, pExpr ); + pExpr =pTmp; + } + pSelf->value.asList.pExprList = NULL; + } + break; + } + return pSelf; +} + /* handler for ( ( array[ idx ] )[ idx ] )[ idx ] */ static HB_EXPR_FUNC( hb_compExprUseArrayAt ) @@ -1272,7 +1367,7 @@ static HB_EXPR_FUNC( hb_compExprUseArrayAt ) { if( pSelf->value.asList.pIndex->ExprType == HB_ET_MACRO ) { - pSelf->value.asList.pIndex->value.asMacro.SubType |= HB_ET_MACRO_INDEX; + pSelf->value.asList.pIndex->value.asMacro.SubType |= HB_ET_MACRO_INDEX; } } HB_EXPR_USE( pSelf->value.asList.pIndex, HB_EA_PUSH_PCODE ); @@ -1370,14 +1465,14 @@ static HB_EXPR_FUNC( hb_compExprUseMacro ) #if ! defined( HB_MACRO_SUPPORT ) BOOL bUseTextSubst; - char *szDupl; - szDupl = hb_strupr( hb_strdup( pSelf->value.asMacro.szMacro ) ); + char *szDupl; + szDupl = hb_strupr( hb_strdup( pSelf->value.asMacro.szMacro ) ); - if( !hb_compExprIsValidMacro( szDupl, &bUseTextSubst, HB_MACRO_PARAM ) ) - { + if( !hb_compExprIsValidMacro( szDupl, &bUseTextSubst, HB_MACRO_PARAM ) ) + { hb_compErrorMacro( pSelf->value.asMacro.szMacro ); - } - hb_xfree( szDupl ); + } + hb_xfree( szDupl ); #endif HB_EXPR_PCODE2( hb_compGenPushString, pSelf->value.asMacro.szMacro, strlen(pSelf->value.asMacro.szMacro) + 1 ); } @@ -1394,51 +1489,28 @@ static HB_EXPR_FUNC( hb_compExprUseMacro ) { if( HB_COMP_ISSUPPORTED(HB_COMPFLAG_XBASE) ) { - if( pSelf->value.asMacro.SubType & HB_ET_MACRO_ARGLIST ) + if( pSelf->value.asMacro.SubType & HB_ET_MACRO_LIST ) { - /* funCall( ¯o ) - */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSHARG ); - - /* Always add add byte to pcode indicating requested macro compiler flag. */ - #if defined( HB_MACRO_SUPPORT ) - 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 ) - ) - ); - #endif - - /* Generate push symbol for the symbol the possible extra macro arguments will be for. */ - HB_EXPR_USE( pSelf->value.asMacro.pFunCall->value.asFunCall.pFunName, HB_EA_PUSH_PCODE ); - } - else if( pSelf->value.asMacro.SubType & HB_ET_MACRO_LIST ) - { - /* { ¯o } - */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSHLIST ); + /* { ¯o or funCall( ¯o ) } + */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSHLIST ); } else if( pSelf->value.asMacro.SubType & HB_ET_MACRO_INDEX ) { - /* var[ ¯o ] */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSHINDEX ); + /* var[ ¯o ] */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSHINDEX ); } else if( pSelf->value.asMacro.SubType & HB_ET_MACRO_PARE ) { - /* var := (somevalue, ¯o) - in xbase compatibility mode - * EVAL( {|| ¯o} ) - in all cases - */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSHPARE ); + /* var := (somevalue, ¯o) - in xbase compatibility mode + * EVAL( {|| ¯o} ) - in all cases + */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSHPARE ); } else { - /* usual ¯o */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSH ); + /* usual ¯o */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSH ); } } else @@ -1446,15 +1518,14 @@ static HB_EXPR_FUNC( hb_compExprUseMacro ) HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSH ); } - if( ( pSelf->value.asMacro.SubType != HB_ET_MACRO_SYMBOL ) && - ( pSelf->value.asMacro.SubType != HB_ET_MACRO_REFER ) && - ( pSelf->value.asMacro.SubType != HB_ET_MACRO_ALIASED && - ! ( pSelf->value.asMacro.SubType & HB_ET_MACRO_ARGLIST ) ) ) + if( pSelf->value.asMacro.SubType != HB_ET_MACRO_SYMBOL && + pSelf->value.asMacro.SubType != HB_ET_MACRO_REFER && + pSelf->value.asMacro.SubType != HB_ET_MACRO_ALIASED ) { /* Always add add byte to pcode indicating requested macro compiler flag. */ - #if defined( HB_MACRO_SUPPORT ) +#if defined( HB_MACRO_SUPPORT ) HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_COMPFLAG_RT_MACRO ); - #else +#else HB_EXPR_GENPCODE1( hb_compGenPData1, ( ( hb_comp_Supported & HB_COMPFLAG_HARBOUR ? HB_SM_HARBOUR : 0 ) | @@ -1463,7 +1534,7 @@ static HB_EXPR_FUNC( hb_compExprUseMacro ) ( hb_comp_Supported & HB_COMPFLAG_RT_MACRO ? HB_SM_RT_MACRO : 0 ) ) ); - #endif +#endif } /* NOTE: pcode for alias context is generated in @@ -1619,6 +1690,7 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall ) case HB_EA_PUSH_PCODE: { + BOOL fMacroList = FALSE; USHORT usCount; HB_EXPR_USE( pSelf->value.asFunCall.pFunName, HB_EA_PUSH_PCODE ); @@ -1642,22 +1714,34 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall ) { if( pExpr->ExprType == HB_ET_MACRO ) { - pExpr->value.asMacro.SubType |= HB_ET_MACRO_ARGLIST; + /* ¯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; } } - 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( usCount > 255 ) - HB_EXPR_GENPCODE3( hb_compGenPCode3, HB_P_FUNCTION, HB_LOBYTE( usCount ), HB_HIBYTE( usCount ), ( BOOL ) 1 ); + 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, ( BOOL ) 1 ); + HB_EXPR_GENPCODE2( hb_compGenPCode2, HB_P_FUNCTIONSHORT, ( BYTE ) usCount, TRUE ); } break; @@ -1667,6 +1751,7 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall ) 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 ); @@ -1681,29 +1766,40 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall ) { if( HB_SUPPORT_XBASE ) { - HB_EXPR_PTR pExpr = pSelf->value.asFunCall.pParms->value.asList.pExprList; /* 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 ) { - /* ¯o was passed - handle it differently then in a normal statement */ - pExpr->value.asMacro.SubType |= HB_ET_MACRO_ARGLIST; - pExpr->value.asMacro.pFunCall = pSelf; + /* ¯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; } } - 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( usCount > 255 ) - HB_EXPR_GENPCODE3( hb_compGenPCode3, HB_P_DO, HB_LOBYTE( usCount ), HB_HIBYTE( usCount ), ( BOOL ) 1 ); + 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, ( BOOL ) 1 ); + HB_EXPR_GENPCODE2( hb_compGenPCode2, HB_P_DOSHORT, ( BYTE ) usCount, TRUE ); } break; diff --git a/harbour/include/hbexprop.h b/harbour/include/hbexprop.h index aea06d70b7..903deca35e 100644 --- a/harbour/include/hbexprop.h +++ b/harbour/include/hbexprop.h @@ -98,10 +98,9 @@ typedef enum #define HB_ET_MACRO_SYMBOL 1 /* &fimcall() */ #define HB_ET_MACRO_ALIASED 2 /* &alias->&variable */ #define HB_ET_MACRO_EXPR 4 /* &( expr ) */ -#define HB_ET_MACRO_ARGLIST 8 /* &variable used as a function call argument */ -#define HB_ET_MACRO_LIST 16 /* &variable used as in literal arrays or parentesised expressions. */ +#define HB_ET_MACRO_LIST 16 /* &variable used as in literal arrays or function call argument. */ #define HB_ET_MACRO_INDEX 32 /* &variable used as arrays index. */ -#define HB_ET_MACRO_PARE 64 /* &variable used as arrays index. */ +#define HB_ET_MACRO_PARE 64 /* &variable used as parentesised expressions. */ #define HB_ET_MACRO_REFER 128 /* ¯o used in @ (pass by reference) */ /* types of expressions @@ -127,6 +126,7 @@ typedef enum HB_ET_IIF, HB_ET_LIST, HB_ET_ARGLIST, + HB_ET_MACROARGLIST, HB_ET_ARRAYAT, HB_ET_MACRO, HB_ET_FUNCALL, @@ -168,6 +168,8 @@ typedef enum HB_EO_PREDEC /* pre-operators -> the highest precedence */ } HB_EXPR_OPERATOR; +#define HB_EXPR_COUNT ( HB_EO_PREDEC + 1 ) + typedef USHORT HB_EXPRTYPE; typedef struct HB_EXPR_ @@ -241,9 +243,9 @@ typedef struct HB_EXPR_ } value; ULONG ulLength; ULONG Counter; - HB_EXPRTYPE ExprType; /* internal expression type */ - USHORT ValType; /* language level value type */ - struct HB_EXPR_ *pNext; /* next expression in the list of expressions */ + HB_EXPRTYPE ExprType; /* internal expression type */ + USHORT ValType; /* language level value type */ + struct HB_EXPR_ *pNext; /* next expression in the list of expressions */ } HB_EXPR, *HB_EXPR_PTR; /* Definitions of function templates used in expression's message @@ -370,6 +372,7 @@ HB_EXPR_PTR hb_compExprEqual( HB_EXPR_PTR, HB_EXPR_PTR ); HB_EXPR_PTR hb_compExprAssignStatic( HB_EXPR_PTR, HB_EXPR_PTR ); HB_EXPR_PTR hb_compExprClone( HB_EXPR_PTR pSrc ); ULONG hb_compExprListLen( HB_EXPR_PTR ); +ULONG hb_compExprMacroListLen( HB_EXPR_PTR ); void hb_compExprClear( HB_EXPR_PTR ); char * hb_compExprDescription( HB_EXPR_PTR ); int hb_compExprType( HB_EXPR_PTR ); diff --git a/harbour/include/hbpcode.h b/harbour/include/hbpcode.h index c7abd54fae..1dc0727594 100644 --- a/harbour/include/hbpcode.h +++ b/harbour/include/hbpcode.h @@ -109,7 +109,7 @@ typedef enum HB_P_MACROPOP, /* 38 compile and run - pop a value from the stack */ HB_P_MACROPOPALIASED, /* 39 compile and run - pop a field value from the stack */ HB_P_MACROPUSH, /* 40 compile and run - leave the result on the stack */ - HB_P_MACROPUSHARG, /* 41 compile and run - leave the result on the stack */ + HB_P_MACROARRAYGEN, /* 41 generate array from arguments set(s) on HVM stack { &var } */ HB_P_MACROPUSHLIST, /* 42 compile and run - leave the result on the stack */ HB_P_MACROPUSHINDEX, /* 43 compile and run - leave the result on the stack */ HB_P_MACROPUSHPARE, /* 44 compile and run - leave the result on the stack */ @@ -193,8 +193,8 @@ typedef enum HB_P_TRUE, /* 120 pushes true on the virtual machine stack */ HB_P_ZERO, /* 121 places a ZERO on the virtual machine stack */ HB_P_ONE, /* 122 places a ONE on the virtual machine stack */ - HB_P_MACROLIST, /* 123 HB_P_MACROPUSHLIST envelope start. */ - HB_P_MACROLISTEND, /* 124 HB_P_MACROPUSHLIST envelope end. */ + HB_P_MACROFUNC, /* 123 execute a function saving its result */ + HB_P_MACRODO, /* 124 execute a function discarding its result */ HB_P_MPUSHSTR, /* 125 Macro compiled pushed string */ HB_P_LOCALNEARADDINT, /* 126 Add/Subtract specified int into specified local without using the stack. */ HB_P_MACROPUSHREF, /* 127 Reference to macro variable @&mvar */ diff --git a/harbour/include/hbxvm.h b/harbour/include/hbxvm.h index 0d5a62f9c9..f0b126e56c 100644 --- a/harbour/include/hbxvm.h +++ b/harbour/include/hbxvm.h @@ -165,8 +165,9 @@ extern HB_EXPORT void hb_xvmLocalName( USHORT uiLocal, char * szLocalName ); extern HB_EXPORT void hb_xvmStaticName( BYTE bIsGlobal, USHORT uiStatic, char * szStaticName ); extern HB_EXPORT void hb_xvmModuleName( char * szModuleName ); -extern HB_EXPORT void hb_xvmMacroList( void ); -extern HB_EXPORT void hb_xvmMacroListEnd( void ); +extern HB_EXPORT BOOL hb_xvmMacroDo( USHORT uiArgSets ); +extern HB_EXPORT BOOL hb_xvmMacroFunc( USHORT uiArgSets ); +extern HB_EXPORT BOOL hb_xvmMacroArrayGen( USHORT uiArgSets ); extern HB_EXPORT BOOL hb_xvmMacroPush( BYTE bFlags ); extern HB_EXPORT BOOL hb_xvmMacroPushRef( void ); extern HB_EXPORT BOOL hb_xvmMacroPushIndex( BYTE bFlags ); diff --git a/harbour/source/common/expropt1.c b/harbour/source/common/expropt1.c index 985dd55be9..12bc7b5870 100644 --- a/harbour/source/common/expropt1.c +++ b/harbour/source/common/expropt1.c @@ -72,7 +72,7 @@ #define HB_XGRAB( size ) hb_xgrab( (size) ) #define HB_XFREE( pPtr ) hb_xfree( (void *)(pPtr) ) -static char * s_OperTable[] = { +static char * s_OperTable[ HB_EXPR_COUNT ] = { "", "NIL", "Numeric", @@ -88,6 +88,7 @@ static char * s_OperTable[] = { "IIF", ",", ",", + ",", "[", "&", "()", @@ -536,6 +537,19 @@ HB_EXPR_PTR hb_compExprNewArgList( HB_EXPR_PTR pFirstItem ) return pExpr; } +/* Creates a list of function call arguments + */ +HB_EXPR_PTR hb_compExprNewMacroArgList( HB_EXPR_PTR pFirstItem ) +{ + HB_EXPR_PTR pExpr; + + HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewMacroArgList()")); + + pExpr = hb_compExprNew( HB_ET_MACROARGLIST ); + pExpr->value.asList.pExprList = pFirstItem; + return pExpr; +} + /* Adds new element to the list */ HB_EXPR_PTR hb_compExprAddListExpr( HB_EXPR_PTR pList, HB_EXPR_PTR pNewItem ) @@ -902,3 +916,32 @@ ULONG hb_compExprListLen( HB_EXPR_PTR pExpr ) return ulLen; } + +/* Return a number of macro gropu elements on the linked list + */ +ULONG hb_compExprMacroListLen( HB_EXPR_PTR pExpr ) +{ + ULONG ulLen = 0, ulItems = 0; + + pExpr = pExpr->value.asList.pExprList; + while( pExpr ) + { + if( pExpr->ExprType == HB_ET_MACRO && + ( pExpr->value.asMacro.SubType | HB_ET_MACRO_LIST ) ) + { + if( ulItems ) + { + ulItems = 0; + ++ulLen; + } + ++ulLen; + } + else + ++ulItems; + pExpr = pExpr->pNext; + } + if( ulItems ) + ++ulLen; + + return ulLen; +} diff --git a/harbour/source/compiler/genc.c b/harbour/source/compiler/genc.c index 9a62dbbd60..5e73dcf4b1 100644 --- a/harbour/source/compiler/genc.c +++ b/harbour/source/compiler/genc.c @@ -805,13 +805,34 @@ static HB_GENC_FUNC( hb_p_macropushref ) return 1; } -static HB_GENC_FUNC( hb_p_macropusharg ) +static HB_GENC_FUNC( hb_p_macrodo ) { HB_SYMBOL_UNUSED( pFunc ); HB_SYMBOL_UNUSED( lPCodePos ); - fprintf( cargo->yyc, "\tHB_P_MACROPUSHARG, %i,\n", pFunc->pCode[ lPCodePos + 1 ] ); - return 2; + fprintf( cargo->yyc, "\tHB_P_MACRODO, %i, %i,\n", + pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); + return 3; +} + +static HB_GENC_FUNC( hb_p_macrofunc ) +{ + HB_SYMBOL_UNUSED( pFunc ); + HB_SYMBOL_UNUSED( lPCodePos ); + + fprintf( cargo->yyc, "\tHB_P_MACROFUNC, %i, %i,\n", + pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); + return 3; +} + +static HB_GENC_FUNC( hb_p_macroarraygen ) +{ + HB_SYMBOL_UNUSED( pFunc ); + HB_SYMBOL_UNUSED( lPCodePos ); + + fprintf( cargo->yyc, "\tHB_P_MACROARRAYGEN, %i, %i,\n", + pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); + return 3; } static HB_GENC_FUNC( hb_p_macropushlist ) @@ -1771,27 +1792,10 @@ static HB_GENC_FUNC( hb_p_dummy ) return 1; } -static HB_GENC_FUNC( hb_p_macrolist ) -{ - HB_SYMBOL_UNUSED( pFunc ); - HB_SYMBOL_UNUSED( lPCodePos ); - - fprintf( cargo->yyc, "\tHB_P_MACROLIST,\n" ); - return 1; -} - -static HB_GENC_FUNC( hb_p_macrolistend ) -{ - HB_SYMBOL_UNUSED( pFunc ); - HB_SYMBOL_UNUSED( lPCodePos ); - - fprintf( cargo->yyc, "\tHB_P_MACROLISTEND,\n" ); - return 1; -} - static HB_GENC_FUNC( hb_p_enumstart ) { - fprintf( cargo->yyc, "\tHB_P_ENUMSTART, %i, %i,\n", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); + fprintf( cargo->yyc, "\tHB_P_ENUMSTART, %i, %i,\n", + pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); return 3; } @@ -2023,7 +2027,7 @@ static HB_GENC_FUNC_PTR s_verbose_table[] = { hb_p_macropop, hb_p_macropopaliased, hb_p_macropush, - hb_p_macropusharg, + hb_p_macroarraygen, hb_p_macropushlist, hb_p_macropushindex, hb_p_macropushpare, @@ -2107,8 +2111,8 @@ static HB_GENC_FUNC_PTR s_verbose_table[] = { hb_p_true, hb_p_zero, hb_p_one, - hb_p_macrolist, - hb_p_macrolistend, + hb_p_macrofunc, + hb_p_macrodo, /* start: more pcodes generated by macro compiler */ hb_p_dummy, /* end: */ diff --git a/harbour/source/compiler/gencc.c b/harbour/source/compiler/gencc.c index 288e698528..6547472645 100644 --- a/harbour/source/compiler/gencc.c +++ b/harbour/source/compiler/gencc.c @@ -597,26 +597,31 @@ static HB_GENC_FUNC( hb_p_macropushref ) return 1; } -static HB_GENC_FUNC( hb_p_macropusharg ) +static HB_GENC_FUNC( hb_p_macrodo ) { - USHORT usSize, usSymbol; - HB_GENC_LABEL(); - if( pFunc->pCode[ lPCodePos + 2 ] == HB_P_PUSHSYMNEAR ) - { - usSymbol = pFunc->pCode[ lPCodePos + 3 ]; - usSize = 4; - } - else - { - usSymbol = HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 3 ] ); - usSize = 5; - } + fprintf( cargo->yyc, "\tif( hb_xvmMacroDo( %hu ) ) break;\n", + HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ) ); + return 3; +} - fprintf( cargo->yyc, "\tif( hb_xvmMacroPushArg( symbols + %hu, %d ) ) break;\n", - usSymbol, pFunc->pCode[ lPCodePos + 1 ] ); - return usSize; +static HB_GENC_FUNC( hb_p_macrofunc ) +{ + HB_GENC_LABEL(); + + fprintf( cargo->yyc, "\tif( hb_xvmMacroFunc( %hu ) ) break;\n", + HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ) ); + return 3; +} + +static HB_GENC_FUNC( hb_p_macroarraygen ) +{ + HB_GENC_LABEL(); + + fprintf( cargo->yyc, "\tif( hb_xvmMacroArrayGen( %hu ) ) break;\n", + HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ) ); + return 3; } static HB_GENC_FUNC( hb_p_macropushlist ) @@ -1357,22 +1362,6 @@ static HB_GENC_FUNC( hb_p_dummy ) return 1; } -static HB_GENC_FUNC( hb_p_macrolist ) -{ - HB_GENC_LABEL(); - - fprintf( cargo->yyc, "\thb_xvmMacroList();\n" ); - return 1; -} - -static HB_GENC_FUNC( hb_p_macrolistend ) -{ - HB_GENC_LABEL(); - - fprintf( cargo->yyc, "\thb_xvmMacroListEnd();\n" ); - return 1; -} - static HB_GENC_FUNC( hb_p_enumstart ) { HB_GENC_LABEL(); @@ -1620,7 +1609,7 @@ static HB_GENC_FUNC_PTR s_verbose_table[] = { hb_p_macropop, hb_p_macropopaliased, hb_p_macropush, - hb_p_macropusharg, + hb_p_macroarraygen, hb_p_macropushlist, hb_p_macropushindex, hb_p_macropushpare, @@ -1704,8 +1693,8 @@ static HB_GENC_FUNC_PTR s_verbose_table[] = { hb_p_true, hb_p_zero, hb_p_one, - hb_p_macrolist, - hb_p_macrolistend, + hb_p_macrofunc, + hb_p_macrodo, /* start: more pcodes generated by macro compiler */ hb_p_dummy, /* end: */ diff --git a/harbour/source/compiler/gencli.c b/harbour/source/compiler/gencli.c index 47fc13deb9..53cca1d863 100644 --- a/harbour/source/compiler/gencli.c +++ b/harbour/source/compiler/gencli.c @@ -775,13 +775,34 @@ static HB_GENC_FUNC( hb_p_macropushref ) return 1; } -static HB_GENC_FUNC( hb_p_macropusharg ) +static HB_GENC_FUNC( hb_p_macrodo ) { HB_SYMBOL_UNUSED( pFunc ); HB_SYMBOL_UNUSED( lPCodePos ); - fprintf( cargo->yyc, "\tHB_P_MACROPUSHARG, %i,\n", pFunc->pCode[ lPCodePos + 1 ] ); - return 2; + fprintf( cargo->yyc, "\tHB_P_MACRODO, %i, %i,\n", + pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); + return 3; +} + +static HB_GENC_FUNC( hb_p_macrofunc ) +{ + HB_SYMBOL_UNUSED( pFunc ); + HB_SYMBOL_UNUSED( lPCodePos ); + + fprintf( cargo->yyc, "\tHB_P_MACROFUNC, %i, %i,\n", + pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); + return 3; +} + +static HB_GENC_FUNC( hb_p_macroarraygen ) +{ + HB_SYMBOL_UNUSED( pFunc ); + HB_SYMBOL_UNUSED( lPCodePos ); + + fprintf( cargo->yyc, "\tHB_P_MACROARRAYGEN, %i, %i,\n", + pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); + return 3; } static HB_GENC_FUNC( hb_p_macropushlist ) @@ -1741,28 +1762,11 @@ static HB_GENC_FUNC( hb_p_dummy ) return 1; } -static HB_GENC_FUNC( hb_p_macrolist ) -{ - HB_SYMBOL_UNUSED( pFunc ); - HB_SYMBOL_UNUSED( lPCodePos ); - - fprintf( cargo->yyc, "\tHB_P_MACROLIST,\n" ); - return 1; -} - -static HB_GENC_FUNC( hb_p_macrolistend ) -{ - HB_SYMBOL_UNUSED( pFunc ); - HB_SYMBOL_UNUSED( lPCodePos ); - - fprintf( cargo->yyc, "\tHB_P_MACROLISTEND,\n" ); - return 1; -} - static HB_GENC_FUNC( hb_p_enumstart ) { - fprintf( cargo->yyc, "\tHB_P_ENUMSTART, %i,\n", pFunc->pCode[ lPCodePos + 1 ] ); - return 2; + fprintf( cargo->yyc, "\tHB_P_ENUMSTART, %i, %i,\n", + pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); + return 3; } static HB_GENC_FUNC( hb_p_enumnext ) @@ -1849,7 +1853,7 @@ static HB_GENC_FUNC_PTR s_verbose_table[] = { hb_p_macropop, hb_p_macropopaliased, hb_p_macropush, - hb_p_macropusharg, + hb_p_macroarraygen, hb_p_macropushlist, hb_p_macropushindex, hb_p_macropushpare, @@ -1933,8 +1937,8 @@ static HB_GENC_FUNC_PTR s_verbose_table[] = { hb_p_true, hb_p_zero, hb_p_one, - hb_p_macrolist, - hb_p_macrolistend, + hb_p_macrofunc, + hb_p_macrodo, /* start: more pcodes generated by macro compiler */ hb_p_dummy, /* end: */ diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 3747e31747..d38777d128 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -1624,19 +1624,11 @@ ForNext : FOR LValue ForAssign Expression /* 1 2 3 4 */ } Crlf /* 10 */ { -#if 0 /* This is real Clipper behavior which I'll restore when we add PCODE version checking */ if( $8 ) hb_compGenPCode1( HB_P_FORTEST ); else hb_compGenPCode1( HB_P_GREATER ); $$ = hb_compGenJumpTrue( 0 ); /* 11 */ -#else - if( $8 ) - hb_compGenPCode1( HB_P_FORTEST ); - else - hb_compGenPCode1( HB_P_LESSEQUAL ); - $$ = hb_compGenJumpFalse( 0 ); /* 11 */ -#endif } ForStatements /* 12 */ { diff --git a/harbour/source/compiler/hbdead.c b/harbour/source/compiler/hbdead.c index 20bc868882..1cf6d8c62e 100644 --- a/harbour/source/compiler/hbdead.c +++ b/harbour/source/compiler/hbdead.c @@ -348,7 +348,7 @@ static PHB_CODETRACE_FUNC s_codeTraceFuncTable[ HB_P_LAST_PCODE ] = hb_p_default, /* HB_P_MACROPOP, */ hb_p_default, /* HB_P_MACROPOPALIASED, */ hb_p_default, /* HB_P_MACROPUSH, */ - hb_p_default, /* HB_P_MACROPUSHARG, */ + hb_p_default, /* HB_P_MACROARRAYGEN, */ hb_p_default, /* HB_P_MACROPUSHLIST, */ hb_p_default, /* HB_P_MACROPUSHINDEX, */ hb_p_default, /* HB_P_MACROPUSHPARE, */ @@ -432,8 +432,8 @@ static PHB_CODETRACE_FUNC s_codeTraceFuncTable[ HB_P_LAST_PCODE ] = hb_p_default, /* HB_P_TRUE, */ hb_p_default, /* HB_P_ZERO, */ hb_p_default, /* HB_P_ONE, */ - hb_p_default, /* HB_P_MACROLIST, */ - hb_p_default, /* HB_P_MACROLISTEND, */ + hb_p_default, /* HB_P_MACROFUNC, */ + hb_p_default, /* HB_P_MACRODO, */ hb_p_default, /* HB_P_MPUSHSTR, */ hb_p_default, /* HB_P_LOCALNEARADDINT, */ hb_p_default, /* HB_P_MACROPUSHREF */ diff --git a/harbour/source/compiler/hbfix.c b/harbour/source/compiler/hbfix.c index 8189f22a29..aa1b180bd1 100644 --- a/harbour/source/compiler/hbfix.c +++ b/harbour/source/compiler/hbfix.c @@ -529,7 +529,7 @@ static HB_FIX_FUNC_PTR s_fixlocals_table[] = NULL, /* HB_P_MACROPOP, */ NULL, /* HB_P_MACROPOPALIASED, */ NULL, /* HB_P_MACROPUSH, */ - NULL, /* HB_P_MACROPUSHARG, */ + NULL, /* HB_P_MACROARRAYGEN, */ NULL, /* HB_P_MACROPUSHLIST, */ NULL, /* HB_P_MACROPUSHINDEX, */ NULL, /* HB_P_MACROPUSHPARE, */ @@ -613,8 +613,8 @@ static HB_FIX_FUNC_PTR s_fixlocals_table[] = hb_p_true, /* HB_P_TRUE, */ NULL, /* HB_P_ZERO, */ NULL, /* HB_P_ONE, */ - NULL, /* HB_P_MACROLIST, */ - NULL, /* HB_P_MACROLISTEND, */ + NULL, /* HB_P_MACROFUNC, */ + NULL, /* HB_P_MACRODO, */ NULL, /* HB_P_MPUSHSTR, */ hb_p_localnearaddint, /* HB_P_LOCALNEARADDINT, */ NULL, /* HB_P_MACROPUSHREF */ diff --git a/harbour/source/compiler/hblbl.c b/harbour/source/compiler/hblbl.c index 01bf7dadb3..7dd32b0e0d 100644 --- a/harbour/source/compiler/hblbl.c +++ b/harbour/source/compiler/hblbl.c @@ -212,7 +212,7 @@ static PHB_LABEL_FUNC s_GenLabelFuncTable[ HB_P_LAST_PCODE ] = NULL, /* HB_P_MACROPOP, */ NULL, /* HB_P_MACROPOPALIASED, */ NULL, /* HB_P_MACROPUSH, */ - NULL, /* HB_P_MACROPUSHARG, */ + NULL, /* HB_P_MACROARRAYGEN, */ NULL, /* HB_P_MACROPUSHLIST, */ NULL, /* HB_P_MACROPUSHINDEX, */ NULL, /* HB_P_MACROPUSHPARE, */ @@ -296,8 +296,8 @@ static PHB_LABEL_FUNC s_GenLabelFuncTable[ HB_P_LAST_PCODE ] = NULL, /* HB_P_TRUE, */ NULL, /* HB_P_ZERO, */ NULL, /* HB_P_ONE, */ - NULL, /* HB_P_MACROLIST, */ - NULL, /* HB_P_MACROLISTEND, */ + NULL, /* HB_P_MACROFUNC, */ + NULL, /* HB_P_MACRODO, */ NULL, /* HB_P_MPUSHSTR, */ NULL, /* HB_P_LOCALNEARADDINT, */ NULL, /* HB_P_MACROPUSHREF */ diff --git a/harbour/source/compiler/hbpcode.c b/harbour/source/compiler/hbpcode.c index d81896d2a6..26084d6ed9 100644 --- a/harbour/source/compiler/hbpcode.c +++ b/harbour/source/compiler/hbpcode.c @@ -145,7 +145,7 @@ const BYTE hb_comp_pcode_len[] = { 2, /* HB_P_MACROPOP, */ 2, /* HB_P_MACROPOPALIASED, */ 2, /* HB_P_MACROPUSH, */ - 2, /* HB_P_MACROPUSHARG, */ + 3, /* HB_P_MACROARRAYGEN, */ 2, /* HB_P_MACROPUSHLIST, */ 2, /* HB_P_MACROPUSHINDEX, */ 2, /* HB_P_MACROPUSHPARE, */ @@ -229,8 +229,8 @@ const BYTE hb_comp_pcode_len[] = { 1, /* HB_P_TRUE, */ 1, /* HB_P_ZERO, */ 1, /* HB_P_ONE, */ - 1, /* HB_P_MACROLIST, */ - 1, /* HB_P_MACROLISTEND, */ + 3, /* HB_P_MACROFUNC, */ + 3, /* HB_P_MACRODO, */ 0, /* HB_P_MPUSHSTR */ 4, /* HB_P_LOCALNEARADDINT, */ 1, /* HB_P_MACROPUSHREF */ @@ -302,7 +302,7 @@ static HB_PCODE_FUNC_PTR s_psize_table[] = NULL, /* HB_P_MACROPOP, */ NULL, /* HB_P_MACROPOPALIASED, */ NULL, /* HB_P_MACROPUSH, */ - NULL, /* HB_P_MACROPUSHARG, */ + NULL, /* HB_P_MACROARRAYGEN, */ NULL, /* HB_P_MACROPUSHLIST, */ NULL, /* HB_P_MACROPUSHINDEX, */ NULL, /* HB_P_MACROPUSHPARE, */ @@ -386,8 +386,8 @@ static HB_PCODE_FUNC_PTR s_psize_table[] = NULL, /* HB_P_TRUE, */ NULL, /* HB_P_ZERO, */ NULL, /* HB_P_ONE, */ - NULL, /* HB_P_MACROLIST, */ - NULL, /* HB_P_MACROLISTEND, */ + NULL, /* HB_P_MACROFUNC, */ + NULL, /* HB_P_MACRODO, */ NULL, /* HB_P_MPUSHSTR, */ NULL, /* HB_P_LOCALNEARADDINT, */ NULL, /* HB_P_MACROPUSHREF */ diff --git a/harbour/source/compiler/hbstripl.c b/harbour/source/compiler/hbstripl.c index b89d7367c2..2d1fd5793d 100644 --- a/harbour/source/compiler/hbstripl.c +++ b/harbour/source/compiler/hbstripl.c @@ -117,7 +117,7 @@ static PHB_STRIP_FUNC s_stripLines_table[] = NULL, /* HB_P_MACROPOP, */ NULL, /* HB_P_MACROPOPALIASED, */ NULL, /* HB_P_MACROPUSH, */ - NULL, /* HB_P_MACROPUSHARG, */ + NULL, /* HB_P_MACROARRAYGEN, */ NULL, /* HB_P_MACROPUSHLIST, */ NULL, /* HB_P_MACROPUSHINDEX, */ NULL, /* HB_P_MACROPUSHPARE, */ @@ -201,8 +201,8 @@ static PHB_STRIP_FUNC s_stripLines_table[] = NULL, /* HB_P_TRUE, */ NULL, /* HB_P_ZERO, */ NULL, /* HB_P_ONE, */ - NULL, /* HB_P_MACROLIST, */ - NULL, /* HB_P_MACROLISTEND, */ + NULL, /* HB_P_MACROFUNC, */ + NULL, /* HB_P_MACRODO, */ NULL, /* HB_P_MPUSHSTR, */ NULL, /* HB_P_LOCALNEARADDINT, */ NULL, /* HB_P_MACROPUSHREF */ diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index c2dd649b68..53d73f7e3b 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -141,7 +141,10 @@ static void hb_vmArrayDim( USHORT uiDimensions ); /* generates an uiDimension static void hb_vmArrayGen( ULONG ulElements ); /* generates an ulElements Array and fills it from the stack values */ /* macros */ -static void hb_vmMacroPushIndex( BYTE bFlags ); /* push macro array index {...}[ &var ] */ +static void hb_vmMacroDo( USHORT uiArgSets ); /* execute function passing arguments set(s) on HVM stack func( &var ) */ +static void hb_vmMacroFunc( USHORT uiArgSets ); /* execute procedure passing arguments set(s) on HVM stack func( &var ) */ +static void hb_vmMacroArrayGen( USHORT uiArgSets ); /* generate array from arguments set(s) on HVM stack { &var } */ +static void hb_vmMacroPushIndex( BYTE bFlags ); /* push macro array index {...}[ &var ] */ /* Database */ static ERRCODE hb_vmSelectWorkarea( PHB_ITEM, PHB_SYMB ); /* select the workarea using a given item or a substituted value */ @@ -264,11 +267,6 @@ static LONG s_lRecoverBase; */ static ULONG s_ulProcLevel = 0; -int hb_vm_aiExtraParams[HB_MAX_MACRO_ARGS], hb_vm_iExtraParamsIndex = 0; -PHB_SYMB hb_vm_apExtraParamsSymbol[HB_MAX_MACRO_ARGS]; - -int hb_vm_aiExtraElements[HB_MAX_MACRO_ARGS], hb_vm_iExtraElementsIndex = 0, hb_vm_iExtraElements = 0; - /* Request for some action - stop processing of opcodes */ static USHORT s_uiActionRequest; @@ -898,8 +896,7 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_ARRAYGEN: - hb_vmArrayGen( HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) + hb_vm_iExtraElements ); - hb_vm_iExtraElements = 0; + hb_vmArrayGen( HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ) ); w += 3; break; @@ -1566,56 +1563,6 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) w++; break; - case HB_P_MACROPUSHARG: - /* compile and run - leave the result on the stack */ - /* the topmost element on the stack contains a macro - * string for compilation - */ - hb_macroGetValue( hb_stackItemFromTop( -1 ), HB_P_MACROPUSHARG, pCode[ ++w ] ); - w++; - - if( hb_vm_iExtraParamsIndex && hb_vm_apExtraParamsSymbol[hb_vm_iExtraParamsIndex - 1] == NULL ) - { - if( pCode[w] == HB_P_PUSHSYMNEAR ) - { - hb_vm_apExtraParamsSymbol[hb_vm_iExtraParamsIndex - 1] = pSymbols + ( USHORT ) ( pCode[w + 1] ); - w += 2; - } - else if( pCode[w] == HB_P_MPUSHSYM ) - { - HB_DYNS_PTR pDynSym = ( HB_DYNS_PTR ) HB_GET_PTR( pCode + w + 1 ); - - hb_vm_apExtraParamsSymbol[hb_vm_iExtraParamsIndex - 1] = pDynSym->pSymbol; - w += sizeof( HB_DYNS_PTR ) + 1; - } - else - { - hb_vm_apExtraParamsSymbol[hb_vm_iExtraParamsIndex - 1] = pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ); - w += 3; - } - } - else - { - if( pCode[w] == HB_P_PUSHSYMNEAR ) - { - w += 2; - } - else if( pCode[w] == HB_P_MPUSHSYM ) - { - w += sizeof( HB_DYNS_PTR ) + 1; - } - else - { - w += 3; - } - } - break; - - case HB_P_MACROLIST: - hb_vm_aiExtraElements[hb_vm_iExtraElementsIndex++] = 0; - w++; - break; - case HB_P_MACROPUSHLIST: /* compile and run - leave the result on the stack */ /* the topmost element on the stack contains a macro @@ -1625,16 +1572,26 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) w++; break; - case HB_P_MACROLISTEND: - hb_vm_iExtraElements = hb_vm_aiExtraElements[--hb_vm_iExtraElementsIndex]; - w++; - break; - case HB_P_MACROPUSHINDEX: hb_vmMacroPushIndex( pCode[ ++w ] ); ++w; break; + case HB_P_MACROARRAYGEN: + hb_vmMacroArrayGen( HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ) ); + w += 3; + break; + + case HB_P_MACRODO: + hb_vmMacroDo( HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ) ); + w += 3; + break; + + case HB_P_MACROFUNC: + hb_vmMacroFunc( HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ) ); + w += 3; + break; + case HB_P_MACROPUSHPARE: /* compile and run - leave the result on the stack */ /* the topmost element on the stack contains a macro @@ -3040,17 +2997,10 @@ static void hb_vmForTest( void ) /* Test to check the end point of the FO return; } -#if 0 /* This is real Clipper behavior which I'll restore when we add PCODE version checking */ if( fBack ) hb_vmLess(); else hb_vmGreater(); -#else - if( fBack ) - hb_vmGreaterEqual(); - else - hb_vmLessEqual(); -#endif } /* With object auto destructor */ @@ -3754,6 +3704,79 @@ static void hb_vmMacroPushIndex( BYTE bFlags ) } } +/* + * On HVM stack we have sets with arguments + * offset value + * (-9) 6 + * (-8) 7 + * (-7) 2 // number of arguments + * (-6) 1 + * (-5) 2 + * (-4) 2 // number of arguments + * (-3) 1 + * (-2) 2 + * (-1) 2 // number of arguments + * we should join them into one continuous list + */ +static LONG hb_vmArgsJoin( LONG lLevel, USHORT uiArgSets ) +{ + LONG lArgs, lRestArgs, lOffset; + PHB_ITEM pArgs = hb_stackItemFromTop( lLevel ) ; + + + lArgs = hb_itemGetNL( pArgs ); + if( HB_IS_COMPLEX( pArgs ) ) + hb_itemClear( pArgs ); + + if( --uiArgSets ) + { + lRestArgs = lArgs; + lArgs += hb_vmArgsJoin( lLevel - lArgs - 1, uiArgSets ); + lOffset = lLevel - lRestArgs - uiArgSets; + while( lRestArgs-- ) + { + hb_itemMove( hb_stackItemFromTop( lOffset ), + hb_stackItemFromTop( lOffset + uiArgSets ) ); + ++lOffset; + } + } + + return lArgs; +} + +static void hb_vmMacroDo( USHORT uiArgSets ) +{ + LONG lArgs; + + HB_TRACE(HB_TR_DEBUG, ("hb_vmMacroDo(%hu)", uiArgSets)); + + lArgs = hb_vmArgsJoin( -1, uiArgSets ); + hb_stackDecrease( uiArgSets ); + hb_vmDo( lArgs ); +} + +static void hb_vmMacroFunc( USHORT uiArgSets ) +{ + LONG lArgs; + + HB_TRACE(HB_TR_DEBUG, ("hb_vmMacroFunc(%hu)", uiArgSets)); + + lArgs = hb_vmArgsJoin( -1, uiArgSets ); + hb_stackDecrease( uiArgSets ); + hb_vmDo( lArgs ); + hb_stackPushReturn(); +} + +static void hb_vmMacroArrayGen( USHORT uiArgSets ) +{ + LONG lArgs; + + HB_TRACE(HB_TR_DEBUG, ("hb_vmMacroArrayGen(%hu)", uiArgSets)); + + lArgs = hb_vmArgsJoin( -1, uiArgSets ); + hb_stackDecrease( uiArgSets ); + hb_vmArrayGen( lArgs ); +} /* ------------------------------- */ /* Database */ @@ -3904,23 +3927,8 @@ HB_EXPORT void hb_vmDo( USHORT uiParams ) HB_TRACE(HB_TR_DEBUG, ("hb_vmDo(%hu)", uiParams)); - /* - printf( "\VmDo nItems: %i Params: %i Extra %i\n", hb_stack.pPos - hb_stack.pBase, uiParams, hb_vm_aiExtraParams[hb_vm_iExtraParamsIndex - 1] ); - */ s_ulProcLevel++; - if( hb_vm_iExtraParamsIndex ) - { - pSelf = hb_stackItemFromTop( -( uiParams + - hb_vm_aiExtraParams[hb_vm_iExtraParamsIndex - 1] + 2 ) ); - if( HB_IS_SYMBOL( pSelf ) && - pSelf->item.asSymbol.value == - hb_vm_apExtraParamsSymbol[hb_vm_iExtraParamsIndex - 1] ) - { - uiParams += hb_vm_aiExtraParams[--hb_vm_iExtraParamsIndex]; - } - } - #ifndef HB_NO_PROFILER if( bProfiler ) ulClock = ( ULONG ) clock(); @@ -4029,18 +4037,8 @@ HB_EXPORT void hb_vmSend( USHORT uiParams ) HB_TRACE(HB_TR_DEBUG, ("hb_vmSend(%hu)", uiParams)); - /* - printf( "\n VmSend nItems: %i Params: %i Extra %i\n", hb_stack.pPos - hb_stack.pBase, uiParams, hb_vm_aiExtraParams[hb_vm_iExtraParamsIndex - 1] ); - */ s_ulProcLevel++; - if( hb_vm_iExtraParamsIndex && - HB_IS_SYMBOL( pItem = hb_stackItemFromTop( -( uiParams + hb_vm_aiExtraParams[hb_vm_iExtraParamsIndex - 1] + 2 ) ) ) && - pItem->item.asSymbol.value == hb_vm_apExtraParamsSymbol[hb_vm_iExtraParamsIndex - 1] ) - { - uiParams += hb_vm_aiExtraParams[--hb_vm_iExtraParamsIndex]; - } - #ifndef HB_NO_PROFILER if( bProfiler ) ulClock = ( ULONG ) clock(); @@ -7471,8 +7469,7 @@ HB_EXPORT void hb_xvmArrayGen( ULONG ulElements ) { HB_TRACE(HB_TR_DEBUG, ("hb_xvmArrayGen(%lu)", ulElements)); - hb_vmArrayGen( ulElements + hb_vm_iExtraElements ); - hb_vm_iExtraElements = 0; + hb_vmArrayGen( ulElements ); } static void hb_vmArrayItemPush( ULONG ulIndex ) @@ -7694,18 +7691,31 @@ HB_EXPORT void hb_xvmModuleName( char * szModuleName ) hb_vmModuleName( szModuleName ); } -HB_EXPORT void hb_xvmMacroList( void ) +HB_EXPORT BOOL hb_xvmMacroArrayGen( USHORT uiArgSets ) { - HB_TRACE(HB_TR_DEBUG, ("hb_xvmMacroList()")); + HB_TRACE(HB_TR_DEBUG, ("hb_xvmMacroArrayGen(%hu)", uiArgSets)); - hb_vm_aiExtraElements[hb_vm_iExtraElementsIndex++] = 0; + hb_vmMacroArrayGen( uiArgSets ); + + HB_XVM_RETURN } -HB_EXPORT void hb_xvmMacroListEnd( void ) +HB_EXPORT BOOL hb_xvmMacroDo( USHORT uiArgSets ) { - HB_TRACE(HB_TR_DEBUG, ("hb_xvmMacroListEnd()")); + HB_TRACE(HB_TR_DEBUG, ("hb_xvmMacroDo(%hu)", uiArgSets)); - hb_vm_iExtraElements = hb_vm_aiExtraElements[--hb_vm_iExtraElementsIndex]; + hb_vmMacroDo( uiArgSets ); + + HB_XVM_RETURN +} + +HB_EXPORT BOOL hb_xvmMacroFunc( USHORT uiArgSets ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_xvmMacroFunc(%hu)", uiArgSets)); + + hb_vmMacroFunc( uiArgSets ); + + HB_XVM_RETURN } HB_EXPORT BOOL hb_xvmMacroPush( BYTE bFlags ) @@ -7739,20 +7749,6 @@ HB_EXPORT BOOL hb_xvmMacroPushIndex( BYTE bFlags ) HB_XVM_RETURN } -HB_EXPORT BOOL hb_xvmMacroPushArg( PHB_SYMB pSymbol, BYTE bFlags ) -{ - HB_TRACE(HB_TR_DEBUG, ("hb_xvmMacroPushArg(%p, %d)", pSymbol, bFlags)); - - hb_macroGetValue( hb_stackItemFromTop( -1 ), HB_P_MACROPUSHARG, bFlags ); - - if( hb_vm_iExtraParamsIndex && hb_vm_apExtraParamsSymbol[hb_vm_iExtraParamsIndex - 1] == NULL ) - { - hb_vm_apExtraParamsSymbol[hb_vm_iExtraParamsIndex - 1] = pSymbol; - } - - HB_XVM_RETURN -} - HB_EXPORT BOOL hb_xvmMacroPushList( BYTE bFlags ) { HB_TRACE(HB_TR_DEBUG, ("hb_xvmMacroPushList(%d)", bFlags)); diff --git a/harbour/source/vm/macro.c b/harbour/source/vm/macro.c index 20c9ca1035..e92fd59ab0 100644 --- a/harbour/source/vm/macro.c +++ b/harbour/source/vm/macro.c @@ -504,7 +504,6 @@ char * hb_macroTextSubst( char * szString, ULONG *pulStringLen ) * PUSH operation * iContext contains additional info when HB_SM_XBASE is enabled * = 0 - in Clipper strict compatibility mode - * = HB_P_MACROPUSHARG - in xbase compatibility mode * = HB_P_MACROPUSHLIST * = HB_P_MACROPUSHINDEX * = HB_P_MACROPUSHPARE @@ -513,11 +512,6 @@ char * hb_macroTextSubst( char * szString, ULONG *pulStringLen ) * EVAL( {|| ¯o} ) * */ - /* TODO: remove these externals */ - extern int hb_vm_aiExtraParams[HB_MAX_MACRO_ARGS], hb_vm_iExtraParamsIndex; - extern int hb_vm_aiExtraElements[HB_MAX_MACRO_ARGS], hb_vm_iExtraElementsIndex; - - extern PHB_SYMB hb_vm_apExtraParamsSymbol[HB_MAX_MACRO_ARGS]; void hb_macroGetValue( HB_ITEM_PTR pItem, BYTE iContext, BYTE flags ) { @@ -552,7 +546,7 @@ void hb_macroGetValue( HB_ITEM_PTR pItem, BYTE iContext, BYTE flags ) * macro := "1,2" * EVAL( {|| ¯o} ) * - */ + */ struMacro.Flags |= HB_MACRO_GEN_LIST; if( iContext == HB_P_MACROPUSHPARE ) { @@ -587,12 +581,6 @@ void hb_macroGetValue( HB_ITEM_PTR pItem, BYTE iContext, BYTE flags ) #endif iStatus = hb_macroParse( &struMacro, szString ); - - if( iContext && ( ( hb_vm_iExtraParamsIndex == HB_MAX_MACRO_ARGS ) || ( hb_vm_iExtraElementsIndex >= HB_MAX_MACRO_ARGS ) ) ) - { - hb_macroSyntaxError( &struMacro ); - } - #ifdef HB_MACRO_STATEMENTS if( struMacro.supported & HB_SM_PREPROC ) { @@ -608,14 +596,9 @@ void hb_macroGetValue( HB_ITEM_PTR pItem, BYTE iContext, BYTE flags ) if( iContext ) { - if( iContext == HB_P_MACROPUSHARG ) + if( iContext == HB_P_MACROPUSHLIST ) { - hb_vm_aiExtraParams[hb_vm_iExtraParamsIndex] = struMacro.iListElements; - hb_vm_apExtraParamsSymbol[hb_vm_iExtraParamsIndex++] = NULL; - } - else if( iContext == HB_P_MACROPUSHLIST ) - { - hb_vm_aiExtraElements[hb_vm_iExtraElementsIndex - 1] += struMacro.iListElements; + hb_vmPushLong( struMacro.iListElements + 1 ); } else if( iContext == HB_P_MACROPUSHINDEX ) {