diff --git a/harbour/ChangeLog b/harbour/ChangeLog index fb5806c30a..37253538b8 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,17 @@ +2001-07-15 20:45 UTC-0800 Ron Pinkas + * include/hbapi.h + + Added member iListElements to HB_MACRO structure. + + * source/macro/macro.y + + Added rules to support a macro of a comma seperated list. + + * source/vm/hvm.c + + Added: int hb_vm_iFunCalls = 0, *hb_vm_aiMacroListParameters = NULL, hb_vm_iMacroListAllocated + to support new logic to track number of extra parameters introduced by means of a macro expanded to a list. + + * source/vm/macro.c + + Added logic to track number of extra parameters introduced by means of a macro expanded to a list. + 2001-07-15 20:15 MEST Martin Vogel * source/rtl/math.c + added functions for custom math handlers diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index f0d59711cd..60d594bb02 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -521,7 +521,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 exprType; /* type of successfully compiled expression */ + int iListElements; } HB_MACRO, * HB_MACRO_PTR; extern void hb_macroGetValue( HB_ITEM_PTR pItem ); /* retrieve results of a macro expansion */ diff --git a/harbour/source/macro/macro.y b/harbour/source/macro/macro.y index 6fcc020196..3edb6d2ba2 100644 --- a/harbour/source/macro/macro.y +++ b/harbour/source/macro/macro.y @@ -193,7 +193,7 @@ int yylex( YYSTYPE *, HB_MACRO_PTR ); %type ObjectData %type ObjectMethod %type IfInline -%type ExpList PareExpList PareExpListAlias +%type ExpList PareExpList PareExpListAlias AsParamList RootParamList %type Expression SimpleExpression %type EmptyExpression %type ExprAssign ExprOperEq ExprPreOp ExprPostOp @@ -222,6 +222,14 @@ Main : Expression '\n' { hb_compExprDelete( hb_compExprGenPop( $1, HB_MACRO_PARAM ), HB_MACRO_PARAM ); hb_compGenPCode1( HB_P_ENDPROC, HB_MACRO_PARAM ); } + | AsParamList { + HB_MACRO_DATA->exprType = hb_compExprType( $1 ); + if( HB_MACRO_DATA->Flags & HB_MACRO_GEN_PUSH ) + hb_compExprDelete( hb_compExprGenPush( $1, HB_MACRO_PARAM ), HB_MACRO_PARAM ); + else + hb_compExprDelete( hb_compExprGenPop( $1, HB_MACRO_PARAM ), 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 ); @@ -457,8 +465,14 @@ SimpleExpression : | ExprRelation { $$ = $1; } ; -Expression : SimpleExpression { $$ = $1; HB_MACRO_CHECK( $$ ); } - | PareExpList { $$ = $1; HB_MACRO_CHECK( $$ ); } +Expression : SimpleExpression { $$ = $1; HB_MACRO_CHECK( $$ ); } + | PareExpList { $$ = $1; HB_MACRO_CHECK( $$ ); } +; + +RootParamList : EmptyExpression ',' EmptyExpression { HB_MACRO_DATA->iListElements = 1; $$ = hb_compExprAddListExpr( hb_compExprNewArgList( $1 ), $3 ); } + +AsParamList : RootParamList { $$ = $1; } + | AsParamList ',' EmptyExpression { HB_MACRO_DATA->iListElements++; $$ = hb_compExprAddListExpr( $1, $3 ); } ; EmptyExpression: /* nothing => nil */ { $$ = hb_compExprNewEmpty(); } diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index a5da1bd32e..c74ad6de43 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -247,6 +247,8 @@ static LONG s_lRecoverBase; #define HB_RECOVER_ADDRESS -3 #define HB_RECOVER_VALUE -4 +int hb_vm_iFunCalls = 0, *hb_vm_aiMacroListParameters = NULL, hb_vm_iMacroListAllocated; + /* Request for some action - stop processing of opcodes */ static USHORT s_uiActionRequest; @@ -282,6 +284,8 @@ void hb_vmInit( BOOL bStartMainProc ) s_lRecoverBase = 0; s_uiActionRequest = 0; + hb_vm_aiMacroListParameters = (int *) hb_xgrab( sizeof( int ) * ( hb_vm_iMacroListAllocated = 16 ) ); + hb_stack.pItems = NULL; /* keep this here as it is used by fm.c */ hb_stack.Return.type = HB_IT_NIL; @@ -383,6 +387,8 @@ void hb_vmQuit( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_vmQuit()")); + hb_xfree( (void*) hb_vm_aiMacroListParameters ); + s_uiActionRequest = 0; /* EXIT procedures should be processed */ hb_vmDoExitFunctions(); /* process defined EXIT functions */ @@ -589,18 +595,18 @@ void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) /* Execution */ case HB_P_DO: - hb_vmDo( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + hb_vmDo( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + hb_vm_aiMacroListParameters[ hb_vm_iFunCalls - 1 ] ); w += 3; break; case HB_P_DOSHORT: - hb_vmDo( pCode[ w + 1 ] ); + hb_vmDo( pCode[ w + 1 ] + hb_vm_aiMacroListParameters[ hb_vm_iFunCalls - 1 ] ); w += 2; break; case HB_P_FUNCTION: hb_itemClear( &hb_stack.Return ); - hb_vmDo( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + hb_vmDo( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + hb_vm_aiMacroListParameters[ hb_vm_iFunCalls - 1 ] ); hb_itemCopy( hb_stackTopItem(), &hb_stack.Return ); hb_stackPush(); w += 3; @@ -608,7 +614,7 @@ void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_FUNCTIONSHORT: hb_itemClear( &hb_stack.Return ); - hb_vmDo( pCode[ w + 1 ] ); + hb_vmDo( pCode[ w + 1 ] + hb_vm_aiMacroListParameters[ hb_vm_iFunCalls - 1 ] ); hb_itemCopy( hb_stackTopItem(), &hb_stack.Return ); hb_stackPush(); w += 2; @@ -616,7 +622,7 @@ void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_SEND: hb_itemClear( &hb_stack.Return ); - hb_vmSend( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + hb_vmSend( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 + hb_vm_aiMacroListParameters[ hb_vm_iFunCalls - 1 ] ) ); hb_itemCopy( hb_stackTopItem(), &hb_stack.Return ); hb_stackPush(); w += 3; @@ -624,7 +630,7 @@ void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_SENDSHORT: hb_itemClear( &hb_stack.Return ); - hb_vmSend( pCode[ w + 1 ] ); + hb_vmSend( pCode[ w + 1 ] + hb_vm_aiMacroListParameters[ hb_vm_iFunCalls - 1 ] ); hb_itemCopy( hb_stackTopItem(), &hb_stack.Return ); hb_stackPush(); w += 2; @@ -1018,11 +1024,23 @@ void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_PUSHSYM: + if( hb_vm_iFunCalls > hb_vm_iMacroListAllocated ) + { + hb_vm_aiMacroListParameters = (int *) hb_xrealloc( (void*) hb_vm_aiMacroListParameters, sizeof( int ) * ( hb_vm_iMacroListAllocated += 16 ) ); + } + hb_vm_aiMacroListParameters[ hb_vm_iFunCalls++ ] = 0; + hb_vmPushSymbol( pSymbols + ( USHORT ) ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ) ); w += 3; break; case HB_P_PUSHSYMNEAR: + if( hb_vm_iFunCalls > hb_vm_iMacroListAllocated ) + { + hb_vm_aiMacroListParameters = (int *) hb_xrealloc( (void*) hb_vm_aiMacroListParameters, sizeof( int ) * ( hb_vm_iMacroListAllocated += 16 ) ); + } + hb_vm_aiMacroListParameters[ hb_vm_iFunCalls++ ] = 0; + hb_vmPushSymbol( pSymbols + ( USHORT ) pCode[ w + 1 ] ); w += 2; break; @@ -1226,6 +1244,12 @@ void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_MACROSYMBOL: /* compile into a symbol name (used in function calls) */ + if( hb_vm_iFunCalls > hb_vm_iMacroListAllocated ) + { + hb_vm_aiMacroListParameters = (int *) hb_xrealloc( (void*) hb_vm_aiMacroListParameters, sizeof( int ) * ( hb_vm_iMacroListAllocated += 16 ) ); + } + hb_vm_aiMacroListParameters[ hb_vm_iFunCalls++ ] = 0; + hb_macroPushSymbol( hb_stackItemFromTop( -1 ) ); w++; break; @@ -2835,6 +2859,8 @@ void hb_vmDo( USHORT uiParams ) HB_TRACE(HB_TR_DEBUG, ("hb_vmDo(%hu)", uiParams)); + hb_vm_aiMacroListParameters[ --hb_vm_iFunCalls ] = 0; + hb_inkeyPoll(); /* Poll the console keyboard */ pItem = hb_stackNewFrame( &sStackState, uiParams ); @@ -2949,6 +2975,8 @@ void hb_vmSend( USHORT uiParams ) HB_TRACE(HB_TR_DEBUG, ("hb_vmSend(%hu)", uiParams)); + hb_vm_aiMacroListParameters[ --hb_vm_iFunCalls ] = 0; + pItem = hb_stackNewFrame( &sStackState, uiParams ); /* procedure name */ pSym = pItem->item.asSymbol.value; pSelf = hb_stackSelfItem(); /* NIL, OBJECT or BLOCK */ diff --git a/harbour/source/vm/macro.c b/harbour/source/vm/macro.c index 913cfbf106..5a97862c1a 100644 --- a/harbour/source/vm/macro.c +++ b/harbour/source/vm/macro.c @@ -423,6 +423,8 @@ char * hb_macroTextSubst( char * szString, ULONG *pulStringLen ) */ void hb_macroGetValue( HB_ITEM_PTR pItem ) { + extern int *hb_vm_aiMacroListParameters, hb_vm_iFunCalls; + HB_TRACE(HB_TR_DEBUG, ("hb_macroGetValue(%p)", pItem)); if( hb_macroCheckParam( pItem ) ) @@ -431,12 +433,16 @@ void hb_macroGetValue( HB_ITEM_PTR pItem ) int iStatus; char * szString = pItem->item.asString.value; - struMacro.Flags = HB_MACRO_GEN_PUSH; - struMacro.bShortCuts = hb_comp_bShortCuts; - struMacro.uiNameLen = HB_SYMBOL_NAME_LEN; - struMacro.status = HB_MACRO_CONT; + struMacro.Flags = HB_MACRO_GEN_PUSH; + struMacro.bShortCuts = hb_comp_bShortCuts; + struMacro.uiNameLen = HB_SYMBOL_NAME_LEN; + struMacro.status = HB_MACRO_CONT; + struMacro.iListElements = 0; + iStatus = hb_macroParse( &struMacro, szString ); + hb_vm_aiMacroListParameters[ hb_vm_iFunCalls - 1 ] = struMacro.iListElements; + hb_stackPop(); /* remove compiled string */ if( iStatus == HB_MACRO_OK && ( struMacro.status & HB_MACRO_CONT ) ) {