ChangeLog 19991117-13:05

This commit is contained in:
Ryszard Glab
1999-11-17 12:23:57 +00:00
parent af16c7e60e
commit 0dd0d8d93f
6 changed files with 267 additions and 434 deletions

View File

@@ -1,3 +1,15 @@
19991117-13:05 GMT+1 Ryszard Glab <rglab@imid.med.pl>
*source/compiler/harbour.y
*source/compiler/harbour.l
*source/compiler/harbour.c
*source/compiler/expropt.c
* corrected support for expression->identifier syntax
* corrected optimization for division operator
*include/compiler.h
* removed declaration no longer needed
19991117-10:51 GMT+1 Victor Szel <info@szelvesz.hu>
* source/compiler/expropt.c
! Fixed the compile-time calculation of numeric operations with results

View File

@@ -219,23 +219,6 @@ extern PCOMSYMBOL KillSymbol( PCOMSYMBOL ); /* releases all memory allocated
#define FUN_USES_LOCAL_PARAMS 16 /* parameters are declared using () */
#define FUN_WITH_RETURN 32 /* there was RETURN statement in previous line */
/* Support for aliased expressions
*/
typedef struct _ALIASID
{
char type;
union
{
int iAlias;
char * szAlias;
} alias;
struct _ALIASID * pPrev;
} ALIASID, *ALIASID_PTR;
#define ALIAS_NUMBER 1
#define ALIAS_NAME 2
#define ALIAS_EVAL 3
typedef struct __EXTERN
{
char * szName;
@@ -260,32 +243,8 @@ typedef struct __ELSEIF
struct __ELSEIF * pNext;
} _ELSEIF, * PELSEIF; /* support structure for else if pcode fixups */
/* Support for parenthesized expressions
/* TODO: clear the functions name space
*/
typedef struct _EXPLIST
{
BYTE * prevPCode; /* pcode buffer used at the start of expression */
ULONG prevSize;
ULONG prevPos;
BYTE * exprPCode; /* pcode buffer for current expression */
ULONG exprSize;
struct _EXPLIST *pPrev; /* previous expression in the list */
struct _EXPLIST *pNext; /* next expression in the list */
} EXPLIST, *EXPLIST_PTR;
/* production related functions */
void AliasAddInt( int );
void AliasAddExp( void );
void AliasAddStr( char * );
void AliasPush( void );
void AliasPop( void );
void AliasSwap( void );
void AliasAdd( ALIASID_PTR );
void AliasRemove( void );
void ExpListPush( void ); /* pushes the new expression on the stack */
void ExpListPop( int ); /* pops previous N expressions */
PFUNCTION hb_compAddFunCall( char * szFuntionName );
void hb_compAddExtern( char * szExternName ); /* defines a new extern name */
void hb_compAddVar( char * szVarName, char cType ); /* add a new param, local, static variable to a function definition or a public or private */
@@ -334,6 +293,8 @@ void hb_compGenPushLong( long lNumber ); /* Pushes a long number on the
void hb_compGenPushNil( void ); /* Pushes nil on the virtual machine stack */
void hb_compGenPushString( char * szText, ULONG ulLen ); /* Pushes a string on the virtual machine stack */
void hb_compPushSymbol( char * szSymbolName, int iIsFunction ); /* Pushes a symbol on to the Virtual machine stack */
void hb_compGenPushAliasedVar( char *, BOOL, char *, long );
void hb_compGenPopAliasedVar( char *, BOOL, char *, long );
/* Codeblocks */
void hb_compCodeBlockStart( void ); /* starts a codeblock creation */

View File

