/* List of compatibility/features modes */ void hb_compPrintModes( HB_COMP_DECL ) { static const char * s_szOptions[] = { "\nOptions: c clear all flags (strict Clipper mode)", "\n h[-] Harbour mode", "\n o[-] allow operator optimizations", "\n i[-] enable support for HB_INLINE", "\n r[-] runtime settings enabled", "\n s[-] allow indexed assignment on all types", "\n x[-] extended Xbase++ mode", "\n u[-] strings in user encoding", "\n d[-] accept macros with declared symbols", "\n m[+] turn off macrotext substitution", "\n j[+] turn off jump optimization in pcode", "\n ? this info", "\n" }; static const int s_flags[] = { 0, HB_COMPFLAG_HARBOUR, HB_COMPFLAG_EXTOPT, HB_COMPFLAG_HB_INLINE, HB_COMPFLAG_RT_MACRO, HB_COMPFLAG_ARRSTR, HB_COMPFLAG_XBASE, HB_COMPFLAG_USERCP, HB_COMPFLAG_MACRODECL, ~HB_COMPFLAG_MACROTEXT, ~HB_COMPFLAG_OPTJUMP, }; int iLine; hb_compOutStd( HB_COMP_PARAM, "\nCompatibility flags: -k[options]\n" ); for( iLine = 0; iLine < ( int ) HB_SIZEOFARRAY( s_szOptions ); iLine++ ) { hb_compOutStd( HB_COMP_PARAM, s_szOptions[ iLine ] ); if( iLine < ( int ) HB_SIZEOFARRAY( s_flags ) && ( s_flags[ iLine ] < 0 ? HB_COMP_ISSUPPORTED( ~s_flags[ iLine ] ) == 0 : HB_COMP_ISSUPPORTED( s_flags[ iLine ] ) != 0 ) ) hb_compOutStd( HB_COMP_PARAM, " (default)" ); } }
HB_BOOL hb_compFunCallCheck( HB_COMP_DECL, const char * szFuncCall, int iArgs ) { unsigned int uiFirst = 0, uiLast = HB_STD_FUNCOUNT - 1, uiMiddle; int iLen = ( int ) strlen( szFuncCall ), iCmp; /* Respect 4 or more letters shortcuts * SECO() is not allowed because of Clipper function SECONDS() * however SECO32() is a valid name. */ if( iLen < 4 ) iLen = 4; do { uiMiddle = ( uiFirst + uiLast ) >> 1; iCmp = strncmp( szFuncCall, s_stdFunc[ uiMiddle ].cFuncName, iLen ); if( iCmp <= 0 ) uiLast = uiMiddle; else uiFirst = uiMiddle + 1; } while( uiFirst < uiLast ); if( uiFirst != uiMiddle ) iCmp = strncmp( szFuncCall, s_stdFunc[ uiFirst ].cFuncName, iLen ); if( iCmp == 0 ) { const HB_FUNCINFO * pFunc = &s_stdFunc[ uiFirst ]; if( ( pFunc->iMinParam != -1 && iArgs < pFunc->iMinParam ) || ( pFunc->iMaxParam != -1 && iArgs > pFunc->iMaxParam ) ) { char szMsg[ 64 ]; if( HB_COMP_ISSUPPORTED( HB_COMPFLAG_HARBOUR ) ) { if( pFunc->iMinParam == pFunc->iMaxParam ) hb_snprintf( szMsg, sizeof( szMsg ), "\nPassed: %i, expected: %i", iArgs, pFunc->iMinParam ); else if( pFunc->iMaxParam == -1 ) hb_snprintf( szMsg, sizeof( szMsg ), "\nPassed: %i, expected at least: %i", iArgs, pFunc->iMinParam ); else if( pFunc->iMinParam == -1 ) hb_snprintf( szMsg, sizeof( szMsg ), "\nPassed: %i, expected less than: %i", iArgs, pFunc->iMaxParam ); else hb_snprintf( szMsg, sizeof( szMsg ), "\nPassed: %i, expected from: %i to: %i", iArgs, pFunc->iMinParam, pFunc->iMaxParam ); } else szMsg[ 0 ] = '\0'; hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_CHECKING_ARGS, szFuncCall, szMsg ); return HB_FALSE; } } return HB_TRUE; }
void hb_compInitPP( HB_COMP_DECL, int argc, const char * const argv[], PHB_PP_OPEN_FUNC pOpenFunc ) { HB_TRACE( HB_TR_DEBUG, ( "hb_compInitPP()" ) ); if( HB_COMP_PARAM->pLex->pPP ) { hb_pp_init( HB_COMP_PARAM->pLex->pPP, HB_COMP_PARAM->fQuiet, HB_COMP_PARAM->iMaxTransCycles, HB_COMP_PARAM, pOpenFunc, NULL, hb_pp_ErrorGen, hb_pp_Disp, hb_pp_PragmaDump, HB_COMP_ISSUPPORTED( HB_COMPFLAG_HB_INLINE ) ? hb_pp_hb_inLine : NULL, hb_pp_CompilerSwitch ); if( HB_COMP_PARAM->iTraceInclude ) hb_pp_setIncFunc( HB_COMP_PARAM->pLex->pPP, hb_pp_fileIncluded ); if( ! HB_COMP_PARAM->szStdCh ) hb_pp_setStdRules( HB_COMP_PARAM->pLex->pPP ); else if( HB_COMP_PARAM->szStdCh[ 0 ] > ' ' ) hb_pp_readRules( HB_COMP_PARAM->pLex->pPP, HB_COMP_PARAM->szStdCh ); else if( ! HB_COMP_PARAM->fQuiet ) hb_compOutStd( HB_COMP_PARAM, "Standard command definitions excluded.\n" ); hb_pp_initDynDefines( HB_COMP_PARAM->pLex->pPP, ! HB_COMP_PARAM->fNoArchDefs ); /* Add /D and /undef: command line or envvar defines */ hb_compChkDefines( HB_COMP_PARAM, argc, argv ); /* add extended definitions files (-u+<file>) */ if( HB_COMP_PARAM->iStdChExt > 0 ) { int i = 0; while( i < HB_COMP_PARAM->iStdChExt ) hb_pp_readRules( HB_COMP_PARAM->pLex->pPP, HB_COMP_PARAM->szStdChExt[ i++ ] ); } /* mark current rules as standard ones */ hb_pp_setStdBase( HB_COMP_PARAM->pLex->pPP ); } }
/* Sets the argument of an operation found previously */ PHB_EXPR hb_compExprSetOperand( PHB_EXPR pExpr, PHB_EXPR pItem, HB_COMP_DECL ) { HB_BYTE ucRight; ucRight = s_PrecedTable[ pItem->ExprType ]; if( ucRight == HB_ET_NIL ) { /* the right side of an operator is an ordinary value * e.g. a := 1 */ pExpr->value.asOperator.pRight = pItem; } else if( ucRight == HB_ET_NONE ) { /* the right side of an operator is an invalid expression * e.g. * a := 1 + b:=2 * a := 1 + b += 2 */ if( pExpr->ExprType >= HB_EO_PLUSEQ && pExpr->ExprType <= HB_EO_EXPEQ ) { } else { HB_COMP_ERROR_SYNTAX( pItem ); } pExpr->value.asOperator.pRight = pItem; /* set it anyway */ } else { /* the right side of an operator is an expression with other operator * e.g. a := 2 + b * 3 * We have to set the proper order of evaluation using * precedence rules */ HB_BYTE ucLeft = s_PrecedTable[ pExpr->ExprType ]; if( ucLeft < ucRight || ( ucLeft == ucRight && HB_COMP_ISSUPPORTED( HB_COMPFLAG_SHORTCUTS ) && ( ucLeft == HB_EO_OR || ucLeft == HB_EO_AND ) ) ) { /* Left operator has a lower precedence then the right one * e.g. a + b * c * pItem -> b * c -> L=b R=c O=* * pExpr -> a + -> l=a r= o=+ * * -> a + (b * c) -> Left=a Right=(b * c) Oper=+ * Left := l * Right := L (O) R := pItem * Oper := o */ pExpr->value.asOperator.pRight = pItem; } else { /* Left operator has the same or higer precedence then the right one * e.g. a * b + c * pItem -> b + c -> L=b R=c O=+ * pExpr -> a * -> l=a r= o=* * * -> (a * b) + c -> Lelf=(a * b) Right=c Oper=+ * Left := l (o) L * Right := R * Oper := O */ pItem->value.asOperator.pLeft = hb_compExprSetOperand( pExpr, pItem->value.asOperator.pLeft, HB_COMP_PARAM ); pExpr = pItem; } } return pExpr; }
void hb_compCodeTraceMarkDead( HB_COMP_DECL, PHB_HFUNC pFunc ) { const PHB_CODETRACE_FUNC * pFuncTable = s_codeTraceFuncTable; HB_CODETRACE_INFO code_info; if( ! HB_COMP_ISSUPPORTED( HB_COMPFLAG_OPTJUMP ) || pFunc->nPCodePos < 2 ) return; assert( HB_P_LAST_PCODE == sizeof( s_codeTraceFuncTable ) / sizeof( PHB_CODETRACE_FUNC ) ); code_info.pnJumps = NULL; code_info.nJumpPos = 0; code_info.nJumpSize = 0; code_info.nJumpCount = 0; code_info.nPCodeSize = pFunc->nPCodePos; code_info.fFinished = HB_FALSE; code_info.pCodeMark = ( HB_BYTE * ) hb_xgrab( code_info.nPCodeSize ); memset( code_info.pCodeMark, 0, code_info.nPCodeSize ); hb_compPCodeTrace( pFunc, ( const PHB_PCODE_FUNC * ) pFuncTable, ( void * ) &code_info ); if( code_info.fFinished ) { HB_SIZE nPos = 0, nCount = 0; HB_BYTE bLastCode = HB_P_LAST_PCODE; do { if( code_info.pCodeMark[ nPos ] == 0 ) ++nCount; else { bLastCode = pFunc->pCode[ nPos ]; if( nCount ) { hb_compNOOPfill( pFunc, nPos - nCount, nCount, HB_FALSE, HB_TRUE ); nCount = 0; } } } while( ++nPos < code_info.nPCodeSize ); /* do not strip the last HB_P_ENDBLOCK / HB_P_ENDPROC marker */ if( nCount > 0 && bLastCode != ( pFunc->szName ? HB_P_ENDPROC : HB_P_ENDBLOCK ) ) { --nPos; --nCount; } if( nCount > 0 ) { /* * We cannot simply decrease size of the generated PCODE here * because jumps or noops tables may point to the this area * and we will have to update also the jump table, [druzus] */ /* pFunc->pCode[ nPos - nCount ] = pFunc->pCode[ nPos - 1 ]; pFunc->nPCodePos = pFunc->nPCodeSize = nPos - nCount + 1; */ hb_compNOOPfill( pFunc, nPos - nCount, nCount, HB_FALSE, HB_TRUE ); } } hb_xfree( code_info.pCodeMark ); if( code_info.pnJumps ) hb_xfree( code_info.pnJumps ); }