827 lines
29 KiB
C++
827 lines
29 KiB
C++
/******************************************************************************
|
|
* CFast_1.cpp : passage de l'ia en C, 1ère passe
|
|
* auteur : Fred "Bart" Compagnon
|
|
******************************************************************************/
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include <malloc.h>
|
|
|
|
#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 ; n<p_stOriginalNode->ucDepth ; 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 ; uwNodesCount<p_stCurrentRule->uwNbNode ; uwNodesCount++, p_stCurrentNode++)
|
|
if (bIsTheElseKeyWord(p_stCurrentNode))
|
|
uwNbTotalNode++;
|
|
}
|
|
else {
|
|
uwNbTotalNode = 0;
|
|
for (ucRulesCount = 0, p_stCurrentRule = p_stComport->p_stRules ; ucRulesCount<p_stComport->ucNbRules ; ucRulesCount++, p_stCurrentRule++) {
|
|
uwNbTotalNode += p_stCurrentRule->uwNbNode;
|
|
// to count the number of "Else"
|
|
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", 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 ; uwPseudoNodesCount<g_stFastTree.uwNbNode ; uwPseudoNodesCount++, p_stCurrentPseudoNode++) {
|
|
if (p_stCurrentPseudoNode->d_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 ; ucRulesCount<p_stComport->ucNbRules ; 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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|