ChangeLog 20000115-15:15
This commit is contained in:
@@ -1,3 +1,56 @@
|
||||
20000115-15:15 GMT+1 Ryszard Glab <rglab@imid.med.pl>
|
||||
|
||||
*include/pcode.h
|
||||
* added new pcodes:
|
||||
HB_P_PUSHALIASEDVAR
|
||||
HB_P_POPALIASEDVAR
|
||||
HB_P_MPUSHALIASEDVAR
|
||||
HB_P_MPOPALIASEDVAR
|
||||
|
||||
NOTE: All sources HAVE TO be recompiled!!!
|
||||
|
||||
*include/macro.h
|
||||
* added new constant:
|
||||
HB_MACRO_GEN_PUSH 4 /* generate PUSH pcodes */
|
||||
HB_MACRO_GEN_POP 8 /* generate POP pcodes */
|
||||
HB_MACRO_GEN_ALIASED 16 /* force aliased variable */
|
||||
|
||||
*include/extend.h
|
||||
* added declaration of
|
||||
hb_macroPopAliasedValue
|
||||
hb_macroPushAliasedValue
|
||||
|
||||
*source/macro/macro.c
|
||||
*source/compiler/harbour.c
|
||||
* corrected handling of aliased variables in case when an alias
|
||||
is determined at runtime (the field variable was assumed previously
|
||||
but now the virtual machine checks the value of passed alias and
|
||||
used either a memvar or a field)
|
||||
for example:
|
||||
alias := "M"
|
||||
? ( alias )->var
|
||||
The value of memvar named "var" should be printed
|
||||
|
||||
*include/hbexpr.c
|
||||
*source/compiler/expropt.c
|
||||
* finished support for aliased macro expressions
|
||||
|
||||
*source/macro/macro.c
|
||||
* finished support for aliased macro expressions
|
||||
|
||||
*source/vm/hvm.c
|
||||
*source/compiler/genc.c
|
||||
*source/compiler/genhrb.c
|
||||
*source/compiler/genjava.c
|
||||
* added support for new pcodes:
|
||||
HB_P_PUSHALIASEDVAR
|
||||
HB_P_POPALIASEDVAR
|
||||
HB_P_MPUSHALIASEDVAR
|
||||
HB_P_MPOPALIASEDVAR
|
||||
|
||||
*source/compiler/harbour.y
|
||||
* removed 'macro support' from the TODO list :)
|
||||
|
||||
2000-01-14 12:20 GMT-5 David G. Holm <dholm@ sd-llc.com>
|
||||
|
||||
* ngdoc/ft_helpc.prg
|
||||
|
||||
@@ -463,6 +463,8 @@ extern HB_MACRO_PTR hb_macroCompile( char * );
|
||||
extern void hb_macroDelete( HB_MACRO_PTR );
|
||||
extern char * hb_macroTextSubst( char *, ULONG * );
|
||||
extern BOOL hb_macroIsIdent( char * );
|
||||
extern void hb_macroPopAliasedValue( HB_ITEM_PTR, HB_ITEM_PTR );
|
||||
extern void hb_macroPushAliasedValue( HB_ITEM_PTR, HB_ITEM_PTR );
|
||||
|
||||
/* misc */
|
||||
extern char * hb_version( USHORT uiMode );
|
||||
|
||||
@@ -2634,7 +2634,12 @@ static HB_EXPR_FUNC( hb_compExprUseAliasVar )
|
||||
|
||||
case HB_EA_DELETE:
|
||||
hb_compExprDelete( pSelf->value.asAlias.pAlias );
|
||||
/* NOTE: variable name is not released now */
|
||||
#ifdef HB_MACRO_SUPPORT
|
||||
if( pSelf->value.asAlias.pVar )
|
||||
hb_compExprDelete( pSelf->value.asAlias.pVar );
|
||||
#else
|
||||
/* NOTE: variable name is not released now */
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
return pSelf;
|
||||
@@ -2728,7 +2733,11 @@ static HB_EXPR_FUNC( hb_compExprUseAlias )
|
||||
case HB_EA_POP_PCODE:
|
||||
case HB_EA_PUSH_POP:
|
||||
case HB_EA_STATEMENT:
|
||||
break;
|
||||
case HB_EA_DELETE:
|
||||
#ifdef HB_MACRO_SUPPORT
|
||||
hb_xfree( pSelf->value.asSymbol );
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
return pSelf;
|
||||
@@ -2803,11 +2812,35 @@ static HB_EXPR_FUNC( hb_compExprUseVariable )
|
||||
case HB_EA_LVALUE:
|
||||
break;
|
||||
case HB_EA_PUSH_PCODE:
|
||||
hb_compGenPushVar( pSelf->value.asSymbol );
|
||||
break;
|
||||
case HB_EA_POP_PCODE:
|
||||
hb_compGenPopVar( pSelf->value.asSymbol );
|
||||
break;
|
||||
|
||||
#ifdef HB_MACRO_SUPPORT
|
||||
/* NOTE: When the following syntax is used:
|
||||
* ( any_expr )->&var2
|
||||
* then macro compiler is compiling the right side of alias
|
||||
* operator only (if 'any_expr' is not a string) - an alias value
|
||||
* is placed on the eval stack before macro compilation.
|
||||
* The HB_MACRO_GEN_ALIASED flag is used to signal that we have to
|
||||
* genearate alias aware pcode even if we known a variable part only.
|
||||
*/
|
||||
if( HB_MACRO_DATA->Flags & HB_MACRO_GEN_ALIASED )
|
||||
hb_compGenPushAliasedVar( pSelf->value.asSymbol, FALSE, NULL, 0 );
|
||||
else
|
||||
hb_compGenPushVar( pSelf->value.asSymbol );
|
||||
#else
|
||||
hb_compGenPushVar( pSelf->value.asSymbol );
|
||||
#endif
|
||||
break;
|
||||
|
||||
case HB_EA_POP_PCODE:
|
||||
#ifdef HB_MACRO_SUPPORT
|
||||
if( HB_MACRO_DATA->Flags & HB_MACRO_GEN_ALIASED )
|
||||
hb_compGenPopAliasedVar( pSelf->value.asSymbol, FALSE, NULL, 0 );
|
||||
else
|
||||
hb_compGenPopVar( pSelf->value.asSymbol );
|
||||
#else
|
||||
hb_compGenPopVar( pSelf->value.asSymbol );
|
||||
#endif
|
||||
break;
|
||||
|
||||
case HB_EA_PUSH_POP:
|
||||
case HB_EA_STATEMENT:
|
||||
|
||||
@@ -59,6 +59,9 @@
|
||||
#define HB_MACRO_OK 0 /* macro compiled successfully */
|
||||
#define HB_MACRO_FAILURE 1 /* syntax error */
|
||||
#define HB_MACRO_TOO_COMPLEX 2 /* compiled expression is too complex */
|
||||
#define HB_MACRO_GEN_PUSH 4 /* generate PUSH pcodes */
|
||||
#define HB_MACRO_GEN_POP 8 /* generate POP pcodes */
|
||||
#define HB_MACRO_GEN_ALIASED 16 /* force aliased variable */
|
||||
|
||||
|
||||
/* Global functions
|
||||
|
||||
@@ -81,9 +81,11 @@ typedef enum
|
||||
/* start: pcodes generated by the macro compiler - the symbol address is used */
|
||||
HB_P_MMESSAGE,
|
||||
HB_P_MPOPALIASEDFIELD,
|
||||
HB_P_MPOPALIASEDVAR,
|
||||
HB_P_MPOPFIELD,
|
||||
HB_P_MPOPMEMVAR,
|
||||
HB_P_MPUSHALIASEDFIELD,
|
||||
HB_P_MPUSHALIASEDVAR,
|
||||
HB_P_MPUSHBLOCK,
|
||||
HB_P_MPUSHFIELD,
|
||||
HB_P_MPUSHMEMVAR,
|
||||
@@ -102,6 +104,7 @@ typedef enum
|
||||
HB_P_POP, /* removes the latest value from the stack */
|
||||
HB_P_POPALIAS, /* pops the item from the eval stack and selects the current workarea */
|
||||
HB_P_POPALIASEDFIELD, /* pops aliased field */
|
||||
HB_P_POPALIASEDVAR, /* pops aliased variable (either a field or a memvar) */
|
||||
HB_P_POPFIELD, /* pops unaliased field */
|
||||
HB_P_POPLOCAL, /* pops the contains of the virtual machine stack onto a local variable */
|
||||
HB_P_POPMEMVAR, /* pops the contains of a memvar variable to the virtual machine stack */
|
||||
@@ -110,6 +113,7 @@ typedef enum
|
||||
HB_P_POWER, /* calculates the power of the two values on the stack, removing them and leaving there the result */
|
||||
HB_P_PUSHALIAS, /* saves the current workarea number on the eval stack */
|
||||
HB_P_PUSHALIASEDFIELD, /* pushes aliased field */
|
||||
HB_P_PUSHALIASEDVAR, /* pushes aliased variable (either a field or a memvar) */
|
||||
HB_P_PUSHBLOCK, /* start of a codeblock definition */
|
||||
HB_P_PUSHFIELD, /* pushes unaliased field */
|
||||
HB_P_PUSHINT, /* places an integer number on the virtual machine stack */
|
||||
|
||||
@@ -554,6 +554,21 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_P_POPALIASEDVAR:
|
||||
{
|
||||
USHORT wFixPos;
|
||||
|
||||
wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256;
|
||||
wFixPos = hb_compSymbolFixPos( wVar );
|
||||
fprintf( yyc, "\tHB_P_POPALIASEDVAR, %i, %i,",
|
||||
HB_LOBYTE( wFixPos ),
|
||||
HB_HIBYTE( wFixPos ) );
|
||||
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %s */", hb_compSymbolGetPos( wVar )->szName );
|
||||
fprintf( yyc, "\n" );
|
||||
lPCodePos += 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_P_POPFIELD:
|
||||
{
|
||||
USHORT wFixPos;
|
||||
@@ -682,6 +697,22 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_P_PUSHALIASEDVAR:
|
||||
{
|
||||
USHORT wFixPos;
|
||||
|
||||
wVar = pFunc->pCode[ lPCodePos + 1 ] +
|
||||
pFunc->pCode[ lPCodePos + 2 ] * 256;
|
||||
wFixPos = hb_compSymbolFixPos( wVar );
|
||||
fprintf( yyc, "\tHB_P_PUSHALIASEDVAR, %i, %i,",
|
||||
HB_LOBYTE( wFixPos ),
|
||||
HB_HIBYTE( wFixPos ) );
|
||||
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %s */", hb_compSymbolGetPos( wVar )->szName );
|
||||
fprintf( yyc, "\n" );
|
||||
lPCodePos += 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_P_PUSHBLOCK:
|
||||
++iNestedCodeblock;
|
||||
|
||||
|
||||
@@ -275,6 +275,8 @@ void hb_compGenPortObj( PHB_FNAME pFileName )
|
||||
case HB_P_PUSHFIELD:
|
||||
case HB_P_POPALIASEDFIELD:
|
||||
case HB_P_PUSHALIASEDFIELD:
|
||||
case HB_P_POPALIASEDVAR:
|
||||
case HB_P_PUSHALIASEDVAR:
|
||||
fputc( pFunc->pCode[ lPCodePos ], yyc );
|
||||
wVar = hb_compSymbolFixPos( pFunc->pCode[ lPCodePos + 1 ] + 256 * pFunc->pCode[ lPCodePos + 2 ] );
|
||||
fputc( HB_LOBYTE( wVar ), yyc );
|
||||
|
||||
@@ -297,6 +297,8 @@ void hb_compGenJava( PHB_FNAME pFileName )
|
||||
case HB_P_PUSHFIELD:
|
||||
case HB_P_POPALIASEDFIELD:
|
||||
case HB_P_PUSHALIASEDFIELD:
|
||||
case HB_P_POPALIASEDVAR:
|
||||
case HB_P_PUSHALIASEDVAR:
|
||||
hb_fputc( pFunc->pCode[ lPCodePos ], yyc );
|
||||
wVar = hb_compSymbolFixPos( pFunc->pCode[ lPCodePos + 1 ] + 256 * pFunc->pCode[ lPCodePos + 2 ] );
|
||||
hb_fputc( HB_LOBYTE( wVar ), yyc );
|
||||
|
||||
@@ -1491,8 +1491,11 @@ void hb_compGenPopAliasedVar( char * szVarName,
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Alias is already placed on stack */
|
||||
hb_compGenVarPCode( HB_P_POPALIASEDFIELD, szVarName );
|
||||
/* Alias is already placed on stack
|
||||
* NOTE: An alias will be determined at runtime then we cannot decide
|
||||
* here if passed name is either a field or a memvar
|
||||
*/
|
||||
hb_compGenVarPCode( HB_P_POPALIASEDVAR, szVarName );
|
||||
}
|
||||
|
||||
/* generates the pcode to push a nonaliased variable value to the virtual
|
||||
@@ -1718,8 +1721,11 @@ void hb_compGenPushAliasedVar( char * szVarName,
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Alias is already placed on stack */
|
||||
hb_compGenVarPCode( HB_P_PUSHALIASEDFIELD, szVarName );
|
||||
/* Alias is already placed on stack
|
||||
* NOTE: An alias will be determined at runtime then we cannot decide
|
||||
* here if passed name is either a field or a memvar
|
||||
*/
|
||||
hb_compGenVarPCode( HB_P_PUSHALIASEDVAR, szVarName );
|
||||
}
|
||||
|
||||
void hb_compGenPushLogical( int iTrueFalse ) /* pushes a logical value on the virtual machine stack */
|
||||
|
||||
@@ -36,9 +36,8 @@
|
||||
|
||||
/* TODO list
|
||||
* 1) jumps longer then 2^15 bytes
|
||||
* 2) macro support
|
||||
* 3) Change the pcode generated by ::cVar from Self:cVar to QSELF():cVar
|
||||
* 4) Support this syntax: nPtr := @Hello()
|
||||
* 2) Change the pcode generated by ::cVar from Self:cVar to QSELF():cVar
|
||||
* 3) Support this syntax: nPtr := @Hello()
|
||||
*/
|
||||
|
||||
#include <malloc.h>
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
static BOOL hb_comp_bShortCuts = TRUE; /* .and. & .or. expressions shortcuts */
|
||||
static BOOL hb_comp_bUseName10 = FALSE; /* names limited to 10 characters */
|
||||
|
||||
static void hb_macroUseAliased( HB_ITEM_PTR, HB_ITEM_PTR, int );
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
||||
/* Compile passed string into a pcode buffer
|
||||
@@ -285,7 +287,7 @@ char * hb_macroTextSubst( char * szString, ULONG *pulStringLen )
|
||||
/* number of characters left on the right side of a variable name */
|
||||
ulCharsLeft = ulResStrLen - ( pHead - szResult );
|
||||
|
||||
/* NOTE:
|
||||
/* NOTE:
|
||||
* if a replacement string is shorter then the variable
|
||||
* name then we don't have to reallocate the result buffer:
|
||||
* 'ulResStrLen' stores the current length of a string in the buffer
|
||||
@@ -341,6 +343,7 @@ char * hb_macroTextSubst( char * szString, ULONG *pulStringLen )
|
||||
* This will be called when macro variable or macro expression is
|
||||
* placed on the right side of the assignment or when it is used as
|
||||
* a parameter.
|
||||
* PUSH operation
|
||||
*/
|
||||
void hb_macroGetValue( HB_ITEM_PTR pItem )
|
||||
{
|
||||
@@ -354,7 +357,7 @@ void hb_macroGetValue( HB_ITEM_PTR pItem )
|
||||
|
||||
struMacro.bShortCuts = hb_comp_bShortCuts;
|
||||
struMacro.bName10 = hb_comp_bUseName10;
|
||||
iStatus = hb_macroParse( &struMacro, szString, HB_P_MACROPUSH );
|
||||
iStatus = hb_macroParse( &struMacro, szString, HB_MACRO_GEN_PUSH );
|
||||
|
||||
hb_stackPop(); /* remove compiled string */
|
||||
if( iStatus == HB_MACRO_OK && struMacro.status == HB_MACRO_OK )
|
||||
@@ -370,6 +373,7 @@ void hb_macroGetValue( HB_ITEM_PTR pItem )
|
||||
/* NOTE:
|
||||
* This will be called when macro variable or macro expression is
|
||||
* placed on the left side of the assignment
|
||||
* POP operation
|
||||
*/
|
||||
void hb_macroSetValue( HB_ITEM_PTR pItem )
|
||||
{
|
||||
@@ -383,7 +387,7 @@ void hb_macroSetValue( HB_ITEM_PTR pItem )
|
||||
|
||||
struMacro.bShortCuts = hb_comp_bShortCuts;
|
||||
struMacro.bName10 = hb_comp_bUseName10;
|
||||
iStatus = hb_macroParse( &struMacro, szString, HB_P_MACROPOP );
|
||||
iStatus = hb_macroParse( &struMacro, szString, HB_MACRO_GEN_POP );
|
||||
|
||||
hb_stackPop(); /* remove compiled string */
|
||||
if( iStatus == HB_MACRO_OK && struMacro.status == HB_MACRO_OK )
|
||||
@@ -396,6 +400,102 @@ void hb_macroSetValue( HB_ITEM_PTR pItem )
|
||||
}
|
||||
}
|
||||
|
||||
/* Compiles and run an aliased macro expression - generated pcode
|
||||
* pops a value from the stack
|
||||
* &alias->var := any
|
||||
* alias->&var := any
|
||||
*/
|
||||
void hb_macroPopAliasedValue( HB_ITEM_PTR pAlias, HB_ITEM_PTR pVar )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_macroPopAliasedValue(%p, %p)", pAlias, pVar));
|
||||
|
||||
hb_macroUseAliased( pAlias, pVar, HB_MACRO_GEN_POP );
|
||||
}
|
||||
|
||||
/* Compiles and run an aliased macro expression - generated pcode
|
||||
* pushes a value onto the stack
|
||||
* any := &alias->var
|
||||
* any := alias->&var
|
||||
*/
|
||||
void hb_macroPushAliasedValue( HB_ITEM_PTR pAlias, HB_ITEM_PTR pVar )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_macroPushAliasedValue(%p, %p)", pAlias, pVar));
|
||||
|
||||
hb_macroUseAliased( pAlias, pVar, HB_MACRO_GEN_PUSH );
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile and run:
|
||||
* &alias->var or
|
||||
* alias->&var
|
||||
* NOTE:
|
||||
* Clipper implements these two cases as: &( alias +'->' + variable )
|
||||
* This causes some non expected behaviours, for example:
|
||||
* A :="M + M"
|
||||
* ? &A->&A
|
||||
* is the same as:
|
||||
* &( "M + M->M + M" )
|
||||
* instead of
|
||||
* &( "M + M" ) -> &( "M + M" )
|
||||
*/
|
||||
static void hb_macroUseAliased( HB_ITEM_PTR pAlias, HB_ITEM_PTR pVar, int iFlag )
|
||||
{
|
||||
if( IS_STRING( pAlias ) && IS_STRING( pVar ) )
|
||||
{
|
||||
/* grab memory for "alias->var"
|
||||
*/
|
||||
char * szString = ( char * ) hb_xgrab( pAlias->item.asString.length + pVar->item.asString.length + 3 );
|
||||
HB_MACRO struMacro;
|
||||
int iStatus;
|
||||
|
||||
memcpy( szString, pAlias->item.asString.value, pAlias->item.asString.length );
|
||||
szString[ pAlias->item.asString.length ] = '-';
|
||||
szString[ pAlias->item.asString.length + 1 ] = '>';
|
||||
memcpy( szString + pAlias->item.asString.length + 2, pVar->item.asString.value, pVar->item.asString.length );
|
||||
szString[ pAlias->item.asString.length + 2 + pVar->item.asString.length ] = '\0';
|
||||
|
||||
struMacro.bShortCuts = hb_comp_bShortCuts;
|
||||
struMacro.bName10 = hb_comp_bUseName10;
|
||||
iStatus = hb_macroParse( &struMacro, szString, iFlag );
|
||||
hb_xfree( szString );
|
||||
struMacro.string = NULL;
|
||||
|
||||
hb_stackPop(); /* remove compiled variable name */
|
||||
hb_stackPop(); /* remove compiled alias */
|
||||
|
||||
if( iStatus == HB_MACRO_OK && struMacro.status == HB_MACRO_OK )
|
||||
{
|
||||
hb_macroRun( &struMacro );
|
||||
hb_macroDelete( &struMacro );
|
||||
}
|
||||
else
|
||||
hb_macroSyntaxError( &struMacro );
|
||||
}
|
||||
else if( hb_macroCheckParam( pVar ) )
|
||||
{
|
||||
/* only right side of alias operator is a string - macro-compile
|
||||
* this part only
|
||||
*/
|
||||
HB_MACRO struMacro;
|
||||
int iStatus;
|
||||
char * szString = pVar->item.asString.value;
|
||||
|
||||
struMacro.bShortCuts = hb_comp_bShortCuts;
|
||||
struMacro.bName10 = hb_comp_bUseName10;
|
||||
iStatus = hb_macroParse( &struMacro, szString, iFlag | HB_MACRO_GEN_ALIASED );
|
||||
|
||||
hb_stackPop(); /* remove compiled string */
|
||||
|
||||
if( iStatus == HB_MACRO_OK && struMacro.status == HB_MACRO_OK )
|
||||
{
|
||||
hb_macroRun( &struMacro );
|
||||
hb_macroDelete( &struMacro );
|
||||
}
|
||||
else
|
||||
hb_macroSyntaxError( &struMacro );
|
||||
}
|
||||
}
|
||||
|
||||
/* compile a string and return a pcode to push a value of expression
|
||||
* NOTE: it can be called to implement an index key evaluation
|
||||
* use hb_macroRun() to evaluate a compiled pcode
|
||||
@@ -711,8 +811,11 @@ void hb_compGenPopAliasedVar( char * szVarName,
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Alias is already placed on stack */
|
||||
hb_compMemvarGenPCode( HB_P_MPOPALIASEDFIELD, szVarName, HB_MACRO_PARAM );
|
||||
/* Alias is already placed on stack
|
||||
* NOTE: An alias will be determined at runtime then we cannot decide
|
||||
* here if passed name is either a field or a memvar
|
||||
*/
|
||||
hb_compMemvarGenPCode( HB_P_MPOPALIASEDVAR, szVarName, HB_MACRO_PARAM );
|
||||
}
|
||||
|
||||
/* generates the pcode to push a nonaliased variable value to the virtual
|
||||
@@ -805,8 +908,11 @@ void hb_compGenPushAliasedVar( char * szVarName,
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Alias is already placed on stack */
|
||||
hb_compMemvarGenPCode( HB_P_MPUSHALIASEDFIELD, szVarName, HB_MACRO_PARAM );
|
||||
/* Alias is already placed on stack
|
||||
* NOTE: An alias will be determined at runtime then we cannot decide
|
||||
* here if passed name is either a field or a memvar
|
||||
*/
|
||||
hb_compMemvarGenPCode( HB_P_MPUSHALIASEDVAR, szVarName, HB_MACRO_PARAM );
|
||||
}
|
||||
|
||||
/* pushes a logical value on the virtual machine stack , */
|
||||
|
||||
@@ -185,13 +185,13 @@ int yylex( YYSTYPE *, HB_MACRO_PTR );
|
||||
|
||||
%%
|
||||
|
||||
Main : Expression '\n' { if( HB_MACRO_DATA->Flags & HB_P_MACROPUSH )
|
||||
Main : Expression '\n' { 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 { if( HB_MACRO_DATA->Flags & HB_P_MACROPUSH )
|
||||
| Expression { 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 );
|
||||
|
||||
@@ -129,6 +129,7 @@ static void hb_vmDebuggerEndProc( void ); /* notifies the debugger for an
|
||||
/* Push */
|
||||
static void hb_vmPushAlias( void ); /* pushes the current workarea number */
|
||||
static void hb_vmPushAliasedField( PHB_SYMB ); /* pushes an aliased field on the eval stack */
|
||||
static void hb_vmPushAliasedVar( PHB_SYMB ); /* pushes an aliased variable on the eval stack */
|
||||
static void hb_vmPushBlock( BYTE * pCode, PHB_SYMB pSymbols ); /* creates a codeblock */
|
||||
static void hb_vmPushMacroBlock( BYTE * pCode, PHB_SYMB pSymbols ); /* creates a macro-compiled codeblock */
|
||||
static void hb_vmPushLocal( SHORT iLocal ); /* pushes the containts of a local onto the stack */
|
||||
@@ -146,6 +147,7 @@ static double hb_vmPopNumber( void ); /* pops the stack latest value
|
||||
static double hb_vmPopDouble( int * ); /* pops the stack latest value and returns its double numeric format value */
|
||||
static void hb_vmPopAlias( void ); /* pops the workarea number form the eval stack */
|
||||
static void hb_vmPopAliasedField( PHB_SYMB ); /* pops an aliased field from the eval stack*/
|
||||
static void hb_vmPopAliasedVar( PHB_SYMB ); /* pops an aliased variable from the eval stack*/
|
||||
static void hb_vmPopLocal( SHORT iLocal ); /* pops the stack latest value onto a local */
|
||||
static void hb_vmPopStatic( USHORT uiStatic ); /* pops the stack latest value onto a static */
|
||||
|
||||
@@ -777,6 +779,12 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols )
|
||||
w += 3;
|
||||
break;
|
||||
|
||||
case HB_P_PUSHALIASEDVAR:
|
||||
uiParams = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 );
|
||||
hb_vmPushAliasedVar( pSymbols + uiParams );
|
||||
w += 3;
|
||||
break;
|
||||
|
||||
case HB_P_PUSHFIELD:
|
||||
/* It pushes the current value of the given field onto the eval stack
|
||||
*/
|
||||
@@ -858,6 +866,12 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols )
|
||||
w += 3;
|
||||
break;
|
||||
|
||||
case HB_P_POPALIASEDVAR:
|
||||
uiParams = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 );
|
||||
hb_vmPopAliasedVar( pSymbols + uiParams );
|
||||
w += 3;
|
||||
break;
|
||||
|
||||
case HB_P_POPFIELD:
|
||||
/* Pops a value from the eval stack and uses it to set
|
||||
* a new value of the given field
|
||||
@@ -916,9 +930,11 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols )
|
||||
break;
|
||||
|
||||
case HB_P_MACROPOPALIASED:
|
||||
/* compile and run - pop a field value from the stack */
|
||||
/* compile and run - pop an aliased variable from the stack */
|
||||
hb_macroPopAliasedValue( hb_stack.pPos - 2, hb_stack.pPos - 1 );
|
||||
w++;
|
||||
break;
|
||||
|
||||
case HB_P_MACROPUSH:
|
||||
/* compile and run - leave the result on the stack */
|
||||
/* the topmost element on the stack contains a macro
|
||||
@@ -929,7 +945,8 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols )
|
||||
break;
|
||||
|
||||
case HB_P_MACROPUSHALIASED:
|
||||
/* compile and run - leave the field value on the stack */
|
||||
/* compile and run - leave an aliased variable on the stack */
|
||||
hb_macroPushAliasedValue( hb_stack.pPos - 2, hb_stack.pPos - 1 );
|
||||
w++;
|
||||
break;
|
||||
|
||||
@@ -940,7 +957,7 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols )
|
||||
break;
|
||||
|
||||
case HB_P_MACROTEXT:
|
||||
/* macro text substitution
|
||||
/* macro text substitution
|
||||
* "text ¯o.other text"
|
||||
*/
|
||||
hb_macroTextValue( hb_stack.pPos - 1 );
|
||||
@@ -965,6 +982,14 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols )
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_P_MPOPALIASEDVAR:
|
||||
{
|
||||
HB_DYNS_PTR *pDynSym = ( HB_DYNS_PTR *) ( pCode + w + 1 );
|
||||
hb_vmPopAliasedVar( ( *pDynSym )->pSymbol );
|
||||
w += sizeof( HB_DYNS_PTR ) + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_P_MPOPFIELD:
|
||||
{
|
||||
HB_DYNS_PTR *pDynSym = ( HB_DYNS_PTR *) ( pCode + w + 1 );
|
||||
@@ -998,6 +1023,14 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols )
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_P_MPUSHALIASEDVAR:
|
||||
{
|
||||
HB_DYNS_PTR *pDynSym = ( HB_DYNS_PTR *) ( pCode + w + 1 );
|
||||
hb_vmPushAliasedVar( ( *pDynSym )->pSymbol );
|
||||
w += sizeof( HB_DYNS_PTR ) + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_P_MPUSHBLOCK:
|
||||
{
|
||||
/*NOTE: the pcode is stored in dynamically allocated memory
|
||||
@@ -2903,6 +2936,56 @@ static void hb_vmPushAliasedField( PHB_SYMB pSym )
|
||||
hb_rddSelectWorkAreaNumber( iCurrArea );
|
||||
}
|
||||
|
||||
/* It pops the last item from the stack to use it to select a workarea
|
||||
* and next pushes the value of either a field or a memvar based on alias value
|
||||
* (for performance reason it replaces alias value with field value)
|
||||
* This is used in the following context:
|
||||
* ( any_alias )->variable
|
||||
*/
|
||||
static void hb_vmPushAliasedVar( PHB_SYMB pSym )
|
||||
{
|
||||
PHB_ITEM pAlias = hb_stack.pPos - 1;
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_vmPushAliasedVar(%p)", pSym));
|
||||
|
||||
if( IS_STRING( pAlias ) )
|
||||
{
|
||||
char * szAlias = hb_strUpper( pAlias->item.asString.value, pAlias->item.asString.length );
|
||||
|
||||
if( szAlias[ 0 ] == 'M' && szAlias[ 1 ] == '\0' )
|
||||
{ /* M->variable */
|
||||
hb_memvarGetValue( pAlias, pSym );
|
||||
}
|
||||
else
|
||||
{
|
||||
int iCmp = strncmp( szAlias, "MEMVAR", 4 );
|
||||
if( iCmp == 0 )
|
||||
iCmp = strncmp( szAlias, "MEMVAR", pAlias->item.asString.length );
|
||||
if( iCmp == 0 )
|
||||
{ /* MEMVAR-> or MEMVA-> or MEMV-> */
|
||||
hb_memvarGetValue( pAlias, pSym );
|
||||
}
|
||||
else
|
||||
{ /* field variable */
|
||||
iCmp = strncmp( szAlias, "FIELD", 4 );
|
||||
if( iCmp == 0 )
|
||||
iCmp = strncmp( szAlias, "FIELD", pAlias->item.asString.length );
|
||||
if( iCmp == 0 )
|
||||
{ /* FIELD-> */
|
||||
hb_rddGetFieldValue( pAlias, pSym );
|
||||
}
|
||||
else
|
||||
{ /* database alias */
|
||||
hb_vmPushAliasedField( pSym );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
hb_vmPushAliasedField( pSym );
|
||||
}
|
||||
|
||||
static void hb_vmPushLocal( SHORT iLocal )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_vmPushLocal(%hd)", iLocal));
|
||||
@@ -3136,7 +3219,7 @@ static void hb_vmPopAlias( void )
|
||||
}
|
||||
|
||||
/* Pops the alias to use it to select a workarea and next pops a value
|
||||
* into given field
|
||||
* into a given field
|
||||
*/
|
||||
static void hb_vmPopAliasedField( PHB_SYMB pSym )
|
||||
{
|
||||
@@ -3153,6 +3236,64 @@ static void hb_vmPopAliasedField( PHB_SYMB pSym )
|
||||
hb_stackPop(); /* field value */
|
||||
}
|
||||
|
||||
/* Pops the alias to use it to select a workarea and next pops a value
|
||||
* into either a field or a memvar based on the alias value
|
||||
* This is used in the following context:
|
||||
* ( any_alias )->variable
|
||||
*/
|
||||
static void hb_vmPopAliasedVar( PHB_SYMB pSym )
|
||||
{
|
||||
HB_ITEM_PTR pAlias = hb_stack.pPos - 1;
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_vmPopAliasedVar(%p)", pSym));
|
||||
|
||||
/* "M", "MEMV" - "MEMVAR" and "FIEL" - "FIELD" are reserved aliases
|
||||
*/
|
||||
if( IS_STRING( pAlias ) )
|
||||
{
|
||||
char * szAlias = pAlias->item.asString.value;
|
||||
|
||||
if( szAlias[ 0 ] == 'M' && szAlias[ 1 ] == '\0' )
|
||||
{ /* M->variable */
|
||||
hb_memvarSetValue( pSym, hb_stack.pPos - 2 );
|
||||
hb_stackPop(); /* alias */
|
||||
hb_stackPop(); /* value */
|
||||
}
|
||||
else
|
||||
{
|
||||
int iCmp = strncmp( szAlias, "MEMVAR", 4 );
|
||||
if( iCmp == 0 )
|
||||
iCmp = strncmp( szAlias, "MEMVAR", pAlias->item.asString.length );
|
||||
if( iCmp == 0 )
|
||||
{ /* MEMVAR-> or MEMVA-> or MEMV-> */
|
||||
hb_memvarSetValue( pSym, hb_stack.pPos - 2 );
|
||||
hb_stackPop(); /* alias */
|
||||
hb_stackPop(); /* value */
|
||||
}
|
||||
else
|
||||
{ /* field variable */
|
||||
iCmp = strncmp( szAlias, "FIELD", 4 );
|
||||
if( iCmp == 0 )
|
||||
iCmp = strncmp( szAlias, "FIELD", pAlias->item.asString.length );
|
||||
if( iCmp == 0 )
|
||||
{ /* FIELD-> */
|
||||
hb_rddPutFieldValue( hb_stack.pPos - 2, pSym );
|
||||
hb_stackPop(); /* alias */
|
||||
hb_stackPop(); /* value */
|
||||
}
|
||||
else
|
||||
{ /* database alias */
|
||||
hb_vmPopAliasedField( pSym );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hb_vmPopAliasedField( pSym );
|
||||
}
|
||||
}
|
||||
|
||||
static void hb_vmPopLocal( SHORT iLocal )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_vmPopLocal(%hd)", iLocal));
|
||||
|
||||
Reference in New Issue
Block a user