@@ -1755,16 +1755,20 @@ static HB_EXPR_FUNC( hb_compExprUseList )
ULONG ulCount;
ulCount = hb_compExprListReduce( pSelf );
/*
if( ulCount == 1 && pSelf->value.asList.pExprList->ExprType <= HB_ET_VARIABLE )
{
*/
/* replace the list with a simple expression
*/
/*
HB_EXPR_PTR pExpr = pSelf;
pSelf = pSelf->value.asList.pExprList;
pExpr->value.asList.pExprList = NULL;
hb_compExprDelete( pExpr );
}
*/
}
break;
@@ -1774,7 +1778,12 @@ static HB_EXPR_FUNC( hb_compExprUseList )
case HB_EA_LVALUE:
if( hb_compExprListLen( pSelf ) == 1 )
{
/* For example:
* ( a ) := 4
*/
hb_compErrorLValue( pSelf->value.asList.pExprList );
}
else
hb_compErrorLValue( pSelf );
break;
@@ -2082,12 +2091,114 @@ static HB_EXPR_FUNC( hb_compExprUseAliasVar )
case HB_EA_ARRAY_AT:
case HB_EA_ARRAY_INDEX:
case HB_EA_LVALUE:
break;
case HB_EA_PUSH_PCODE:
{
HB_EXPR_PTR pAlias = pSelf->value.asAlias.pAlias;
BOOL bReduced = FALSE;
if( pAlias->ExprType == HB_ET_LIST )
{
pSelf->value.asAlias.pAlias = HB_EXPR_USE( pSelf->value.asAlias.pAlias, HB_EA_REDUCE );
bReduced = TRUE;
}
if( pAlias->ExprType == HB_ET_SYMBOL )
{
/*
* myalias->var
* FIELD->var
* MEMVAR->var
*
* NOTE: TRUE = push also alias
*/
hb_compGenPushAliasedVar( pSelf->value.asAlias.szVarName, TRUE, pAlias->value.asSymbol, 0 );
}
else if( pAlias->ExprType == HB_ET_NUMERIC )
{
/* numeric alias
* 2->var
*
* NOTE: only integer (long) values are allowed
*/
if( pAlias->value.asNum.NumType == HB_ET_LONG )
hb_compGenPushAliasedVar( pSelf->value.asAlias.szVarName, TRUE, NULL, pAlias->value.asNum.lVal );
else
hb_compErrorAlias( pAlias );
}
else if( bReduced )
{
/*
* ( expression )->var
*
* NOTE: FALSE = don't push alias value
*/
HB_EXPR_USE( pAlias, HB_EA_PUSH_PCODE );
hb_compGenPushAliasedVar( pSelf->value.asAlias.szVarName, FALSE, NULL, 0 );
}
else
hb_compErrorAlias( pAlias );
}
break;
case HB_EA_POP_PCODE:
{
HB_EXPR_PTR pAlias = pSelf->value.asAlias.pAlias;
BOOL bReduced = FALSE;
if( pAlias->ExprType == HB_ET_LIST )
{
pSelf->value.asAlias.pAlias = HB_EXPR_USE( pSelf->value.asAlias.pAlias, HB_EA_REDUCE );
bReduced = TRUE;
}
if( pAlias->ExprType == HB_ET_SYMBOL )
{
/*
* myalias->var
* FIELD->var
* MEMVAR->var
*/
hb_compGenPopAliasedVar( pSelf->value.asAlias.szVarName, TRUE, pAlias->value.asSymbol, 0 );
}
else if( pAlias->ExprType == HB_ET_NUMERIC )
{
/* numeric alias
* 2->var
*
* NOTE: only integer (long) values are allowed
*/
if( pAlias->value.asNum.NumType == HB_ET_LONG )
hb_compGenPopAliasedVar( pSelf->value.asAlias.szVarName, TRUE, NULL, pAlias->value.asNum.lVal );
else
hb_compErrorAlias( pAlias );
}
else if( bReduced )
{
/*
* ( expression )->var
*
* NOTE: FALSE = don't push alias value
*/
HB_EXPR_USE( pAlias, HB_EA_PUSH_PCODE );
hb_compGenPopAliasedVar( pSelf->value.asAlias.szVarName, FALSE, NULL, 0 );
}
else
hb_compErrorAlias( pAlias );
}
break;
case HB_EA_PUSH_POP:
case HB_EA_STATEMENT:
hb_compWarnMeaningless( pSelf );
HB_EXPR_USE( pSelf, HB_EA_PUSH_PCODE );
hb_compGenPCode1( HB_P_POP );
break;
case HB_EA_DELETE:
hb_compExprDelete( pSelf->value.asAlias.pAlias );
/* NOTE: variable name is not released now */
break;
}
return pSelf;
@@ -4322,6 +4433,7 @@ static HB_EXPR_FUNC( hb_compExprUseDiv )
pSelf->value.asNum.bDec = 2; /* TODO: See NOTE 1 */
pSelf->value.asNum.NumType = HB_ET_DOUBLE;
}
pSelf->ExprType = HB_ET_NUMERIC;
}
break;
@@ -4332,6 +4444,7 @@ static HB_EXPR_FUNC( hb_compExprUseDiv )
pSelf->value.asNum.dVal = dVal;
pSelf->value.asNum.NumType = HB_ET_DOUBLE;
pSelf->value.asNum.bDec = 2; /* TODO: See NOTE 1 */
pSelf->ExprType = HB_ET_NUMERIC;
}
break;
@@ -4350,8 +4463,10 @@ static HB_EXPR_FUNC( hb_compExprUseDiv )
dVal = ( double ) pLeft->value.asNum.lVal / pRight->value.asNum.dVal;
pSelf->value.asNum.dVal = dVal;
pSelf->value.asNum.bDec = 2; /* TODO: See NOTE 1 */
}
pSelf->value.asNum.NumType = HB_ET_DOUBLE;
pSelf->ExprType = HB_ET_NUMERIC;
}
/* TODO: NOTE 1
Clipper manages to print the default number of decimal
@@ -4362,11 +4477,14 @@ static HB_EXPR_FUNC( hb_compExprUseDiv )
for HB_DEC_DEFAULT when formatting numbers and print
the current default number of decimal digits.
*/
}
pSelf->ExprType = HB_ET_NUMERIC;
pSelf->ValType = HB_EV_NUMERIC;
HB_EXPR_USE( pLeft, HB_EA_DELETE );
HB_EXPR_USE( pRight, HB_EA_DELETE );
} /* switch bType*/
if( pSelf->ExprType == HB_ET_NUMERIC )
{
/* The expression was reduced - delete old components */
pSelf->ValType = HB_EV_NUMERIC;
hb_compExprDelete( pLeft );
hb_compExprDelete( pRight );
}
}
else
{

View File

@@ -118,12 +118,10 @@ BOOL hb_comp_bDontGenLineNum = FALSE; /* suppress line number generation */
LONG hb_comp_lLastPushPos = -1; /* position of last push pcode */
ULONG hb_comp_ulLastLinePos = 0; /* position of last opcode with line number */
ULONG hb_comp_ulMessageFix = 0; /* Position of the message which needs to be changed */
ALIASID_PTR hb_comp_pAliasId = NULL;
int hb_comp_iStaticCnt = 0; /* number of defined statics variables on the PRG */
BOOL hb_comp_bExternal = FALSE;
PTR_LOOPEXIT hb_comp_pLoops = NULL;
PEXTERN hb_comp_pExterns = NULL;
EXPLIST_PTR hb_comp_pExprList = NULL; /* stack used for parenthesized expressions */
int hb_comp_iVarScope = VS_LOCAL; /* holds the scope for next variables to be defined */
/* different values for hb_comp_iVarScope */
@@ -1575,79 +1573,6 @@ PCOMSYMBOL hb_compAddSymbol( char * szSymbolName, USHORT * pwPos )
return pSym;
}
/* Adds new alias to the alias stack
*/
void AliasAdd( ALIASID_PTR pAlias )
{
pAlias->pPrev = hb_comp_pAliasId;
hb_comp_pAliasId = pAlias;
}
/* Restores previously selected alias
*/
void AliasRemove( void )
{
ALIASID_PTR pAlias = hb_comp_pAliasId;
hb_comp_pAliasId = hb_comp_pAliasId->pPrev;
hb_xfree( pAlias );
}
/* Adds an integer workarea number into alias stack
*/
void AliasAddInt( int iWorkarea )
{
ALIASID_PTR pAlias = ( ALIASID_PTR ) hb_xgrab( sizeof( ALIASID ) );
pAlias->type = ALIAS_NUMBER;
pAlias->alias.iAlias = iWorkarea;
AliasAdd( pAlias );
}
/* Adds an expression into alias stack
*/
void AliasAddExp( void )
{
ALIASID_PTR pAlias = ( ALIASID_PTR ) hb_xgrab( sizeof( ALIASID ) );
pAlias->type = ALIAS_EVAL;
AliasAdd( pAlias );
}
/* Adds an alias name into alias stack
*/
void AliasAddStr( char * szAlias )
{
ALIASID_PTR pAlias = ( ALIASID_PTR ) hb_xgrab( sizeof( ALIASID ) );
pAlias->type = ALIAS_NAME;
pAlias->alias.szAlias = szAlias;
AliasAdd( pAlias );
}
/* Generates pcodes to store the current workarea number
*/
void AliasPush( void )
{
hb_compGenPCode1( HB_P_PUSHALIAS );
}
/* Generates pcodes to select the workarea number using current value
* from the eval stack
*/
void AliasPop( void )
{
hb_compGenPCode1( HB_P_POPALIAS );
}
/* Generates pcodes to swap two last items from the eval stack.
* Last item (after swaping) is next popped as current workarea
*/
void AliasSwap( void )
{
hb_compGenPCode1( HB_P_SWAPALIAS );
}
void Duplicate( void )
{
hb_compGenPCode1( HB_P_DUPLICATE );
@@ -1661,98 +1586,6 @@ void DupPCode( ULONG ulStart ) /* duplicates the current generated pcode from an
hb_compGenPCode1( hb_comp_functions.pLast->pCode[ ulStart + w ] );
}
/*
* Starts a new expression in the parenthesized epressions list
*/
void ExpListPush( void )
{
EXPLIST_PTR pExp = ( EXPLIST_PTR ) hb_xgrab( sizeof( EXPLIST ) );
pExp->pNext = pExp->pPrev = NULL;
/* Store the previous state on the stack */
if( hb_comp_pExprList )
{
hb_comp_pExprList->pNext = pExp;
pExp->pPrev = hb_comp_pExprList;
/* save currently used pcode buffer */
hb_comp_pExprList->exprSize = hb_comp_functions.pLast->lPCodePos;
hb_comp_pExprList->exprPCode = hb_comp_functions.pLast->pCode;
}
hb_comp_pExprList = pExp;
/* store current pcode buffer */
pExp->prevPCode = hb_comp_functions.pLast->pCode;
pExp->prevSize = hb_comp_functions.pLast->lPCodeSize;
pExp->prevPos = hb_comp_functions.pLast->lPCodePos;
/* and create the new one */
hb_comp_functions.pLast->pCode = ( BYTE * ) hb_xgrab( PCODE_CHUNK );
hb_comp_functions.pLast->lPCodeSize = PCODE_CHUNK;
hb_comp_functions.pLast->lPCodePos = 0;
pExp->exprPCode = hb_comp_functions.pLast->pCode;
}
/*
* Pops specified number of expressions from the stack
*/
void ExpListPop( int iExpCount )
{
EXPLIST_PTR pExp, pDel;
/* save currently used pcode buffer */
hb_comp_pExprList->exprSize = hb_comp_functions.pLast->lPCodePos;
hb_comp_pExprList->exprPCode = hb_comp_functions.pLast->pCode;
/* find the first expression in the list */
while( --iExpCount )
hb_comp_pExprList = hb_comp_pExprList->pPrev;
/* return to the original pcode buffer */
hb_comp_functions.pLast->pCode = hb_comp_pExprList->prevPCode;
hb_comp_functions.pLast->lPCodeSize = hb_comp_pExprList->prevSize;
hb_comp_functions.pLast->lPCodePos = hb_comp_pExprList->prevPos;
pExp = hb_comp_pExprList;
if( hb_comp_pExprList->pPrev )
{
hb_comp_pExprList = hb_comp_pExprList->pPrev;
hb_comp_pExprList->pNext = NULL;
}
else
hb_comp_pExprList = NULL;
while( pExp )
{
if( pExp->exprSize )
{
hb_compGenPCodeN( pExp->exprPCode, pExp->exprSize );
if( pExp->pNext )
hb_compGenPCode1( HB_P_POP );
}
else
{
/* exprN, , exprN1
* in this context empty expression is not allowed
*
* NOTE:
* We don't have to generate this error - it is safe to continue
* pcode generation - in this case an empty expression will not
* generate any opcode
*/
hb_compGenError( hb_comp_szCErrors, 'E', ERR_SYNTAX, ")", NULL );
}
hb_xfree( pExp->exprPCode );
pDel = pExp;
pExp = pExp->pNext;
hb_xfree( pDel );
}
}
/*
* Function generates passed pcode for passed database field
*/
@@ -1994,118 +1827,6 @@ void hb_compGenExterns( void ) /* generates the symbols for the EXTERN names */
}
}
/* This function generates pcodes for IIF( expr1, expr2, expr3 )
* or IF( expr1, expr2, expr3 )
*
* NOTE:
* 'IF' followed by parenthesized expression containing 3 expressions
* is always interpreted as IF inlined - it is not possible to distinguish
* it from IF( expr1, expr2, expr3 ); ENDIF syntax
* (This behaviour is Clipper compatible)
*/
void GenIfInline( void )
{
EXPLIST_PTR pExp, pDel;
int iExpCount = 3; /* We are expecting 3 expressions here */
BOOL bhb_compGenPCode;
/* save currently used pcode buffer */
hb_comp_pExprList->exprSize = hb_comp_functions.pLast->lPCodePos;
hb_comp_pExprList->exprPCode = hb_comp_functions.pLast->pCode;
/* find the first expression in the list */
while( --iExpCount )
hb_comp_pExprList = hb_comp_pExprList->pPrev;
/* return to the original pcode buffer */
hb_comp_functions.pLast->pCode = hb_comp_pExprList->prevPCode;
hb_comp_functions.pLast->lPCodeSize = hb_comp_pExprList->prevSize;
hb_comp_functions.pLast->lPCodePos = hb_comp_pExprList->prevPos;
/* Update the pointer for nested or next expressions */
pExp = hb_comp_pExprList;
if( hb_comp_pExprList->pPrev )
{
hb_comp_pExprList = hb_comp_pExprList->pPrev;
hb_comp_pExprList->pNext = NULL;
}
else
hb_comp_pExprList = NULL;
bhb_compGenPCode = TRUE;
pDel = pExp; /* save it for later use */
/* pExp points now to pcode buffer for logical condition
*/
if( pExp->exprSize == 0 )
{
/* The logical condition have to be specified.
* If it is empty then generate the syntax error
*/
hb_compGenError( hb_comp_szCErrors, 'E', ERR_SYNTAX, ",", NULL );
}
else if( pExp->exprSize == 1 )
{
/* one byte opcode for logical condition - check if it is TRUE or FALSE
*/
if( pExp->exprPCode[ 0 ] == HB_P_TRUE )
{
/* move to the second expression */
pExp = pExp->pNext;
if( pExp->exprSize )
hb_compGenPCodeN( pExp->exprPCode, pExp->exprSize );
else
hb_compGenPushNil(); /* IIF have to return some value */
bhb_compGenPCode = FALSE;
}
else if( pExp->exprPCode[ 0 ] == HB_P_FALSE )
{
/* move to the third expression */
pExp = pExp->pNext;
pExp = pExp->pNext;
if( pExp->exprSize )
hb_compGenPCodeN( pExp->exprPCode, pExp->exprSize );
else
hb_compGenPushNil(); /* IIF have to return some value */
bhb_compGenPCode = FALSE;
}
}
if( bhb_compGenPCode )
{
/* generate pcodes for all expressions
*/
LONG lPosFalse, lPosEnd;
hb_compGenPCodeN( pExp->exprPCode, pExp->exprSize );
lPosFalse = hb_compGenJumpFalse( 0 );
pExp = pExp->pNext;
if( pExp->exprSize )
hb_compGenPCodeN( pExp->exprPCode, pExp->exprSize );
else
hb_compGenPushNil(); /* IIF have to return some value */
lPosEnd = hb_compGenJump( 0 );
hb_compGenJumpHere( lPosFalse );
pExp = pExp->pNext;
if( pExp->exprSize )
hb_compGenPCodeN( pExp->exprPCode, pExp->exprSize );
else
hb_compGenPushNil(); /* IIF have to return some value */
hb_compGenJumpHere( lPosEnd );
}
while( pDel )
{
pExp = pDel;
pDel = pDel->pNext;
hb_xfree( pExp->exprPCode );
hb_xfree( pExp );
}
}
PFUNCTION GetFuncall( char * szFunctionName ) /* returns a previously called defined function */
{
PFUNCTION pFunc = hb_comp_funcalls.pFirst;
@@ -2689,135 +2410,99 @@ void hb_compGenPopVar( char * szVarName ) /* generates the pcode to pop a value
{
int iVar;
if( hb_comp_pAliasId == NULL )
{
iVar = GetLocalVarPos( szVarName );
if( iVar )
hb_compGenPCode3( HB_P_POPLOCAL, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
else
{
iVar = GetStaticVarPos( szVarName );
if( iVar )
{
hb_compGenPCode3( HB_P_POPSTATIC, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
hb_comp_functions.pLast->bFlags |= FUN_USES_STATICS;
}
else
{
VariablePCode( HB_P_POPVARIABLE, szVarName );
}
}
}
iVar = GetLocalVarPos( szVarName );
if( iVar )
hb_compGenPCode3( HB_P_POPLOCAL, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
else
{
if( hb_comp_pAliasId->type == ALIAS_NAME )
iVar = GetStaticVarPos( szVarName );
if( iVar )
{
if( hb_comp_pAliasId->alias.szAlias[ 0 ] == 'M' && hb_comp_pAliasId->alias.szAlias[ 1 ] == '\0' )
hb_compGenPCode3( HB_P_POPSTATIC, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
hb_comp_functions.pLast->bFlags |= FUN_USES_STATICS;
}
else
{
VariablePCode( HB_P_POPVARIABLE, szVarName );
}
}
}
/* generates the pcode to pop a value from the virtual machine stack onto
* an aliased variable
*/
void hb_compGenPopAliasedVar( char * szVarName,
BOOL bPushAliasValue,
char * szAlias,
long lWorkarea )
{
if( bPushAliasValue )
{
if( szAlias )
{
if( szAlias[ 0 ] == 'M' && szAlias[ 1 ] == '\0' )
{ /* M->variable */
MemvarPCode( HB_P_POPMEMVAR, szVarName );
}
else
{
int iCmp = strncmp( hb_comp_pAliasId->alias.szAlias, "MEMVAR", 4 );
int iCmp = strncmp( szAlias, "MEMVAR", 4 );
if( iCmp == 0 )
iCmp = strncmp( hb_comp_pAliasId->alias.szAlias, "MEMVAR", strlen( hb_comp_pAliasId->alias.szAlias ) );
iCmp = strncmp( szAlias, "MEMVAR", strlen( szAlias ) );
if( iCmp == 0 )
{ /* MEMVAR-> or MEMVA-> or MEMV-> */
MemvarPCode( HB_P_POPMEMVAR, szVarName );
}
else
{ /* field variable */
iCmp = strncmp( hb_comp_pAliasId->alias.szAlias, "FIELD", 4 );
iCmp = strncmp( szAlias, "FIELD", 4 );
if( iCmp == 0 )
iCmp = strncmp( hb_comp_pAliasId->alias.szAlias, "FIELD", strlen( hb_comp_pAliasId->alias.szAlias ) );
iCmp = strncmp( szAlias, "FIELD", strlen( szAlias ) );
if( iCmp == 0 )
{ /* FIELD-> */
FieldPCode( HB_P_POPFIELD, szVarName );
}
else
{ /* database alias */
hb_compPushSymbol( yy_strdup( hb_comp_pAliasId->alias.szAlias ), 0 );
hb_compPushSymbol( yy_strdup( szAlias ), 0 );
FieldPCode( HB_P_POPALIASEDFIELD, szVarName );
}
}
}
}
else if( hb_comp_pAliasId->type == ALIAS_NUMBER )
{
hb_compGenPushInteger( hb_comp_pAliasId->alias.iAlias );
FieldPCode( HB_P_POPALIASEDFIELD, szVarName );
}
else
/* Alias is already placed on stack */
FieldPCode( HB_P_POPALIASEDFIELD, szVarName );
}
}
void hb_compGenPushVar( char * szVarName ) /* generates the pcode to push a variable value to the virtual machine stack */
{
int iVar;
if( hb_comp_pAliasId == NULL )
{
iVar = GetLocalVarPos( szVarName );
if( iVar )
hb_compGenPCode3( HB_P_PUSHLOCAL, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
else
{
iVar = GetStaticVarPos( szVarName );
if( iVar )
{
hb_compGenPCode3( HB_P_PUSHSTATIC, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
hb_comp_functions.pLast->bFlags |= FUN_USES_STATICS;
}
else
{
VariablePCode( HB_P_PUSHVARIABLE, szVarName );
}
hb_compGenPushLong( lWorkarea );
FieldPCode( HB_P_POPALIASEDFIELD, szVarName );
}
}
else
/* Alias is already placed on stack */
FieldPCode( HB_P_POPALIASEDFIELD, szVarName );
}
/* generates the pcode to push a nonaliased variable value to the virtual
* machine stack
*/
void hb_compGenPushVar( char * szVarName )
{
int iVar;
iVar = GetLocalVarPos( szVarName );
if( iVar )
hb_compGenPCode3( HB_P_PUSHLOCAL, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
else
{
if( hb_comp_pAliasId->type == ALIAS_NAME )
iVar = GetStaticVarPos( szVarName );
if( iVar )
{
if( hb_comp_pAliasId->alias.szAlias[ 0 ] == 'M' && hb_comp_pAliasId->alias.szAlias[ 1 ] == '\0' )
{ /* M->variable */
MemvarPCode( HB_P_PUSHMEMVAR, szVarName );
}
else
{
int iCmp = strncmp( hb_comp_pAliasId->alias.szAlias, "MEMVAR", 4 );
if( iCmp == 0 )
iCmp = strncmp( hb_comp_pAliasId->alias.szAlias, "MEMVAR", strlen( hb_comp_pAliasId->alias.szAlias ) );
if( iCmp == 0 )
{ /* MEMVAR-> or MEMVA-> or MEMV-> */
MemvarPCode( HB_P_PUSHMEMVAR, szVarName );
}
else
{ /* field variable */
iCmp = strncmp( hb_comp_pAliasId->alias.szAlias, "FIELD", 4 );
if( iCmp == 0 )
iCmp = strncmp( hb_comp_pAliasId->alias.szAlias, "FIELD", strlen( hb_comp_pAliasId->alias.szAlias ) );
if( iCmp == 0 )
{ /* FIELD-> */
FieldPCode( HB_P_PUSHFIELD, szVarName );
}
else
{ /* database alias */
hb_compPushSymbol( yy_strdup( hb_comp_pAliasId->alias.szAlias ), 0 );
FieldPCode( HB_P_PUSHALIASEDFIELD, szVarName );
}
}
}
}
else if( hb_comp_pAliasId->type == ALIAS_NUMBER )
{
hb_compGenPushInteger( hb_comp_pAliasId->alias.iAlias );
FieldPCode( HB_P_PUSHALIASEDFIELD, szVarName );
hb_compGenPCode3( HB_P_PUSHSTATIC, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
hb_comp_functions.pLast->bFlags |= FUN_USES_STATICS;
}
else
/* Alias is already placed on stack */
FieldPCode( HB_P_PUSHALIASEDFIELD, szVarName );
{
VariablePCode( HB_P_PUSHVARIABLE, szVarName );
}
}
}
@@ -2847,6 +2532,63 @@ void hb_compGenPushVarRef( char * szVarName ) /* generates the pcode to push a v
}
}
/* generates the pcode to push an aliased variable value to the virtual
* machine stack
*/
void hb_compGenPushAliasedVar( char * szVarName,
BOOL bPushAliasValue,
char * szAlias,
long lWorkarea )
{
if( bPushAliasValue )
{
if( szAlias )
{
/* myalias->var
* FIELD->var
* MEMVAR->var
*/
if( szAlias[ 0 ] == 'M' && szAlias[ 1 ] == '\0' )
{ /* M->variable */
MemvarPCode( HB_P_PUSHMEMVAR, szVarName );
}
else
{
int iCmp = strncmp( szAlias, "MEMVAR", 4 );
if( iCmp == 0 )
iCmp = strncmp( szAlias, "MEMVAR", strlen( szAlias ) );
if( iCmp == 0 )
{ /* MEMVAR-> or MEMVA-> or MEMV-> */
MemvarPCode( HB_P_PUSHMEMVAR, szVarName );
}
else
{ /* field variable */
iCmp = strncmp( szAlias, "FIELD", 4 );
if( iCmp == 0 )
iCmp = strncmp( szAlias, "FIELD", strlen( szAlias ) );
if( iCmp == 0 )
{ /* FIELD-> */
FieldPCode( HB_P_PUSHFIELD, szVarName );
}
else
{ /* database alias */
hb_compPushSymbol( yy_strdup( szAlias ), 0 );
FieldPCode( HB_P_PUSHALIASEDFIELD, szVarName );
}
}
}
}
else
{
hb_compGenPushLong( lWorkarea );
FieldPCode( HB_P_PUSHALIASEDFIELD, szVarName );
}
}
else
/* Alias is already placed on stack */
FieldPCode( HB_P_PUSHALIASEDFIELD, szVarName );
}
void hb_compGenPushLogical( int iTrueFalse ) /* pushes a logical value on the virtual machine stack */
{
if( iTrueFalse )

View File

@@ -559,6 +559,10 @@ Separator {SpaceTab}
%{
/* ************************************************************************ */
%}
"_fie"|"_fiel"|"_field" { BEGIN FIELD_;
yylval.string = yy_strupr( yy_strdup( yytext ) );
}
"fiel"|"field" { BEGIN FIELD_;
yylval.string = yy_strupr( yy_strdup( yytext ) );
}

View File

@@ -43,12 +43,8 @@
* 4) in some cases incorrect warnings are generated when -w option is used
* 5) in some cases GPF occurs when -w option is used, example:
* LOCAL nDouble := NumAnd32(RandGetLong() / 65536, 32767) / 997
* 6) support for expr:expr (QSELF():cVar) syntax.
* see tests/broken/clasname.prg
* 7) Change the pcode generated by ::cVar from Self:cVar to QSELF():cVar
* 8) Support this syntax: _FIELD->c->mmezo := mt
* 9) Support this syntax: nPtr := @Hello()
*10) Support for syntax: FOR [ array | object | alias_expr | other ] := value
* 6) Change the pcode generated by ::cVar from Self:cVar to QSELF():cVar
* 7) Support this syntax: nPtr := @Hello()
*/
#include "compiler.h"
@@ -281,7 +277,7 @@ ParamList : IDENTIFIER AsType { hb_compAddVar( $1, ' ' ); $$ = 1
* stop compilation if invalid syntax will be used.
*/
Statement : ExecFlow CrlfStmnt { }
| Expression { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); } CrlfStmnt
| Expression CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
| BREAK { hb_compGenBreak(); } CrlfStmnt { hb_compGenDoProc( 0 ); }
| BREAK { hb_compGenBreak(); } Expression CrlfStmnt { hb_compExprDelete( hb_compExprGenPush( $3 ) ); hb_compGenDoProc( 1 ); }
| RETURN CrlfStmnt {
@@ -946,13 +942,13 @@ DoCaseBegin : DoCaseStart { }
}
;
Cases : CASE Expression Crlf
Cases : CASE Expression Crlf
{
hb_compExprDelete( hb_compExprGenPush( $2 ) );
$<iNumber>$ = hb_compGenJumpFalse( 0 );
Line();
}
EmptyStats
EmptyStats
{
$$ = GenElseIf( 0, hb_compGenJump( 0 ) );
hb_compGenJumpHere( $<iNumber>4 );
@@ -965,7 +961,7 @@ Cases : CASE Expression Crlf
$<iNumber>$ = hb_compGenJumpFalse( 0 );
Line();
}
EmptyStats
EmptyStats
{
$$ = GenElseIf( $1, hb_compGenJump( 0 ) );
hb_compGenJumpHere( $<iNumber>5 );
@@ -976,7 +972,7 @@ Cases : CASE Expression Crlf
Otherwise : OTHERWISE Crlf { Line(); } EmptyStats
;
DoWhile : WhileBegin Expression Crlf
DoWhile : WhileBegin Expression Crlf
{
hb_compExprDelete( hb_compExprGenPush( $2 ) );
$<lNumber>$ = hb_compGenJumpFalse( 0 );
@@ -1128,9 +1124,9 @@ DoArgList : ',' { hb_compGenPushNil(); hb_compGen
| ',' { hb_compGenPushNil(); } DoExpression { $$ = 2; }
;
DoExpression: IDENTIFIER { hb_compGenPushVarRef( $1 ); }
| SimpleExpression { }
| PareExpList { }
DoExpression: IDENTIFIER { hb_compExprDelete( hb_compExprGenPush( hb_compExprNewVarRef( $1 ) ) ); }
| SimpleExpression { hb_compExprDelete( hb_compExprGenPush( $1 ) ); }
| PareExpList { hb_compExprDelete( hb_compExprGenPush( $1 ) ); }
;
Crlf : '\n' { ++iLine; }