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 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); }
bool CBotFor :: Execute(CBotStack* &pj) { CBotStack* pile = pj->AddStack(this, true); // adds an item to the stack (variables locales) // 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 four possible states (depending on recovery) case 0: // initialize if ( m_Init != nullptr && !m_Init->Execute(pile) ) return false; // interrupted here ? if (!pile->SetState(1)) return false; // ready for further case 1: // evaluates the condition if ( m_Test != nullptr ) // no strings attached? -> True! { if (!m_Test->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 } } // la condition est vrai, passe à la suite if (!pile->SetState(2)) return false; // ready for further case 2: // evaluates the associated statement block if ( m_Block != nullptr && !m_Block->Execute(pile) ) { if (pile->IfContinue(3, m_label)) continue; // if continued, going on to incrementation 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 } if (!pile->SetState(3)) return false; // ready for further case 3: // evalutate the incrementation if ( m_Incr != nullptr && !m_Incr->Execute(pile) ) return false; // interrupted here ? // returns to the test again if (!pile->SetState(1, 0)) return false; // returns to the test continue; } }
bool CBotClass::CompileDefItem(CBotToken* &p, CBotCStack* pStack, bool bSecond) { bool bStatic = false; int mProtect = PR_PUBLIC; bool bSynchro = false; while (IsOfType(p, ID_SEP)) ; CBotTypResult type( -1 ); if ( IsOfType(p, ID_SYNCHO) ) bSynchro = true; CBotToken* pBase = p; if ( IsOfType(p, ID_STATIC) ) bStatic = true; if ( IsOfType(p, ID_PUBLIC) ) mProtect = PR_PUBLIC; if ( IsOfType(p, ID_PRIVATE) ) mProtect = PR_PRIVATE; if ( IsOfType(p, ID_PROTECTED) ) mProtect = PR_PROTECT; if ( IsOfType(p, ID_STATIC) ) bStatic = true; // CBotClass* pClass = NULL; type = TypeParam(p, pStack); // type of the result if ( type.Eq(-1) ) { pStack->SetError(TX_NOTYP, p); return false; } while (pStack->IsOk()) { CBotToken* pp = p; IsOfType(p, ID_NOT); // skips ~ eventual (destructor) if (IsOfType(p, TokenTypVar)) { CBotInstr* limites = NULL; while ( IsOfType( p, ID_OPBRK ) ) // a table? { CBotInstr* i = NULL; if ( p->GetType() != ID_CLBRK ) i = CBotExpression::Compile( p, pStack ); // expression for the value else i = new CBotEmpty(); // special if not a formula type = CBotTypResult(CBotTypArrayPointer, type); if (!pStack->IsOk() || !IsOfType( p, ID_CLBRK ) ) { pStack->SetError(TX_CLBRK, p->GetStart()); return false; } /* CBotVar* pv = pStack->GetVar(); if ( pv->GetType()>= CBotTypBoolean ) { pStack->SetError(TX_BADTYPE, p->GetStart()); return false; }*/ if (limites == NULL) limites = i; else limites->AddNext3(i); } if ( p->GetType() == ID_OPENPAR ) { if ( !bSecond ) { p = pBase; CBotFunction* f = CBotFunction::Compile1(p, pStack, this); if ( f == NULL ) return false; if (m_pMethod == NULL) m_pMethod = f; else m_pMethod->AddNext(f); } else { // return a method precompiled in pass 1 CBotFunction* pf = m_pMethod; CBotFunction* prev = NULL; while ( pf != NULL ) { if (pf->GetName() == pp->GetString()) break; prev = pf; pf = pf->Next(); } bool bConstructor = (pp->GetString() == GetName()); CBotCStack* pile = pStack->TokenStack(NULL, true); // make "this" known CBotToken TokenThis(CBotString("this"), CBotString()); CBotVar* pThis = CBotVar::Create(&TokenThis, CBotTypResult( CBotTypClass, this ) ); pThis->SetUniqNum(-2); pile->AddVar(pThis); if ( m_pParent ) { // makes "super" known CBotToken TokenSuper(CBotString("super"), CBotString()); CBotVar* pThis = CBotVar::Create(&TokenSuper, CBotTypResult( CBotTypClass, m_pParent ) ); pThis->SetUniqNum(-3); pile->AddVar(pThis); } // int num = 1; CBotClass* my = this; while (my != NULL) { // places a copy of variables of a class (this) on a stack CBotVar* pv = my->m_pVar; while (pv != NULL) { CBotVar* pcopy = CBotVar::Create(pv); pcopy->SetInit(!bConstructor || pv->IsStatic()); pcopy->SetUniqNum(pv->GetUniqNum()); pile->AddVar(pcopy); pv = pv->GetNext(); } my = my->m_pParent; } // compiles a method p = pBase; CBotFunction* f = CBotFunction::Compile(p, pile, NULL/*, false*/); if ( f != NULL ) { f->m_pProg = pStack->GetBotCall(); f->m_bSynchro = bSynchro; // replaces the element in the chain f->m_next = pf->m_next; pf->m_next = NULL; delete pf; if (prev == NULL) m_pMethod = f; else prev->m_next = f; } pStack->Return(NULL, pile); } return pStack->IsOk(); } // definition of an element if (type.Eq(0)) { pStack->SetError(TX_ENDOF, p); return false; } CBotInstr* i = NULL; if ( IsOfType(p, ID_ASS ) ) { if ( type.Eq(CBotTypArrayPointer) ) { i = CBotListArray::Compile(p, pStack, type.GetTypElem()); } else { // it has an assignmet to calculate i = CBotTwoOpExpr::Compile(p, pStack); } if ( !pStack->IsOk() ) return false; } if ( !bSecond ) { CBotVar* pv = CBotVar::Create(pp->GetString(), type); pv -> SetStatic( bStatic ); pv -> SetPrivate( mProtect ); AddItem( pv ); pv->m_InitExpr = i; pv->m_LimExpr = limites; if ( pv->IsStatic() && pv->m_InitExpr != NULL ) { CBotStack* pile = CBotStack::FirstStack(); // independent stack while(pile->IsOk() && !pv->m_InitExpr->Execute(pile)); // evaluates the expression without timer pv->SetVal( pile->GetVar() ) ; pile->Delete(); } } else delete i; if ( IsOfType(p, ID_COMMA) ) continue; if ( IsOfType(p, ID_SEP) ) break; } pStack->SetError(TX_ENDOF, p); } return pStack->IsOk(); }