/****************************************************************************** * CFast_1.cpp : passage de l'ia en C, 1ère passe * auteur : Fred "Bart" Compagnon ******************************************************************************/ #include "stdafx.h" #include #include "ai.h" #include "CFast_1.hpp" extern char CFast_IsAReference(tdstNodeInterpret *_pst_Node, int *pi_Indice); bool bGoToFatherNode ( tdstNodeInterpret** p_p_stNode ) ; CFast_tdstComportTree g_stFastTree; CFast_tdstNode* g_p_stPseudoNode; unsigned short g_uwNbMetaAction; // Nb de MetaAction unsigned short g_uwNbStopEngine; // Nb de BloquantMoteur tdstNodeInterpret* g_p_stIf2Node = NULL; // init, desinit #if defined (CFAST_DEBUG_FIRST_PASS) long g_lNbTotalDeNoeud; long g_lNbTotalDeNoeudToTest; FILE *g_fdCru = NULL ; void CFast_FirstPassOpening() { g_lNbTotalDeNoeud = 0; g_lNbTotalDeNoeudToTest = 0; g_fdCru = fopen ( "CFastRul.log", "w" ); } long lCFast_FirstPassClosing() { if ( g_fdCru != NULL ) { if (g_lNbTotalDeNoeudToTest == g_lNbTotalDeNoeud) fprintf ( g_fdCru, "\nTaille de l'IA : Nb Noeuds = %d / Taille de l'arbre = %d\n", g_lNbTotalDeNoeud, g_lNbTotalDeNoeud*sizeof(struct tdstNodeInterpret_) ); else fprintf ( g_fdCru, "\nERREUR : Nb Noeuds dans l'IA (%d) différent du Nb de Noeuds générés (%d)\n" , g_lNbTotalDeNoeudToTest, g_lNbTotalDeNoeud); fclose ( g_fdCru ) ; } return (g_lNbTotalDeNoeudToTest == g_lNbTotalDeNoeud)?g_lNbTotalDeNoeud:-1; } void OriginalNodeDescription(tdstNodeInterpret* p_stOriginalNode) { tdeTypeInterpret eType=M_GetTypeInterpret(p_stOriginalNode); //char sz128Temp[128]; if ( g_fdCru != NULL ) { if (eType == E_ti_KeyWord) fprintf ( g_fdCru, "KeyWord : %s", szFindKeyWordEditorNameFromId(M_eKeyWordIdInterpret(p_stOriginalNode))); else if (eType == E_ti_Condition) fprintf ( g_fdCru, "Condition : %s", szFindConditionEditorNameFromId(M_eCondIdInterpret(p_stOriginalNode))); else if (eType == E_ti_Operator) fprintf ( g_fdCru, "Operator : %s", szFindOperatorEditorNameFromId(M_eOperatorIdInterpret(p_stOriginalNode))); else if (eType == E_ti_Function) fprintf ( g_fdCru, "Function : %s", szFindFunctionEditorNameFromId(M_eFuncIdInterpret(p_stOriginalNode))); else if (eType == E_ti_Procedure) fprintf ( g_fdCru, "Procedure : %s", szFindProcedureEditorNameFromId(M_eProcedureIdInterpret(p_stOriginalNode))); else if (eType == E_ti_MetaAction) fprintf ( g_fdCru, "MetaAction : %s", szFindMetaActionEditorNameFromId(M_eMetaActionIdInterpret(p_stOriginalNode))); else if (eType == E_ti_Field) fprintf ( g_fdCru, "Field : %s", szFindFieldEditorNameFromId(M_eFieldIdInterpret(p_stOriginalNode))); else switch (eType) { case E_ti_DsgVar : fprintf ( g_fdCru, "DsgVar : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_DsgVarRef : fprintf ( g_fdCru, "DsgVarRef : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_PersoRef : fprintf ( g_fdCru, "PersoRef : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_ActionRef : fprintf ( g_fdCru, "ActionRef : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_SuperObjectRef : fprintf ( g_fdCru, "SuperObjectRef : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_WayPointRef : fprintf ( g_fdCru, "WayPointRef : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_ComportRef : fprintf ( g_fdCru, "ComportRef : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_ModuleRef : fprintf ( g_fdCru, "ModuleRef : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_ObjectTableRef : fprintf ( g_fdCru, "ObjectTableRef : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_GameMaterialRef : fprintf ( g_fdCru, "GameMaterialRef : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_ModelRef : fprintf ( g_fdCru, "ModelRef : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_MacroRef : fprintf ( g_fdCru, "MacroRef : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_EndTree : fprintf ( g_fdCru, "EndTree : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_Constant : fprintf ( g_fdCru, "Constant : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_Real : fprintf ( g_fdCru, "Real : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_Vector : fprintf ( g_fdCru, "Vector : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_Mask : fprintf ( g_fdCru, "Mask : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_Module : fprintf ( g_fdCru, "Module : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_Caps : fprintf ( g_fdCru, "Caps : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_Graph : fprintf ( g_fdCru, "Graph : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_BeginMacro : //strncpy(sz128Temp, M_GetSetParam_szString(p_stOriginalNode), 100); //sz128Temp[100] = 0; //fprintf ( g_fdCru, "BeginMacro : \"%s...\"", sz128Temp); fprintf ( g_fdCru, "BeginMacro : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; case E_ti_EndMacro : fprintf ( g_fdCru, "EndMacro : %d", M_GetSetParam_ulValue(p_stOriginalNode)); break; default : fprintf ( g_fdCru, "%d : %d", eType, M_GetSetParam_ulValue(p_stOriginalNode)); break; } } } void AddTabsForDepth(tdstNodeInterpret* p_stOriginalNode) { for (int n=0 ; nucDepth ; n++) fprintf ( g_fdCru, " "); } void PseudoNodeDescription(CFast_tdstNode* _p_stPseudoNode) { if ( g_fdCru != NULL ) { AddTabsForDepth(&(_p_stPseudoNode->stNode)); OriginalNodeDescription(&(_p_stPseudoNode->stNode)); if (_p_stPseudoNode->lIndexOfRef == -1) fprintf ( g_fdCru, " (%d)", _p_stPseudoNode->ucNumberOfParamNeeded); else fprintf ( g_fdCru, " [Ref:%d] (%d)", _p_stPseudoNode->lIndexOfRef, _p_stPseudoNode->ucNumberOfParamNeeded); if (_p_stPseudoNode->ucIndexOfEvalParam != 0) fprintf ( g_fdCru, " -> %d", _p_stPseudoNode->ucIndexOfEvalParam); if (_p_stPseudoNode->bAffectWithGetVector ) fprintf ( g_fdCru, " *", _p_stPseudoNode->ucIndexOfEvalParam); if (_p_stPseudoNode->bIsABooleanDsgVarRef) fprintf ( g_fdCru, " bool", _p_stPseudoNode->ucIndexOfEvalParam); if (M_GetTypeInterpret(&(g_p_stPseudoNode->stMiscellaneousNode)) != E_ti_Unknown){ fprintf ( g_fdCru, " => { "); OriginalNodeDescription(&(_p_stPseudoNode->stMiscellaneousNode)); fprintf ( g_fdCru, " }"); } if ( _p_stPseudoNode->bIsACondition ) { fprintf ( g_fdCru, " [condition]" ) ; } if ( _p_stPseudoNode->bIsATernOpParam ) { fprintf ( g_fdCru, "[ternop]" ) ; } fprintf ( g_fdCru, "\n"); fflush(g_fdCru); } } #endif //defined (CFAST_DEBUG_FIRST_PASS) bool bIsTheUltraOperator( tdstNodeInterpret* p_stNode ) { if ( (M_GetTypeInterpret(p_stNode) == E_ti_Operator) && (M_eOperatorIdInterpret(p_stNode) == eOperator_Ultra) ) return TRUE; return FALSE; } bool bIsTheDotOperator( tdstNodeInterpret* p_stNode ) { if ( (M_GetTypeInterpret(p_stNode) == E_ti_Operator) && (M_eOperatorIdInterpret(p_stNode) == eOperator_Dot) ) return TRUE; return FALSE; } bool bIsTheAffectOperator( tdstNodeInterpret* p_stNode ) { if ( (M_GetTypeInterpret(p_stNode) == E_ti_Operator) && (M_eOperatorIdInterpret(p_stNode) == eOperator_Affect) ) return TRUE; return FALSE; } bool bIsAnAffectOperator( tdstNodeInterpret* p_stNode ) { if ( (M_GetTypeInterpret(p_stNode) == E_ti_Operator) && ( (M_eOperatorIdInterpret(p_stNode) == eOperator_Affect) || (M_eOperatorIdInterpret(p_stNode) == eOperator_PlusAffect) || (M_eOperatorIdInterpret(p_stNode) == eOperator_MinusAffect) || (M_eOperatorIdInterpret(p_stNode) == eOperator_MulAffect) || (M_eOperatorIdInterpret(p_stNode) == eOperator_DivAffect) || (M_eOperatorIdInterpret(p_stNode) == eOperator_PlusPlusAffect) || (M_eOperatorIdInterpret(p_stNode) == eOperator_MinusMinusAffect) ) ) return TRUE; return FALSE; } bool bIsAGetVectorOperator( tdstNodeInterpret* p_stNode ) { if ( (M_GetTypeInterpret(p_stNode) == E_ti_Operator) && ( (M_eOperatorIdInterpret(p_stNode) == eOperator_GetVectorX) || (M_eOperatorIdInterpret(p_stNode) == eOperator_GetVectorY) || (M_eOperatorIdInterpret(p_stNode) == eOperator_GetVectorZ) ) ) return TRUE; return FALSE; } bool bIsAnIfKeyWord( tdstNodeInterpret* p_stNode ) { if (M_GetTypeInterpret(p_stNode) != E_ti_KeyWord) return FALSE; if ( (M_eKeyWordIdInterpret(p_stNode) == eKeyWord_If) || (M_eKeyWordIdInterpret(p_stNode) == eKeyWord_IfNot) || (M_eKeyWordIdInterpret(p_stNode) == eKeyWord_If2) || (M_eKeyWordIdInterpret(p_stNode) == eKeyWord_If4) || (M_eKeyWordIdInterpret(p_stNode) == eKeyWord_If8) || (M_eKeyWordIdInterpret(p_stNode) == eKeyWord_If16) ) return TRUE; return FALSE; } bool bIsTheElseKeyWord( tdstNodeInterpret* p_stNode ) { if ( (M_GetTypeInterpret(p_stNode) == E_ti_KeyWord) && (M_eKeyWordIdInterpret(p_stNode) == eKeyWord_Else) ) return TRUE; //jawaka : new keyword sidebug if ( (M_GetTypeInterpret(p_stNode) == E_ti_KeyWord) && (M_eKeyWordIdInterpret(p_stNode) == eKeyWord_IfDebug) ) return TRUE; if ( (M_GetTypeInterpret(p_stNode) == E_ti_KeyWord) && (M_eKeyWordIdInterpret(p_stNode) == eKeyWord_IfNotU64) ) return TRUE; return FALSE; } bool bIsTheThenKeyWord( tdstNodeInterpret* p_stNode ) { if ( (M_GetTypeInterpret(p_stNode) == E_ti_KeyWord) && (M_eKeyWordIdInterpret(p_stNode) == eKeyWord_Then) ) return TRUE; return FALSE; } bool bIsTheEndifKeyWord( tdstNodeInterpret* p_stNode ) { if ( (M_GetTypeInterpret(p_stNode) == E_ti_KeyWord) && (M_eKeyWordIdInterpret(p_stNode) == eKeyWord_Endif) ) return TRUE; return FALSE; } bool bIsABooleanCondition( tdstNodeInterpret* p_stNode ) { if (M_GetTypeInterpret(p_stNode) != E_ti_Condition) return FALSE; if ( (M_eCondIdInterpret(p_stNode) == eCond_Et) || (M_eCondIdInterpret(p_stNode) == eCond_Ou) || (M_eCondIdInterpret(p_stNode) == eCond_Not) || (M_eCondIdInterpret(p_stNode) == eCond_XOr) ) return TRUE; return FALSE; } bool bNeedBooleanParam( tdstNodeInterpret* p_stNode ) { if (bIsAnIfKeyWord(p_stNode)) return TRUE; if (bIsABooleanCondition(p_stNode)) return TRUE; /* if ( M_GetTypeInterpret(p_stNode) == E_ti_Function && M_eFuncIdInterpret(p_stNode) == eFunc_TernOp ) return TRUE ;*/ return FALSE; } bool bIsATernOpFunction (tdstNodeInterpret* p_stNode) { if ( (M_GetTypeInterpret(p_stNode) == E_ti_Function) && ( (M_eFuncIdInterpret(p_stNode) == eFunc_TernOp) || (M_eFuncIdInterpret(p_stNode) == eFunc_TernSup) || (M_eFuncIdInterpret(p_stNode) == eFunc_TernEq) || (M_eFuncIdInterpret(p_stNode) == eFunc_TernInfEq) || (M_eFuncIdInterpret(p_stNode) == eFunc_TernSupEq) ) ) return TRUE; return FALSE; } bool bCheckForTernOp ( tdstNodeInterpret* p_stNode ) { tdstNodeInterpret* p_stFatherNode ; if ( bIsATernOpFunction(p_stNode) ) return (TRUE) ; p_stFatherNode = p_stNode; while ( bGoToFatherNode(&p_stFatherNode) ) { if ( bIsATernOpFunction(p_stFatherNode) ) return ( TRUE ) ; } return (FALSE) ; } bool bCheckForCondition (tdstNodeInterpret* p_stNode ) { tdstNodeInterpret* p_stFatherNode ; if ( M_GetTypeInterpret(p_stNode) == E_ti_Condition ){ p_stFatherNode = p_stNode; bGoToFatherNode(&p_stFatherNode) ; if ( bIsTheUltraOperator(p_stFatherNode) ) bGoToFatherNode(&p_stFatherNode) ; if ( M_GetTypeInterpret(p_stFatherNode) != E_ti_Condition && (!bIsAnIfKeyWord(p_stFatherNode) ) ) return ( TRUE ) ; } return (FALSE) ; } CFast_tdstComportTree* CFast_FirstPassInitComport ( tdstComport* p_stComport ) { unsigned short uwNbTotalNode, uwNodesCount; unsigned char ucRulesCount; tdstTreeInterpret* p_stCurrentRule; tdstNodeInterpret* p_stCurrentNode; if (p_stComport->p_stSchedule != NULL) { p_stCurrentRule = p_stComport->p_stSchedule; uwNbTotalNode = p_stCurrentRule->uwNbNode; for (uwNodesCount = 0, p_stCurrentNode = p_stCurrentRule->p_stNodeInterpret ; uwNodesCountuwNbNode ; uwNodesCount++, p_stCurrentNode++) if (bIsTheElseKeyWord(p_stCurrentNode)) uwNbTotalNode++; } else { uwNbTotalNode = 0; for (ucRulesCount = 0, p_stCurrentRule = p_stComport->p_stRules ; ucRulesCountucNbRules ; ucRulesCount++, p_stCurrentRule++) { uwNbTotalNode += p_stCurrentRule->uwNbNode; // to count the number of "Else" for (uwNodesCount = 0, p_stCurrentNode = p_stCurrentRule->p_stNodeInterpret ; uwNodesCountuwNbNode ; uwNodesCount++, p_stCurrentNode++) if (bIsTheElseKeyWord(p_stCurrentNode)) uwNbTotalNode++; } } g_stFastTree.p_stCFastNode = NULL ; g_stFastTree.p_stCFastNode = (CFast_tdstNode*)malloc ( uwNbTotalNode * sizeof(struct CFast_tdstNode_) ) ; g_stFastTree.uwNbNode = uwNbTotalNode; g_stFastTree.d_cDeclarations = NULL; #if defined (CFAST_DEBUG_FIRST_PASS) g_lNbTotalDeNoeudToTest += uwNbTotalNode; if ( g_fdCru != NULL ) fprintf ( g_fdCru, "\n***** %s *****\n\n", M_GetNameComport(p_stComport)); #endif //defined (CFAST_DEBUG_FIRST_PASS) return (&g_stFastTree) ; } CFast_tdstComportTree* CFast_FirstPassInitSubr ( tdstMacro* p_stMacro ) { unsigned short uwNbTotalNode , uwNodesCount ; tdstTreeInterpret *p_stCurrentRule = p_stMacro->p_stInitTree ; tdstNodeInterpret* p_stCurrentNode; uwNbTotalNode = p_stCurrentRule->uwNbNode ; for ( uwNodesCount = 0, p_stCurrentNode = p_stCurrentRule->p_stNodeInterpret ; uwNodesCount < p_stCurrentRule->uwNbNode ; uwNodesCount ++ , p_stCurrentNode ++ ) if ( bIsTheElseKeyWord ( p_stCurrentNode ) ) uwNbTotalNode ++ ; g_stFastTree.p_stCFastNode = NULL ; g_stFastTree.p_stCFastNode = ( CFast_tdstNode * ) malloc ( uwNbTotalNode * sizeof(struct CFast_tdstNode_) ) ; g_stFastTree.uwNbNode = uwNbTotalNode; g_stFastTree.d_cDeclarations = NULL; #if defined (CFAST_DEBUG_FIRST_PASS) g_lNbTotalDeNoeudToTest += uwNbTotalNode; if ( g_fdCru != NULL ) fprintf ( g_fdCru, "\n***** %s *****\n\n", "Subroutine"); #endif //defined (CFAST_DEBUG_FIRST_PASS) return (&g_stFastTree) ; } void CFast_FirstPassDesinit () { if (g_stFastTree.p_stCFastNode != NULL) { CFast_tdstNode* p_stCurrentPseudoNode; unsigned short uwPseudoNodesCount; for (uwPseudoNodesCount = 0, p_stCurrentPseudoNode = g_stFastTree.p_stCFastNode ; uwPseudoNodesCountd_cOptimisedNode != NULL) free(p_stCurrentPseudoNode->d_cOptimisedNode); } free (g_stFastTree.p_stCFastNode) ; } g_stFastTree.p_stCFastNode = NULL ; if (g_stFastTree.d_cDeclarations != NULL) { free(g_stFastTree.d_cDeclarations); } #if defined (CFAST_DEBUG_FIRST_PASS) if ( g_fdCru != NULL ) fprintf ( g_fdCru, "\n############################################################\n\n" ); #endif //defined (CFAST_DEBUG_FIRST_PASS) } // nodes manipulation tdstNodeInterpret* NextNode (tdstNodeInterpret* p_stNode ) { return (p_stNode + 1); } tdstNodeInterpret* PrevNode (tdstNodeInterpret* p_stNode ) { return (p_stNode - 1); } bool bGoToNextParam ( tdstNodeInterpret** p_p_stNode ) { tdstNodeInterpret* p_stCurrentNode = *p_p_stNode; unsigned char ucNodeDepth = p_stCurrentNode->ucDepth; do { p_stCurrentNode = NextNode(p_stCurrentNode) ; //p_stCurrentNode++; } while (p_stCurrentNode->ucDepth > ucNodeDepth); *p_p_stNode = p_stCurrentNode; return (p_stCurrentNode->ucDepth == ucNodeDepth) ; } bool bGoToPrevParam ( tdstNodeInterpret** p_p_stNode ) { tdstNodeInterpret* p_stCurrentNode = *p_p_stNode; unsigned char ucNodeDepth = p_stCurrentNode->ucDepth; // careful : you must be sure not to be the first node of a tree (no test possible !) do { p_stCurrentNode = PrevNode(p_stCurrentNode) ; //p_stCurrentNode--; } while (p_stCurrentNode->ucDepth > ucNodeDepth); *p_p_stNode = p_stCurrentNode; return (p_stCurrentNode->ucDepth == ucNodeDepth) ; } bool bGoToFatherNode ( tdstNodeInterpret** p_p_stNode ) { tdstNodeInterpret* p_stCurrentNode = *p_p_stNode; unsigned char ucNodeDepth = p_stCurrentNode->ucDepth; if (ucNodeDepth == 0) return FALSE; // no father ! do { p_stCurrentNode = PrevNode(p_stCurrentNode) ; //p_stCurrentNode--; } while (p_stCurrentNode->ucDepth >= ucNodeDepth); *p_p_stNode = p_stCurrentNode; return (p_stCurrentNode->ucDepth == ucNodeDepth-1) ; } tdstNodeInterpret* p_stNeedInfoWithThisNode(tdstNodeInterpret* p_stFakeOrOriginalNode, tdstNodeInterpret* p_stOriginalNode) { tdstNodeInterpret* p_stNodeForInfo; // case 1 : 1st param of If2 if (g_p_stIf2Node != NULL) { p_stNodeForInfo = g_p_stIf2Node; g_p_stIf2Node = NULL; return p_stNodeForInfo; } if (bIsTheEndifKeyWord(p_stFakeOrOriginalNode)) { // case 2 : Then of If2, without Else if (bIsTheThenKeyWord(p_stOriginalNode)) { p_stNodeForInfo = p_stOriginalNode; if (bGoToNextParam(&p_stNodeForInfo)) { if (bIsTheElseKeyWord(p_stNodeForInfo)) return NULL; // Then is followed by Else => no info ! } p_stNodeForInfo = p_stOriginalNode; if (bGoToPrevParam(&p_stNodeForInfo)) // If { if (bIsAnIfKeyWord(p_stNodeForInfo)) return p_stNodeForInfo; } } // case 3 : Else of If2 if (bIsTheElseKeyWord(p_stOriginalNode)) { p_stNodeForInfo = p_stOriginalNode; if (bGoToPrevParam(&p_stNodeForInfo)) // Then { if (bGoToPrevParam(&p_stNodeForInfo)) // If { if (bIsAnIfKeyWord(p_stNodeForInfo)) return p_stNodeForInfo; } } } } // default : No info ! return NULL; } // node BOOL fn_bIsABooleanDsgVarRef(tdstNodeInterpret* p_stOriginalNode) { if ( M_GetTypeInterpret(p_stOriginalNode) == E_ti_Constant || M_GetTypeInterpret(p_stOriginalNode) == E_ti_Real || M_GetTypeInterpret(p_stOriginalNode) == E_ti_DsgVarRef || M_GetTypeInterpret(p_stOriginalNode) == E_ti_Field || ( M_GetTypeInterpret(p_stOriginalNode) == E_ti_Operator && M_eOperatorIdInterpret(p_stOriginalNode) == eOperator_Dot ) || M_GetTypeInterpret(p_stOriginalNode) == E_ti_Function ) { tdstNodeInterpret* p_stTempNode = p_stOriginalNode; if (bGoToFatherNode(&p_stTempNode)) { if ( bNeedBooleanParam(p_stTempNode) ) { return TRUE; } } } return FALSE; } void CFast_FillOneNode( tdstNodeInterpret* p_stFakeOrOriginalNode, tdstNodeInterpret* p_stOriginalNode, unsigned char _ucIndexOfEvalParam, unsigned char _ucNumberOfParamNeeded, BOOL _bAffectWithGetVector) { // à revoir car certainement plusieurs nodes à copier ... int iIndice; memcpy(&g_p_stPseudoNode->stNode, p_stFakeOrOriginalNode, sizeof(struct tdstNodeInterpret_) ); tdstNodeInterpret* p_stNodeForInfo = p_stNeedInfoWithThisNode(p_stFakeOrOriginalNode, p_stOriginalNode); if (p_stNodeForInfo == NULL) { memset(&g_p_stPseudoNode->stMiscellaneousNode, 0, sizeof(struct tdstNodeInterpret_) ); M_SetTypeInterpret(&(g_p_stPseudoNode->stMiscellaneousNode), E_ti_Unknown); } else memcpy(&g_p_stPseudoNode->stMiscellaneousNode, p_stNodeForInfo, sizeof(struct tdstNodeInterpret_) ); g_p_stPseudoNode->ucIndexOfEvalParam = _ucIndexOfEvalParam; g_p_stPseudoNode->ucNumberOfParamNeeded = _ucNumberOfParamNeeded; g_p_stPseudoNode->bAffectWithGetVector = _bAffectWithGetVector; g_p_stPseudoNode->bIsABooleanDsgVarRef = fn_bIsABooleanDsgVarRef(p_stOriginalNode); // FROM two past two TO two to two g_p_stPseudoNode->bIsACondition = bCheckForCondition(p_stOriginalNode) ; g_p_stPseudoNode->bIsATernOpParam = bCheckForTernOp(p_stOriginalNode) ; g_p_stPseudoNode->d_cOptimisedNode = NULL; g_p_stPseudoNode->ucNumberOfNodeToSkipAfterOptimisation = 0; if (CFast_IsAReference(p_stFakeOrOriginalNode, &iIndice)) { g_p_stPseudoNode->lIndexOfRef = (long)iIndice; } else { g_p_stPseudoNode->lIndexOfRef = -1L; } #if defined (CFAST_DEBUG_FIRST_PASS) PseudoNodeDescription(g_p_stPseudoNode); g_lNbTotalDeNoeud++; #endif //defined (CFAST_DEBUG_FIRST_PASS) g_p_stPseudoNode++; } // misc tests on nodes bool bToBeMemorised ( tdstNodeInterpret* p_stNode ) { if (bIsTheUltraOperator(p_stNode)) // bicose on teste plutot le retour de la fonction ultraable p_stNode = NextNode(NextNode(p_stNode)); //p_stNode += 2; switch (M_GetTypeInterpret(p_stNode)) { case E_ti_DsgVarRef: if (fn_bIsABooleanDsgVarRef(p_stNode)) return TRUE; else return FALSE; break; case E_ti_KeyWord: if (szGetKeyWordTypeOutParamFromId(M_eKeyWordIdInterpret(p_stNode))[0] == 0) // USE_NO_PARAM return FALSE; else return TRUE; break; case E_ti_Operator: if (M_eOperatorIdInterpret(p_stNode) == eOperator_ModelCast) return FALSE; // a la demande de JMD ! if (szGetOperatorTypeOutParamFromId(M_eOperatorIdInterpret(p_stNode))[0] == 0) // USE_NO_PARAM return FALSE; else return TRUE; break; case E_ti_Function: case E_ti_Condition: case E_ti_Vector: return TRUE; break; default: return FALSE; } } bool bToBeEvalued ( tdstNodeInterpret* p_stNode ) { if (NextNode(p_stNode)->ucDepth > p_stNode->ucDepth) // at least one param (because next node has deeper depth) return TRUE; else return FALSE; } bool bIsTheEndingNode( tdstNodeInterpret* p_stNode ) { if (M_GetTypeInterpret(p_stNode) == E_ti_EndTree) return TRUE; return FALSE; } // special nodes tdstNodeInterpret* p_stNode_TreatSpecialNodes(tdstNodeInterpret* p_stOriginalNode, BOOL* p_bSkipFirstParam, BOOL* p_bAffectWithGetVector) { tdstNodeInterpret* p_stFirstParamNode; tdstNodeInterpret* p_stFakeNode=NULL; *p_bSkipFirstParam = FALSE; *p_bAffectWithGetVector = FALSE; //MAJ des compteurs if (M_GetTypeInterpret(p_stOriginalNode) == E_ti_MetaAction) g_uwNbMetaAction++; else if ( (M_GetTypeInterpret(p_stOriginalNode) == E_ti_Procedure) && (M_eProcedureIdInterpret(p_stOriginalNode) == eProc_SetActionReturn) ) g_uwNbStopEngine++; /* special nodes */ if (bIsAnIfKeyWord(p_stOriginalNode)) g_p_stIf2Node = p_stOriginalNode; // ELSE if (bIsTheElseKeyWord(p_stOriginalNode)) //eKeyWord_Else CFast_FillOneNode(p_stOriginalNode, p_stOriginalNode, 0, 0, FALSE); // ELSE or THEN if (bIsTheElseKeyWord(p_stOriginalNode) || bIsTheThenKeyWord(p_stOriginalNode)) { p_stFakeNode = (tdstNodeInterpret*)malloc ( sizeof(struct tdstNodeInterpret_) ) ; memcpy(p_stFakeNode, p_stOriginalNode, sizeof(struct tdstNodeInterpret_) ); M_eKeyWordIdInterpret(p_stFakeNode) = eKeyWord_Endif; // because "Endif" is the end of an "If" (or an "Else") } // AFFECT with .X .Y or .Z else if ( bIsAnAffectOperator(p_stOriginalNode) ) { p_stFirstParamNode = NextNode(p_stOriginalNode); // the param to be changed if ( bIsAGetVectorOperator(p_stFirstParamNode) ) { if ( bIsTheAffectOperator(p_stOriginalNode) ) // for the real AFFECT operator (:=) it is better to change the node ! { p_stFakeNode = (tdstNodeInterpret*)malloc ( sizeof(struct tdstNodeInterpret_) ) ; memcpy(p_stFakeNode, p_stOriginalNode, sizeof(struct tdstNodeInterpret_) ); //M_SetTypeInterpret(p_stFakeNode, E_ti_Operator); switch (M_eOperatorIdInterpret(p_stFirstParamNode)) { case eOperator_GetVectorX: M_eOperatorIdInterpret(p_stFakeNode) = eOperator_SetVectorX; break; case eOperator_GetVectorY: M_eOperatorIdInterpret(p_stFakeNode) = eOperator_SetVectorY; break; case eOperator_GetVectorZ: M_eOperatorIdInterpret(p_stFakeNode) = eOperator_SetVectorZ; break; } *p_bSkipFirstParam = TRUE; } else { *p_bAffectWithGetVector = TRUE; } } } if (*p_bSkipFirstParam) { g_stFastTree.uwNbNode--; #if defined (CFAST_DEBUG_FIRST_PASS) g_lNbTotalDeNoeudToTest--; #endif //defined (CFAST_DEBUG_FIRST_PASS) } if (p_stFakeNode!=NULL) return p_stFakeNode; else return p_stOriginalNode; } // main fct (recursive) void CFast_TreatOneDepthRecursively(tdstNodeInterpret* p_stOriginalNode, unsigned char _ucParamIndex, BOOL _bEvaluatingUltra, BOOL _bGetVectorVariableForAffect) ; void CFast_TreatOneDepthRecursively(tdstNodeInterpret* p_stOriginalNode, unsigned char _ucParamIndex, BOOL _bEvaluatingUltra, BOOL _bGetVectorVariableForAffect) { unsigned char ucNumberOfParamNeeded; tdstNodeInterpret* p_stFakeOrOriginalNode; tdstNodeInterpret* p_stCurrentParamNode; tdstNodeInterpret* p_stParamNodeToTreat; unsigned char ucIndexOfParam; BOOL bStillOneParamToTreat; BOOL bShiftNodeForFirstParam=FALSE; BOOL bAffectWithGetVector=FALSE; tdstNodeInterpret* p_stUltraNode=NULL; // != NULL if fct w/ Ultra if ( (!_bEvaluatingUltra) && (bIsTheUltraOperator(p_stOriginalNode)) ) { p_stUltraNode = p_stOriginalNode; p_stOriginalNode = NextNode(NextNode(p_stOriginalNode)); } p_stFakeOrOriginalNode = p_stNode_TreatSpecialNodes(p_stOriginalNode, &bShiftNodeForFirstParam, &bAffectWithGetVector); ucNumberOfParamNeeded = 0; //ucIndexOfParam = (_ucParamIndex==0)? 1:_ucParamIndex; ucIndexOfParam = _ucParamIndex; if (bToBeEvalued(p_stOriginalNode)) { // it has some params ? p_stCurrentParamNode = NextNode(p_stOriginalNode) ; // the first param in the list do { ucNumberOfParamNeeded++; if (bShiftNodeForFirstParam) { p_stParamNodeToTreat = NextNode(p_stCurrentParamNode); bShiftNodeForFirstParam = FALSE; } else p_stParamNodeToTreat = p_stCurrentParamNode; if ((!bAffectWithGetVector) && (bToBeMemorised(p_stParamNodeToTreat))) { CFast_TreatOneDepthRecursively( p_stParamNodeToTreat, ucIndexOfParam+1, FALSE, FALSE); ucIndexOfParam++; } else CFast_TreatOneDepthRecursively( p_stParamNodeToTreat, 0, FALSE, bAffectWithGetVector); bAffectWithGetVector = FALSE; bStillOneParamToTreat = bGoToNextParam(&p_stCurrentParamNode); } while ( (!_bEvaluatingUltra) && (bStillOneParamToTreat) ); } if (p_stUltraNode) { // has ULTRA (we add the ULTRA as a new param of the fct) ucNumberOfParamNeeded++; CFast_TreatOneDepthRecursively( p_stUltraNode, ucIndexOfParam, TRUE, FALSE); // EvaluatingUltra } if ( _bEvaluatingUltra ) CFast_FillOneNode(p_stFakeOrOriginalNode, p_stOriginalNode, 0, ucNumberOfParamNeeded, FALSE); else CFast_FillOneNode(p_stFakeOrOriginalNode, p_stOriginalNode, _ucParamIndex, ucNumberOfParamNeeded, _bGetVectorVariableForAffect); // desallocation éventuelle : if (p_stFakeOrOriginalNode != p_stOriginalNode) free (p_stFakeOrOriginalNode); } CFast_tdstNode* CFast_FillTreeWithOneRule(CFast_tdstNode* p_stPseudoNode, tdstNodeInterpret* p_stOriginalNode) { tdstNodeInterpret* p_stCurrentNode = p_stOriginalNode; g_p_stPseudoNode = p_stPseudoNode; BOOL bOk = TRUE; while ( (!bIsTheEndingNode(p_stCurrentNode)) && bOk ) { CFast_TreatOneDepthRecursively(p_stCurrentNode, bToBeMemorised(p_stCurrentNode)? 1:0, FALSE, FALSE); bOk = bGoToNextParam(&p_stCurrentNode); } if (bIsTheEndingNode(p_stCurrentNode)) CFast_FillOneNode(p_stCurrentNode, p_stCurrentNode, 0 ,0, FALSE); return (g_p_stPseudoNode); } void CFast_FirstPassFillTreeComport ( CFast_tdstComportTree* p_stFastTree, tdstComport* p_stComport ) { unsigned char ucRulesCount; tdstTreeInterpret* p_stCurrentRule; CFast_tdstNode* p_stCurrentPseudoNode; // init special nodes g_uwNbMetaAction = 0; g_uwNbStopEngine = 0; p_stCurrentPseudoNode = p_stFastTree->p_stCFastNode; if (p_stComport->p_stSchedule != NULL) p_stCurrentPseudoNode = CFast_FillTreeWithOneRule(p_stCurrentPseudoNode, (p_stComport->p_stSchedule)->p_stNodeInterpret); else { for (ucRulesCount = 0, p_stCurrentRule = p_stComport->p_stRules ; ucRulesCountucNbRules ; ucRulesCount++, p_stCurrentRule++) { #if defined (CFAST_DEBUG_FIRST_PASS) if ( g_fdCru != NULL ) fprintf ( g_fdCru, "\n* Rule No %d *\n", ucRulesCount); #endif //defined (CFAST_DEBUG_FIRST_PASS) p_stCurrentPseudoNode = CFast_FillTreeWithOneRule(p_stCurrentPseudoNode, p_stCurrentRule->p_stNodeInterpret); } } // report special nodes p_stFastTree->uwNbMetaAction = g_uwNbMetaAction; p_stFastTree->uwNbStopEngine = g_uwNbStopEngine; } void CFast_FirstPassFillTreeSubr ( CFast_tdstComportTree* p_stFastTree, tdstMacro* p_stMacro ) { CFast_tdstNode* p_stCurrentPseudoNode; // init special nodes g_uwNbMetaAction = 0; g_uwNbStopEngine = 0; p_stCurrentPseudoNode = p_stFastTree->p_stCFastNode; p_stCurrentPseudoNode = CFast_FillTreeWithOneRule(p_stCurrentPseudoNode, p_stMacro->p_stInitTree->p_stNodeInterpret ) ; // report special nodes p_stFastTree->uwNbMetaAction = g_uwNbMetaAction; p_stFastTree->uwNbStopEngine = g_uwNbStopEngine; }