PHB_EXPR hb_compWarnMeaningless( HB_COMP_DECL, PHB_EXPR pExpr ) { if( ! HB_COMP_PARAM->fMeaningful ) { const char * szDesc = hb_compExprDescription( pExpr ); hb_compGenWarning( HB_COMP_PARAM, hb_comp_szWarnings, 'W', HB_COMP_WARN_MEANINGLESS, szDesc, NULL ); } return pExpr; }
static void hb_pp_ErrorGen( void * cargo, const char * const szMsgTable[], char cPrefix, int iErrorCode, const char * szParam1, const char * szParam2 ) { HB_COMP_DECL = ( PHB_COMP ) cargo; int iCurrLine = HB_COMP_PARAM->currLine; const char * currModule = HB_COMP_PARAM->currModule; HB_COMP_PARAM->currLine = hb_pp_line( HB_COMP_PARAM->pLex->pPP ); HB_COMP_PARAM->currModule = hb_pp_fileName( HB_COMP_PARAM->pLex->pPP ); if( cPrefix == 'W' ) hb_compGenWarning( HB_COMP_PARAM, szMsgTable, cPrefix, iErrorCode, szParam1, szParam2 ); else hb_compGenError( HB_COMP_PARAM, szMsgTable, cPrefix, iErrorCode, szParam1, szParam2 ); HB_COMP_PARAM->fError = HB_FALSE; HB_COMP_PARAM->currLine = iCurrLine; HB_COMP_PARAM->currModule = currModule; }
PHB_EXPR hb_compExprNewFunCall( PHB_EXPR pName, PHB_EXPR pParms, HB_COMP_DECL ) #endif { PHB_EXPR pExpr; #ifdef HB_MACRO_SUPPORT if( pName->ExprType == HB_ET_VARIABLE ) { /* My&var.1() executed by macro compiler */ /* NOTE: direct type change */ pName->ExprType = HB_ET_FUNNAME; pName->value.asSymbol.name = hb_compGetFuncID( pName->value.asSymbol.name, &pName->value.asSymbol.funcid, &pName->value.asSymbol.flags ); } #endif if( pName->ExprType == HB_ET_FUNNAME ) { /* The name of a function is specified at compile time * e.g. MyFunc() * * NOTE: 'pName' can be a macro expression that will be resolved * at runtime - in this case pName is an expression of HB_ET_MACRO type * e.g. &MyVar() */ HB_TRACE( HB_TR_DEBUG, ( "hb_compExprNewFunCall(%s)", pName->value.asSymbol.name ) ); #if ! defined( HB_MACRO_SUPPORT ) && defined( HB_USE_ENUM_FUNCTIONS ) { int iLen = strlen( pName->value.asSymbol.name ); if( iLen >= 10 && iLen <= 14 && memcmp( "HB_ENUM", pName->value.asSymbol.name, 7 ) == 0 ) { const char * szMessage = pName->value.asSymbol.name + 7; if( iLen == 12 && memcmp( "INDEX", szMessage, 5 ) == 0 ) szMessage = "__ENUMINDEX"; else if( iLen == 12 && memcmp( "VALUE", szMessage, 5 ) == 0 ) szMessage = "__ENUMVALUE"; else if( iLen == 11 && memcmp( "BASE", szMessage, 4 ) == 0 ) szMessage = "__ENUMBASE"; else if( iLen == 10 && memcmp( "KEY", szMessage, 3 ) == 0 ) szMessage = "__ENUMKEY"; else if( iLen == 14 && memcmp( "ISFIRST", szMessage, 7 ) == 0 ) szMessage = "__ENUMISFIRST"; else if( iLen == 13 && memcmp( "ISLAST", szMessage, 6 ) == 0 ) szMessage = "__ENUMISLAST"; else szMessage = NULL; if( szMessage ) { int iCount = ( int ) hb_compExprParamListLen( pParms ); PHB_ENUMERATOR pForVar, pEnumVar = NULL; pForVar = HB_COMP_PARAM->functions.pLast->pEnum; if( iCount == 0 ) { while( pForVar ) { if( pForVar->iForEachDir != 0 ) pEnumVar = pForVar; pForVar = pForVar->pNext; } } else if( iCount == 1 ) { if( pParms->value.asList.pExprList->ExprType == HB_ET_VARIABLE || pParms->value.asList.pExprList->ExprType == HB_ET_VARREF ) { const char * szName = pParms->value.asList.pExprList->value.asSymbol.name; while( pForVar ) { if( pForVar->iForEachDir != 0 && strcmp( pEnumVar->szName, szName ) == 0 ) { pEnumVar = pForVar; break; } pForVar = pForVar->pNext; } } } if( pEnumVar ) { #if 0 if( pEnumVar->iForEachDir < 0 ) { if( strcmp( "__ENUMISFIRST", szMessage ) == 0 ) szMessage = "__ENUMISLAST"; else if( strcmp( "__ENUMISLAST", szMessage ) == 0 ) szMessage = "__ENUMISFIRST"; } #endif if( pParms ) HB_COMP_EXPR_FREE( pParms ); HB_COMP_EXPR_FREE( pName ); return hb_compExprNewMethodObject( hb_compExprNewSend( szMessage, HB_COMP_PARAM ), hb_compExprNewVar( pEnumVar->szName, HB_COMP_PARAM ) ); } } } } #endif if( pName->value.asSymbol.funcid == HB_F_EVAL && hb_compExprParamListLen( pParms ) != 0 ) { /* Optimize Eval( bBlock, [ArgList] ) to: bBlock:Eval( [ArgList] ) */ PHB_EXPR pEval; pEval = hb_compExprNewMethodCall( hb_compExprNewMethodObject( hb_compExprNewSend( "EVAL", HB_COMP_PARAM ), pParms->value.asList.pExprList ), hb_compExprNewArgList( pParms->value.asList.pExprList->pNext, HB_COMP_PARAM ) ); #if ! defined( HB_MACRO_SUPPORT ) /* force reduction */ pEval->nLength = 1; #endif pParms->value.asList.pExprList = NULL; HB_COMP_EXPR_FREE( pParms ); HB_COMP_EXPR_FREE( pName ); return pEval; } else if( pName->value.asSymbol.funcid == HB_F__GET_ && hb_compExprParamListLen( pParms ) != 0 ) { /* Reserved Clipper function used to handle GET variables */ PHB_EXPR pArg, pNext; /* pArg has to be reduced to eliminate possible problems with * cloned expressions in SETGET block */ if( HB_SUPPORT_HARBOUR ) { pParms = HB_EXPR_USE( pParms, HB_EA_REDUCE ); pArg = pParms->value.asList.pExprList; } else { pArg = pParms->value.asList.pExprList; pNext = pArg->pNext; pArg->pNext = NULL; pArg = hb_compExprListStrip( HB_EXPR_USE( pArg, HB_EA_REDUCE ), HB_COMP_PARAM ); pArg->pNext = pNext; pParms->value.asList.pExprList = pArg; } if( pArg->ExprType == HB_ET_ARRAYAT ) { HB_USHORT uiCount; /* replace: _GET_( a[1], "a[1]", , , ) into: __GetA( {||a }, "a", , , , { 1 } ) */ PHB_EXPR pIndex, pVar; PHB_EXPR pBase; pName->value.asSymbol.name = "__GETA"; /* NOTE: a[ i, j ] is stored as: (pExprList)->(pIndex) * ( ( a->[ i ] )->[ j ] ) */ pVar = HB_EXPR_USE( pArg->value.asList.pExprList, HB_EA_REDUCE ); pBase = pVar->ExprType == HB_ET_ARRAYAT ? pVar : NULL; pIndex = HB_EXPR_USE( pArg->value.asList.pIndex, HB_EA_REDUCE ); pIndex->pNext = NULL; while( pVar->ExprType == HB_ET_ARRAYAT ) { /* traverse back to a leftmost expression and build a list * of index expressions */ pVar->value.asList.pIndex->pNext = pIndex; pIndex = pVar->value.asList.pIndex; pVar = pVar->value.asList.pExprList; } /* create a set only codeblock */ if( pVar->ExprType == HB_ET_MACRO ) { /* &var[ 1 ] */ HB_COMP_EXPR_FREE( pVar ); pVar = hb_compExprNewNil( HB_COMP_PARAM ); } else { pVar = hb_compExprAddCodeblockExpr( hb_compExprNewCodeBlock( NULL, 0, 0, HB_COMP_PARAM ), pVar ); } /* pVar will be the first argument now */ pParms->value.asList.pExprList = pVar; /* link the rest of parameters */ pVar->pNext = pArg->pNext; /* Delete an argument that was the first one */ pArg->value.asList.pIndex = NULL; pArg->value.asList.pExprList = NULL; HB_COMP_EXPR_CLEAR( pArg ); /* Create an array with index elements */ pIndex = hb_compExprNewArray( hb_compExprNewList( pIndex, HB_COMP_PARAM ), HB_COMP_PARAM ); /* The array with index elements have to be the sixth argument * of __GetA() call */ uiCount = 1; while( ++uiCount < 6 ) { if( pVar->pNext == NULL ) pVar->pNext = hb_compExprNewNil( HB_COMP_PARAM ); pVar = pVar->pNext; } if( pVar->pNext ) /* Delete 6-th argument if present */ { pIndex->pNext = pVar->pNext->pNext; HB_COMP_EXPR_FREE( pVar->pNext ); } pVar->pNext = pIndex; /* Set a new 6-th argument */ /* Remove the index expression from a string representation */ pVar = pParms->value.asList.pExprList->pNext; if( pVar->ExprType == HB_ET_STRING ) { HB_SIZE i = 0; char * szVar = pVar->value.asString.string; /* NOTE: Clipper strips a string at the first '[' character too */ while( ++i < pVar->nLength ) { if( szVar[ i ] == '[' ) { if( ! pVar->value.asString.dealloc ) { szVar = pVar->value.asString.string = ( char * ) hb_xmemdup( pVar->value.asString.string, i + 1 ); pVar->value.asString.dealloc = HB_TRUE; } szVar[ i ] = 0; pVar->nLength = i; break; } } } /* clear expressions no longer used */ if( pBase ) { while( pBase->ExprType == HB_ET_ARRAYAT ) { pVar = pBase->value.asList.pExprList; pBase->value.asList.pExprList = NULL; HB_COMP_EXPR_CLEAR( pBase ); pBase = pVar; } } } else if( pArg->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 ) { /* Simple macro expansion (not a parenthesized expressions) */ PHB_EXPR pFirst; pFirst = pArg; /* first argument */ pNext = pFirst->pNext; /* second argument */ if( pNext ) pNext = pNext->pNext; /* third argument */ pArg = hb_compExprNewNil( HB_COMP_PARAM ); /* replace 1st with NIL */ pParms->value.asList.pExprList = pArg; pArg->pNext = pFirst->pNext; if( pFirst->value.asMacro.cMacroOp == '&' ) { /* 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 */ } else { /* 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; } } HB_COMP_EXPR_FREE( pFirst ); /* delete first argument */ } else { /* @ 0,0 GET &(var) */ #if defined( HB_MACRO_SUPPORT ) hb_macroError( EG_SYNTAX, HB_COMP_PARAM ); #else hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_GET_COMPLEX_MACRO, NULL, NULL ); #endif } } else { pName->value.asSymbol.name = "__GET"; /* store second and a rest of arguments */ pNext = pArg->pNext; pArg->pNext = NULL; /* replace first argument with a set/get codeblock */ #if ! defined( HB_MACRO_SUPPORT ) if( pArg->ExprType == HB_ET_VARIABLE ) { 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 ); } } else #endif { pArg = hb_compExprSetGetBlock( pArg, HB_COMP_PARAM ); } /* restore next arguments */ pArg->pNext = pNext; /* set an updated list of arguments */ pParms->value.asList.pExprList = pArg; } pName->value.asSymbol.name = hb_compGetFuncID( pName->value.asSymbol.name, &pName->value.asSymbol.funcid, &pName->value.asSymbol.flags ); } } else if( pName->ExprType == HB_ET_MACRO ) { /* Signal that macro compiler have to generate a pcode that will * return function name as symbol instead of usual value */ pName->value.asMacro.SubType = HB_ET_MACRO_SYMBOL; HB_TRACE( HB_TR_DEBUG, ( "hb_compExprNewFunCall(&)" ) ); } pExpr = HB_COMP_EXPR_NEW( HB_ET_FUNCALL ); pExpr->value.asFunCall.pParms = pParms; pExpr->value.asFunCall.pFunName = pName; return pExpr; }