2015-12-04 23:05 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)

* include/hbexpra.c
    ! accept strings passed in 2-nd parameter of _GET_() function
      with the highest priority for macro and macroalias expressions
    ! fixed late evaluation of macroalias expressions in GET variables.
      Thanks to Volodimyr for information about the problem and self
      contain code example.

  * include/hbexprb.c
    ! fixed typo in SetGet expression LValue validation
This commit is contained in:
Przemysław Czerpak
2015-12-04 23:05:18 +01:00
parent d087133e36
commit ef0912cb9e
3 changed files with 98 additions and 52 deletions

View File

@@ -10,6 +10,17 @@
* Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment
*/
2015-12-04 23:05 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* include/hbexpra.c
! accept strings passed in 2-nd parameter of _GET_() function
with the highest priority for macro and macroalias expressions
! fixed late evaluation of macroalias expressions in GET variables.
Thanks to Volodimyr for information about the problem and self
contain code example.
* include/hbexprb.c
! fixed typo in SetGet expression LValue validation
2015-12-04 22:56 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* contrib/hbnetio/netiosrv.c
! fixed typo in previous modification

View File

@@ -377,55 +377,56 @@ PHB_EXPR hb_compExprNewFunCall( PHB_EXPR pName, PHB_EXPR pParms, HB_COMP_DECL )
}
}
}
else if( pArg->ExprType == HB_ET_MACRO )
else if( pArg->ExprType == HB_ET_MACRO ||
( pArg->ExprType == HB_ET_ALIASVAR &&
( pArg->value.asAlias.pAlias->ExprType == HB_ET_MACRO ||
pArg->value.asAlias.pVar->ExprType == HB_ET_MACRO ) ) )
{
/* @ 0,0 GET &var => __Get( NIL, var,... )
* @ 0,0 GET var&var => __Get( NIL, "var&var",... )
*/
pName->value.asSymbol.name = "__GET";
if( pArg->value.asMacro.pExprList == NULL )
const char * szText = NULL;
if( pArg->ExprType == HB_ET_ALIASVAR )
{
/* Simple macro expansion (not a parenthesized expressions)
*/
PHB_EXPR pFirst;
const char * szAlias = NULL, * szAliasPref = "",
* szVar = NULL, * szVarPref = "";
pFirst = pArg; /* first argument */
pNext = pFirst->pNext; /* second argument */
if( pNext )
pNext = pNext->pNext; /* third argument */
if( pArg->value.asAlias.pAlias->ExprType == HB_ET_ALIAS )
szAlias = pArg->value.asAlias.pAlias->value.asSymbol.name;
else if( pArg->value.asAlias.pAlias->ExprType == HB_ET_MACRO &&
pArg->value.asAlias.pAlias->value.asMacro.pExprList == NULL )
{
szAlias = pArg->value.asAlias.pAlias->value.asMacro.szMacro;
if( pArg->value.asAlias.pAlias->value.asMacro.cMacroOp == '&' )
szAliasPref = "&";
}
pArg = hb_compExprNewNil( HB_COMP_PARAM ); /* replace 1st with NIL */
pParms->value.asList.pExprList = pArg;
pArg->pNext = pFirst->pNext;
if( pFirst->value.asMacro.cMacroOp == '&' )
if( pArg->value.asAlias.pVar->ExprType == HB_ET_VARIABLE )
szVar = pArg->value.asAlias.pVar->value.asSymbol.name;
else if( pArg->value.asAlias.pVar->ExprType == HB_ET_MACRO &&
pArg->value.asAlias.pVar->value.asMacro.pExprList == NULL )
{
/* simple &variable - replace the second argument with
* a variable name
*/
const char * szName = pFirst->value.asMacro.szMacro;
if( pFirst->pNext )
HB_COMP_EXPR_FREE( pFirst->pNext ); /* delete a second argument */
pArg->pNext = hb_compExprNewVar( szName, HB_COMP_PARAM );
pArg->pNext->pNext = pNext; /* restore third argument */
szVar = pArg->value.asAlias.pVar->value.asMacro.szMacro;
if( pArg->value.asAlias.pVar->value.asMacro.cMacroOp == '&' )
szVarPref = "&";
}
else
if( szAlias != NULL && szVar != NULL )
{
/* text substitution text&variable - replace the second
* argument with a string
*/
if( pArg->pNext == NULL )
{
/* no second argument */
const char *szText = pFirst->value.asMacro.szMacro;
pArg->pNext = hb_compExprNewString( szText, strlen( szText ), HB_FALSE, HB_COMP_PARAM );
pArg->pNext->pNext = pNext;
}
if( pArg->pNext && pArg->pNext->ExprType == HB_ET_STRING )
szText = "";
else
szText = hb_xstrcpy( NULL, szAliasPref, szAlias, "->", szVarPref, szVar, NULL );
}
HB_COMP_EXPR_FREE( pFirst ); /* delete first argument */
}
else
else if( pArg->value.asMacro.pExprList == NULL )
/* Simple macro expansion (not a parenthesized expressions) */
szText = pArg->value.asMacro.szMacro;
pName->value.asSymbol.name = "__GET";
if( szText == NULL )
{
/* @ 0,0 GET &(var)
* @ 0,0 GET &(var)->var
* @ 0,0 GET var->&(var)
*/
#if defined( HB_MACRO_SUPPORT )
hb_macroError( EG_SYNTAX, HB_COMP_PARAM );
@@ -433,6 +434,44 @@ PHB_EXPR hb_compExprNewFunCall( PHB_EXPR pName, PHB_EXPR pParms, HB_COMP_DECL )
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_GET_COMPLEX_MACRO, NULL, NULL );
#endif
}
else
{
/* @ 0,0 GET &var => __Get( NIL, var,... )
* @ 0,0 GET var&var => __Get( NIL, "var&var",... )
* @ 0,0 GET &var->var => __Get( NIL, "&var->var",... )
* @ 0,0 GET var->var&var => __Get( NIL, "var->var&var",... )
* @ 0,0 GET var&var->&var => __Get( NIL, "var&var->&var",... )
*/
PHB_EXPR pFirst = pArg; /* save first argument */
pArg = hb_compExprNewNil( HB_COMP_PARAM ); /* replace 1-st with NIL */
if( pFirst->pNext && pFirst->pNext->ExprType == HB_ET_STRING )
pArg->pNext = pFirst->pNext;
else
{
if( pArg->ExprType == HB_ET_ALIASVAR )
pArg->pNext = hb_compExprNewString( szText, strlen( szText ), HB_TRUE, HB_COMP_PARAM );
else if( pFirst->value.asMacro.cMacroOp == '&' )
/* simple &variable - replace the second argument with
* a variable name
*/
pArg->pNext = hb_compExprNewVar( szText, HB_COMP_PARAM );
else
/* text substitution text&variable - replace the second
* argument with a string
*/
pArg->pNext = hb_compExprNewString( szText, strlen( szText ), HB_FALSE, HB_COMP_PARAM );
if( pFirst->pNext )
{
pArg->pNext->pNext = pFirst->pNext->pNext;
HB_COMP_EXPR_FREE( pFirst->pNext ); /* delete a second argument */
}
}
HB_COMP_EXPR_FREE( pFirst ); /* delete first argument */
/* set an updated list of arguments */
pParms->value.asList.pExprList = pArg;
}
}
else
{
@@ -443,20 +482,16 @@ PHB_EXPR hb_compExprNewFunCall( PHB_EXPR pName, PHB_EXPR pParms, HB_COMP_DECL )
pArg->pNext = NULL;
/* replace first argument with a set/get codeblock */
#if ! defined( HB_MACRO_SUPPORT )
if( pArg->ExprType == HB_ET_VARIABLE )
if( pArg->ExprType == HB_ET_VARIABLE &&
! hb_compVariableFind( HB_COMP_PARAM, pArg->value.asSymbol.name, NULL, NULL ) )
{
if( hb_compVariableFind( HB_COMP_PARAM, pArg->value.asSymbol.name, NULL, NULL ) )
pArg = hb_compExprSetGetBlock( pArg, HB_COMP_PARAM );
else
{
/* Undeclared variable name - create a set/get codeblock
* at runtime
*/
if( HB_COMP_PARAM->iWarnings >= 2 )
hb_compGenWarning( HB_COMP_PARAM, hb_comp_szWarnings, 'W', HB_COMP_WARN_AMBIGUOUS_VAR, pArg->value.asSymbol.name, NULL );
HB_COMP_EXPR_FREE( pArg );
pArg = hb_compExprNewNil( HB_COMP_PARAM );
}
/* Undeclared variable name - create a set/get codeblock
* at runtime
*/
if( HB_COMP_PARAM->iWarnings >= 2 )
hb_compGenWarning( HB_COMP_PARAM, hb_comp_szWarnings, 'W', HB_COMP_WARN_AMBIGUOUS_VAR, pArg->value.asSymbol.name, NULL );
HB_COMP_EXPR_FREE( pArg );
pArg = hb_compExprNewNil( HB_COMP_PARAM );
}
else
#endif

View File

@@ -2603,7 +2603,7 @@ static HB_EXPR_FUNC( hb_compExprUseSetGet )
if( ! HB_SUPPORT_HARBOUR )
pSelf->value.asSetGet.pVar = hb_compExprListStrip( pSelf->value.asSetGet.pVar, HB_COMP_PARAM );
#endif
HB_EXPR_USE( pSelf->value.asSetGet.pVar, HB_EA_LVALUE );
HB_EXPR_USE( pSelf->value.asSetGet.pExpr, HB_EA_LVALUE );
break;
case HB_EA_ARRAY_AT:
case HB_EA_ARRAY_INDEX: