ChangeLog 20000115-15:15

This commit is contained in:
Ryszard Glab
2000-01-15 14:02:08 +00:00
parent a6983e1330
commit e579205654
13 changed files with 408 additions and 26 deletions

View File

@@ -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

View File

@@ -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 );

View File

@@ -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:

View File

@@ -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

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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 );

View File

@@ -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 );

View File

@@ -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 */

View File

@@ -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>

View File

@@ -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 , */

View File

@@ -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 );

View File

@@ -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 &macro.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));