ChangeLog 19991117-13:05
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 ) );
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
Reference in New Issue
Block a user