void CBotIf :: RestoreState(CBotStack* &pj, BOOL bMain) { if ( !bMain ) return; CBotStack* pile = pj->RestoreStack(this); // ajoute un élément à la pile if ( pile == NULL ) return; // selon la reprise, on peut être dans l'un des 2 états if( pile->GivState() == 0 ) { // évalue la condition m_Condition->RestoreState(pile, bMain); // interrompu ici ! return; } // second état, évalue les instructions associées // le résultat de la condition est sur la pile if ( pile->GivVal() == TRUE ) // condition était vraie ? { if ( m_Block != NULL ) // bloc peut être absent m_Block->RestoreState(pile, bMain); // interrompu ici ! } else { if ( m_BlockElse != NULL ) // s'il existe un bloc alternatif m_BlockElse->RestoreState(pile, bMain); // interrompu ici ! } }
void CBotListExpression::RestoreState(CBotStack* &pj, bool bMain) { CBotStack* pile = pj; int state = 0x7000; if ( bMain ) { pile = pj->RestoreStack(); if ( pile == nullptr ) return; state = pile->GetState(); } CBotInstr* p = m_Expr; // the first expression while (p != nullptr && state-->0) { p->RestoreState(pile, false); p = p->GetNext(); // returns to the interrupted operation } if ( p != nullptr ) { p->RestoreState(pile, bMain); } }
void CBotIf :: RestoreState(CBotStack* &pj, bool bMain) { if ( !bMain ) return; CBotStack* pile = pj->RestoreStack(this); // adds an item to the stack if ( pile == nullptr ) return; // according to recovery, it may be in one of two states if( pile->GetState() == 0 ) { // evaluates the condition m_condition->RestoreState(pile, bMain); // interrupted here! return; } // second state, evaluates the associated instructions // the result of the condition is on the stack if ( pile->GetVal() == true ) // condition was true? { if (m_block != nullptr ) // block may be absent m_block->RestoreState(pile, bMain); // interrupted here! } else { if (m_blockElse != nullptr ) // if there is an alternate block m_blockElse->RestoreState(pile, bMain); // interrupted here! } }
bool CBotExprLitNum::Execute(CBotStack* &pj) { CBotStack* pile = pj->AddStack(this); if (pile->IfStep()) return false; CBotVar* var = CBotVar::Create("", m_numtype); std::string nombre ; if (m_token.GetType() == TokenTypDef) { nombre = m_token.GetString(); } switch (m_numtype) { case CBotTypShort: case CBotTypInt: var->SetValInt(m_valint, nombre); break; case CBotTypFloat: var->SetValFloat(m_valfloat); break; default: assert(false); } pile->SetVar(var); // place on the stack return pj->Return(pile); // it's ok }
void CBotInstrCall::RestoreState(CBotStack* &pj, bool bMain) { if ( !bMain ) return; CBotStack* pile = pj->RestoreStack(this); if ( pile == NULL ) return; // CBotStack* pile1 = pile; int i = 0; CBotVar* ppVars[1000]; CBotInstr* p = m_Parameters; // evaluate parameters // and place the values on the stack // for allow of interruption at any time if ( p != NULL) while ( true ) { pile = pile->RestoreStack(); // place on the stack for the results if ( pile == NULL ) return; if ( pile->GetState() == 0 ) { p->RestoreState(pile, bMain); // interrupt here! return; } ppVars[i++] = pile->GetVar(); // constructs the list of parameters p = p->GetNext(); if ( p == NULL) break; } ppVars[i] = NULL; CBotStack* pile2 = pile->RestoreStack(); if ( pile2 == NULL ) return; pile2->RestoreCall(m_nFuncIdent, GetToken(), ppVars); }
bool CBotBreak :: Execute(CBotStack* &pj) { CBotStack* pile = pj->AddStack(this); // if ( pile == EOX ) return true; if ( pile->IfStep() ) return false; pile->SetBreak(m_token.GetType()==ID_BREAK ? 1 : 2, m_label); return pj->Return(pile); }
void CBotExprRetVar::RestoreState(CBotStack* &pj, bool bMain) { if (!bMain) return; CBotStack* pile = pj->RestoreStack(); if ( pile == nullptr ) return; if (pile->GetState() == 0) m_next3->RestoreStateVar(pile, bMain); }
void CBotReturn::RestoreState(CBotStack* &pj, bool bMain) { if ( !bMain ) return; CBotStack* pile = pj->RestoreStack(this); if ( pile == NULL ) return; if ( pile->GetState() == 0 ) { if ( m_Instr != NULL ) m_Instr->RestoreState(pile, bMain); // evaluate the result return; } }
void CBotThrow :: RestoreState(CBotStack* &pj, bool bMain) { if ( !bMain ) return; CBotStack* pile = pj->RestoreStack(this); if ( pile == nullptr ) return; if ( pile->GetState() == 0 ) { m_Value->RestoreState(pile, bMain); return; } }
bool CBotFunction::Execute(CBotVar** ppVars, CBotStack* &pj, CBotVar* pInstance) { CBotStack* pile = pj->AddStack(this, 2); // one end of stack local to this function // if ( pile == EOX ) return true; pile->SetBotCall(m_pProg); // bases for routines if ( pile->GetState() == 0 ) { if ( !m_Param->Execute(ppVars, pile) ) return false; // define parameters pile->IncState(); } if ( pile->GetState() == 1 && !m_MasterClass.IsEmpty() ) { // makes "this" known CBotVar* pThis ; if ( pInstance == NULL ) { pThis = CBotVar::Create("this", CBotTypResult( CBotTypClass, m_MasterClass )); pThis->SetInit(2); } else { pThis = CBotVar::Create("this", CBotTypResult( CBotTypPointer, m_MasterClass )); pThis->SetPointer(pInstance); pThis->SetInit(2); } // pThis->SetUniqNum(m_nThisIdent); pThis->SetUniqNum(-2); pile->AddVar(pThis); pile->IncState(); } if ( pile->IfStep() ) return false; if ( !m_Block->Execute(pile) ) { if ( pile->GetError() < 0 ) pile->SetError( 0 ); else return false; } return pj->Return(pile); }
void CBotListArray::RestoreState(CBotStack* &pj, bool bMain) { if (bMain) { CBotStack* pile = pj->RestoreStack(this); if (pile == nullptr) return; CBotInstr* p = m_expr; int state = pile->GetState(); while(state-- > 0) p = p->GetNext3b() ; p->RestoreState(pile, bMain); // size calculation //interrupted! } }
bool CBotListExpression::Execute(CBotStack* &pj) { CBotStack* pile = pj->AddStack(); // essential CBotInstr* p = m_Expr; // the first expression int state = pile->GetState(); while (state-->0) p = p->GetNext(); // returns to the interrupted operation if ( p != nullptr ) while (true) { if ( !p->Execute(pile) ) return false; p = p->GetNext(); if ( p == nullptr ) break; if (!pile->IncState()) return false; // ready for next } return pj->Return(pile); }
bool CBotReturn::Execute(CBotStack* &pj) { CBotStack* pile = pj->AddStack(this); // if ( pile == EOX ) return true; if ( pile->GetState() == 0 ) { if ( m_Instr != NULL && !m_Instr->Execute(pile) ) return false; // evaluate the result // the result is on the stack pile->IncState(); } if ( pile->IfStep() ) return false; pile->SetBreak(3, CBotString()); return pj->Return(pile); }
void CBotFunction::RestoreState(CBotVar** ppVars, CBotStack* &pj, CBotVar* pInstance) { CBotStack* pile = pj->RestoreStack(this); // one end of stack local to this function if ( pile == NULL ) return; CBotStack* pile2 = pile; pile->SetBotCall(m_pProg); // bases for routines if ( pile->GetBlock() < 2 ) { CBotStack* pile2 = pile->RestoreStack(NULL); // one end of stack local to this function if ( pile2 == NULL ) return; pile->SetState(pile->GetState() + pile2->GetState()); pile2->Delete(); } m_Param->RestoreState(pile2, true); // parameters if ( !m_MasterClass.IsEmpty() ) { CBotVar* pThis = pile->FindVar("this"); pThis->SetInit(2); pThis->SetUniqNum(-2); } m_Block->RestoreState(pile2, true); }
bool CBotInstrCall::Execute(CBotStack* &pj) { CBotVar* ppVars[1000]; CBotStack* pile = pj->AddStack(this); if ( pile->StackOver() ) return pj->Return( pile ); // CBotStack* pile1 = pile; int i = 0; CBotInstr* p = m_Parameters; // evaluates parameters // and places the values on the stack // for allow of interruption at any time if ( p != NULL) while ( true ) { pile = pile->AddStack(); // place on the stack for the results if ( pile->GetState() == 0 ) { if (!p->Execute(pile)) return false; // interrupted here? pile->SetState(1); // mark as special for reknowed parameters \TODO marque spéciale pour reconnaîre parameters } ppVars[i++] = pile->GetVar(); p = p->GetNext(); if ( p == NULL) break; } ppVars[i] = NULL; CBotStack* pile2 = pile->AddStack(); if ( pile2->IfStep() ) return false; if ( !pile2->ExecuteCall(m_nFuncIdent, GetToken(), ppVars, m_typRes)) return false; // interrupt return pj->Return(pile2); // release the entire stack }
void CBotListInstr::RestoreState(CBotStack* &pj, bool bMain) { if (!bMain) return; CBotStack* pile = pj->RestoreStack(this); if (pile == nullptr) return; CBotInstr* p = m_instr; // the first expression int state = pile->GetState(); while ( p != nullptr && state-- > 0) { p->RestoreState(pile, false); p = p->GetNext(); // returns to the interrupted operation } if (p != nullptr) p->RestoreState(pile, true); }
bool CBotInstrCall::Execute(CBotStack* &pj) { CBotVar* ppVars[1000]; CBotStack* pile = pj->AddStack(this); if ( pile->StackOver() ) return pj->Return( pile ); CBotStack* pile3 = nullptr; if (m_exprRetVar != nullptr) // func().member { pile3 = pile->AddStack2(); if (pile3->GetState() == 1) // function call is done? { if (!m_exprRetVar->Execute(pile3)) return false; return pj->Return(pile3); } } // CBotStack* pile1 = pile; int i = 0; CBotInstr* p = m_parameters; // evaluates parameters // and places the values on the stack // for allow of interruption at any time if ( p != nullptr) while ( true ) { pile = pile->AddStack(); // place on the stack for the results if ( pile->GetState() == 0 ) { if (!p->Execute(pile)) return false; // interrupted here? pile->SetState(1); // set state to remember that parameters were executed } ppVars[i++] = pile->GetVar(); p = p->GetNext(); if ( p == nullptr) break; } ppVars[i] = nullptr; CBotStack* pile2 = pile->AddStack(); if ( pile2->IfStep() ) return false; if ( !pile2->ExecuteCall(m_nFuncIdent, GetToken(), ppVars, m_typRes)) return false; // interrupt if (m_exprRetVar != nullptr) // func().member { pile3->SetCopyVar( pile2->GetVar() ); // copy the result pile2->SetVar(nullptr); pile3->SetState(1); // set call is done return false; // go back to the top ^^^ } return pj->Return(pile2); // release the entire stack }
void CBotWhile::RestoreState(CBotStack* &pj, bool bMain) { if ( !bMain ) return; CBotStack* pile = pj->RestoreStack(this); // adds an item to the stack if ( pile == nullptr ) return; switch( pile->GetState() ) { // there are two possible states (depending on recovery) case 0: // evaluates the condition m_condition->RestoreState(pile, bMain); return; case 1: // evaluates the associated statement block if (m_block != nullptr ) m_block->RestoreState(pile, bMain); return; } }
bool CBotWhile::Execute(CBotStack* &pj) { CBotStack* pile = pj->AddStack(this); // adds an item to the stack // or find in case of recovery // if ( pile == EOX ) return true; if ( pile->IfStep() ) return false; while( true ) switch( pile->GetState() ) // executes the loop { // there are two possible states (depending on recovery) case 0: // evaluates the condition if ( !m_condition->Execute(pile) ) return false; // interrupted here? // the result of the condition is on the stack // terminates if an error or if the condition is false if ( !pile->IsOk() || pile->GetVal() != true ) { return pj->Return(pile); // sends the results and releases the stack } // the condition is true, pass in the second mode if (!pile->SetState(1)) return false; // ready for further case 1: // evaluates the associated statement block if (m_block != nullptr && !m_block->Execute(pile) ) { if (pile->IfContinue(0, m_label)) continue; // if continued, will return to test return pj->BreakReturn(pile, m_label); // sends the results and releases the stack } // terminates if there is an error if ( !pile->IsOk() ) { return pj->Return(pile); // sends the results and releases the stack } // returns to the test again if (!pile->SetState(0, 0)) return false; continue; } }
bool CBotLeftExpr::Execute(CBotStack* &pj, CBotStack* array) { CBotStack* pile = pj->AddStack(); CBotVar* var1 = nullptr; CBotVar* var2 = nullptr; // fetch a variable (not copy) if (!ExecuteVar(var1, array, nullptr, false)) return false; if (pile->IfStep()) return false; if (var1) { var2 = pj->GetVar(); // result on the input stack if (var2) { CBotTypResult t1 = var1->GetTypResult(); CBotTypResult t2 = var2->GetTypResult(); if (t2.Eq(CBotTypPointer)) { CBotClass* c1 = t1.GetClass(); CBotClass* c2 = var2->GetClass(); if ( !c2->IsChildOf(c1)) { CBotToken* pt = &m_token; pile->SetError(CBotErrBadType1, pt); return pj->Return(pile); // operation performed } var1->SetVal(var2); // set pointer var1->SetType(t1); // keep pointer type } else var1->SetVal(var2); // do assignment } pile->SetCopyVar(var1); // replace the stack with the copy of the variable // (for name) } return pj->Return(pile); // operation performed }
void CBotFunction::RestoreCall(long& nIdent, const char* name, CBotVar* pThis, CBotVar** ppVars, CBotStack* pStack, CBotClass* pClass) { CBotTypResult type; CBotFunction* pt = FindLocalOrPublic(nIdent, name, ppVars, type); if ( pt != NULL ) { CBotStack* pStk = pStack->RestoreStack(pt); if ( pStk == NULL ) return; pStk->SetBotCall(pt->m_pProg); // it may have changed module CBotVar* pthis = pStk->FindVar("this"); pthis->SetUniqNum(-2); CBotStack* pStk3 = pStk->RestoreStack(NULL); // to set parameters passed if ( pStk3 == NULL ) return; pt->m_Param->RestoreState(pStk3, true); // parameters if ( pStk->GetState() > 1 && // latching is effective? pt->m_bSynchro ) { CBotProgram* pProgBase = pStk->GetBotCall(true); pClass->Lock(pProgBase); // locks the class } // finally calls the found function pt->m_Block->RestoreState(pStk3, true); // interrupt ! } }
void CBotDefArray::RestoreState(CBotStack* &pj, bool bMain) { CBotStack* pile1 = pj; CBotVar* var = pj->FindVar(m_var->GetToken()->GetString()); if (var != nullptr) var->SetUniqNum((static_cast<CBotLeftExprVar*>(m_var))->m_nIdent); if (bMain) { pile1 = pj->RestoreStack(this); CBotStack* pile = pile1; if (pile == nullptr) return; if (pile1->GetState() == 0) { // seek the maximum dimension of the table CBotInstr* p = GetNext3b(); while (p != nullptr) { pile = pile->RestoreStack(); if (pile == nullptr) return; if (pile->GetState() == 0) { p->RestoreState(pile, bMain); return; } p = p->GetNext3b(); } } if (pile1->GetState() == 1 && m_listass != nullptr) { m_listass->RestoreState(pile1, bMain); } } if (m_next2b ) m_next2b->RestoreState( pile1, bMain); }
bool CBotListInstr::Execute(CBotStack* &pj) { CBotStack* pile = pj->AddStack(this, CBotStack::BlockVisibilityType::BLOCK); //needed for SetState() if (pile->StackOver() ) return pj->Return( pile); CBotInstr* p = m_instr; // the first expression int state = pile->GetState(); while (state-->0) p = p->GetNext(); // returns to the interrupted operation if (p != nullptr) while (true) { if (!p->Execute(pile)) return false; p = p->GetNext(); if (p == nullptr) break; (void)pile->IncState(); // ready for next } return pj->Return(pile); }
void CBotFor :: RestoreState(CBotStack* &pj, bool bMain) { if ( !bMain ) return; CBotStack* pile = pj->RestoreStack(this); // adds an item to the stack (variables locales) if ( pile == nullptr ) return; switch( pile->GetState() ) { // there are four possible states (depending on recovery) case 0: // initialize if ( m_Init != nullptr ) m_Init->RestoreState(pile, true); // interrupted here ! return; case 1: if ( m_Init != nullptr ) m_Init->RestoreState(pile, false); // variables definitions // evaluates the condition if ( m_Test != nullptr ) m_Test->RestoreState(pile, true); // interrupted here ! return; case 2: if ( m_Init != nullptr ) m_Init->RestoreState(pile, false); // variable definitions // evaluates the associated statement block if ( m_Block != nullptr ) m_Block->RestoreState(pile, true); return; case 3: if ( m_Init != nullptr ) m_Init->RestoreState(pile, false); // variable definitions // evaluate the incrementation if ( m_Incr != nullptr ) m_Incr->RestoreState(pile, true); // interrupted here ! return; } }
void CBotInstrCall::RestoreState(CBotStack* &pj, bool bMain) { if ( !bMain ) return; CBotStack* pile = pj->RestoreStack(this); if ( pile == nullptr ) return; if (m_exprRetVar != nullptr) // func().member { CBotStack* pile3 = pile->AddStack2(); if (pile3->GetState() == 1) // function call is done? { m_exprRetVar->RestoreState(pile3, bMain); return; } } // CBotStack* pile1 = pile; int i = 0; CBotVar* ppVars[1000]; CBotInstr* p = m_parameters; // evaluate parameters // and place the values on the stack // for allow of interruption at any time if ( p != nullptr) while ( true ) { pile = pile->RestoreStack(); // place on the stack for the results if ( pile == nullptr ) return; if ( pile->GetState() == 0 ) { p->RestoreState(pile, bMain); // interrupt here! return; } ppVars[i++] = pile->GetVar(); // constructs the list of parameters p = p->GetNext(); if ( p == nullptr) break; } ppVars[i] = nullptr; CBotStack* pile2 = pile->RestoreStack(); if ( pile2 == nullptr ) return; pile2->RestoreCall(m_nFuncIdent, GetToken(), ppVars); }
bool CBotThrow :: Execute(CBotStack* &pj) { CBotStack* pile = pj->AddStack(this); // if ( pile == EOX ) return true; if ( pile->GetState() == 0 ) { if ( !m_Value->Execute(pile) ) return false; pile->IncState(); } if ( pile->IfStep() ) return false; int val = pile->GetVal(); if ( val < 0 ) val = TX_BADTHROW; pile->SetError( val, &m_token ); return pj->Return( pile ); }
bool CBotIf :: Execute(CBotStack* &pj) { CBotStack* pile = pj->AddStack(this); // adds an item to the stack // or found in case of recovery // if ( pile == EOX ) return true; if ( pile->IfStep() ) return false; // according to recovery, it may be in one of two states if( pile->GetState() == 0 ) { // evaluates the condition if ( !m_condition->Execute(pile) ) return false; // interrupted here? // terminates if there is an error if ( !pile->IsOk() ) { return pj->Return(pile); // returns the results and releases the stack } // passes into the second state if (!pile->SetState(1)) return false; // ready for further } // second state, evaluates the associated instructions // the result of the condition is on the stack if ( pile->GetVal() == true ) // condition was true? { if (m_block != nullptr && // block may be absent !m_block->Execute(pile) ) return false; // interrupted here? } else { if (m_blockElse != nullptr && // if there is an alternate block !m_blockElse->Execute(pile) ) return false; // interrupted here } // sends the results and releases the stack return pj->Return(pile); }
BOOL CBotIf :: Execute(CBotStack* &pj) { CBotStack* pile = pj->AddStack(this); // ajoute un élément à la pile // ou le retrouve en cas de reprise // if ( pile == EOX ) return TRUE; if ( pile->IfStep() ) return FALSE; // selon la reprise, on peut être dans l'un des 2 états if( pile->GivState() == 0 ) { // évalue la condition if ( !m_Condition->Execute(pile) ) return FALSE; // interrompu ici ? // termine s'il y a une erreur if ( !pile->IsOk() ) { return pj->Return(pile); // transmet le résultat et libère la pile } // passe dans le second état if (!pile->SetState(1)) return FALSE; // prêt pour la suite } // second état, évalue les instructions associées // le résultat de la condition est sur la pile if ( pile->GivVal() == TRUE ) // condition était vraie ? { if ( m_Block != NULL && // bloc peut être absent !m_Block->Execute(pile) ) return FALSE; // interrompu ici ? } else { if ( m_BlockElse != NULL && // s'il existe un bloc alternatif !m_BlockElse->Execute(pile) ) return FALSE; // interrompu ici } // transmet le résultat et libère la pile return pj->Return(pile); }
void CBotNew::RestoreState(CBotStack* &pj, bool bMain) { if (!bMain) return; CBotStack* pile = pj->RestoreStack(this); //primary stack if (pile == nullptr) return; if (m_exprRetVar != nullptr) // new Class().method() { if (pile->GetState() == 2) { CBotStack* pile3 = pile->RestoreStack(); m_exprRetVar->RestoreState(pile3, bMain); return; } } CBotStack* pile1 = pj->AddStack2(); //secondary stack CBotToken* pt = &m_vartoken; CBotClass* pClass = CBotClass::Find(pt); // create the variable "this" pointer type to the object if ( pile->GetState()==0) { return; } CBotVar* pThis = pile1->GetVar(); // find the pointer pThis->SetUniqNum(-2); // is ther an assignment or parameters (constructor) if ( pile->GetState()==1) { // evaluates the constructor of the instance CBotVar* ppVars[1000]; CBotStack* pile2 = pile; int i = 0; CBotInstr* p = m_parameters; // evaluate the parameters // and places the values on the stack // to be interrupted at any time if (p != nullptr) while ( true) { pile2 = pile2->RestoreStack(); // space on the stack for the result if (pile2 == nullptr) return; if (pile2->GetState() == 0) { p->RestoreState(pile2, bMain); // interrupt here! return; } ppVars[i++] = pile2->GetVar(); p = p->GetNext(); if ( p == nullptr) break; } ppVars[i] = nullptr; pClass->RestoreMethode(m_nMethodeIdent, m_vartoken.GetString(), pThis, ppVars, pile2) ; // interrupt here! } }
bool CBotNew::Execute(CBotStack* &pj) { CBotStack* pile = pj->AddStack(this); //main stack if (m_exprRetVar != nullptr) // new Class().method() { if (pile->GetState() == 2) { CBotStack* pile3 = pile->AddStack(); if (!m_exprRetVar->Execute(pile3)) return false; return pj->Return(pile3); } } if (pile->IfStep()) return false; CBotStack* pile1 = pj->AddStack2(); //secondary stack CBotVar* pThis = nullptr; CBotToken* pt = &m_vartoken; CBotClass* pClass = CBotClass::Find(pt); // create the variable "this" pointer type to the stack if ( pile->GetState()==0) { // create an instance of the requested class // and initialize the pointer to that object pThis = CBotVar::Create("this", pClass); pThis->SetUniqNum(-2) ; pile1->SetVar(pThis); // place on stack1 pile->IncState(); } // fetch the this pointer if it was interrupted if ( pThis == nullptr) { pThis = pile1->GetVar(); // find the pointer } // is there an assignment or parameters (constructor) if ( pile->GetState()==1) { // evaluates the constructor of the instance CBotVar* ppVars[1000]; CBotStack* pile2 = pile; int i = 0; CBotInstr* p = m_parameters; // evaluate the parameters // and places the values on the stack // to be interrupted at any time if (p != nullptr) while ( true) { pile2 = pile2->AddStack(); // space on the stack for the result if (pile2->GetState() == 0) { if (!p->Execute(pile2)) return false; // interrupted here? pile2->SetState(1); } ppVars[i++] = pile2->GetVar(); p = p->GetNext(); if ( p == nullptr) break; } ppVars[i] = nullptr; // create a variable for the result CBotVar* pResult = nullptr; // constructos still void if ( !pClass->ExecuteMethode(m_nMethodeIdent, pClass->GetName(), pThis, ppVars, pResult, pile2, GetToken())) return false; // interrupt pThis->ConstructorSet(); // indicates that the constructor has been called } if (m_exprRetVar != nullptr) // new Class().method() { pile->AddStack()->Delete(); // release pile2 stack CBotStack* pile3 = pile->AddStack(); // add new stack pile3->SetCopyVar(pThis); // copy the pointer (from pile1) pile1->Delete(); // release secondary stack(pile1) pile->SetState(2); return false; // go back to the top ^^^ } return pj->Return(pile1); // passes below }