void CBotFunction::RestoreCall(long& nIdent, const char* name, CBotVar** ppVars, CBotStack* pStack) { CBotTypResult type; CBotFunction* pt = NULL; CBotStack* pStk1; CBotStack* pStk3; // search function to return the ok identifier pt = FindLocalOrPublic(nIdent, name, ppVars, type); if ( pt != NULL ) { pStk1 = pStack->RestoreStack(pt); if ( pStk1 == NULL ) return; pStk1->SetBotCall(pt->m_pProg); // it may have changed module if ( pStk1->GetBlock() < 2 ) { CBotStack* pStk2 = pStk1->RestoreStack(NULL); // used more if ( pStk2 == NULL ) return; pStk3 = pStk2->RestoreStack(NULL); if ( pStk3 == NULL ) return; } else { pStk3 = pStk1->RestoreStack(NULL); if ( pStk3 == NULL ) return; } // preparing parameters on the stack { if ( !pt->m_MasterClass.IsEmpty() ) { // CBotVar* pInstance = m_pProg->m_pInstance; // make "this" known CBotVar* pThis = pStk1->FindVar("this"); pThis->SetInit(2); pThis->SetUniqNum(-2); } } if ( pStk1->GetState() == 0 ) { pt->m_Param->RestoreState(pStk3, true); return; } // initializes the variables as parameters pt->m_Param->RestoreState(pStk3, false); pt->m_Block->RestoreState(pStk3, true); } }
CBotVar* CBotClass::GetItemRef(int nIdent) { CBotVar* p = m_pVar; while ( p != NULL ) { if ( p->GetUniqNum() == nIdent ) return p; p = p->GetNext(); } if ( m_pParent != NULL ) return m_pParent->GetItemRef(nIdent); return NULL; }
CBotVar* CBotClass::GetItem(const char* name) { CBotVar* p = m_pVar; while ( p != NULL ) { if ( p->GetName() == name ) return p; p = p->GetNext(); } if ( m_pParent != NULL ) return m_pParent->GetItem(name); return NULL; }
bool CBotCatch :: TestCatch(CBotStack* &pile, int val) { if ( !m_Cond->Execute(pile) ) return false; if ( val > 0 || pile->GetType() != CBotTypBoolean ) { CBotVar* var = CBotVar::Create(static_cast<CBotToken*>(nullptr), CBotTypBoolean); var->SetValInt( pile->GetVal() == val ); pile->SetVar(var); // calls on the stack } return true; }
void CBotDefParam::RestoreState(CBotStack* &pj, bool bMain) { // int i = 0; CBotDefParam* p = this; while ( p != NULL ) { // creates a local variable on the stack CBotVar* var = pj->FindVar(p->m_token.GetString()); var->SetUniqNum(p->m_nIdent); p = p->m_next; } }
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); }
BOOL rSpace(CBotVar* var, CBotVar* result, int& exception, void* user) { CBotVar* pSub; float rMin, rMax, dist; rMin = 5.0f*UNIT; rMax = 50.0f*UNIT; dist = 4.0f*UNIT; if ( var == 0 ) { // center = pThis->RetPosition(0); } else { if ( var != 0 ) { rMin = var->GivValFloat()*UNIT; var = var->GivNext(); if ( var != 0 ) { rMax = var->GivValFloat()*UNIT; var = var->GivNext(); if ( var != 0 ) { dist = var->GivValFloat()*UNIT; var = var->GivNext(); } } } } if ( result != 0 ) { pSub = result->GivItemList(); if ( pSub != 0 ) { pSub->SetValFloat(1); pSub = pSub->GivNext(); // "y" pSub->SetValFloat(2); pSub = pSub->GivNext(); // "z" // pSub->SetValFloat(3); } } return TRUE; }
BOOL roRadar( CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception ) { pResult->SetPointer( NULL ); compt+=45671; if (compt&0x11) return TRUE; CBotVar* pAutre = CBotVar::Create("autre", CBotTypResult( CBotTypClass, "object" )); pAutre->SetUserPtr( (void*)2 ); pResult->SetPointer( pAutre ); if (!pResult->IsElemOfClass("object")) return TRUE; delete pAutre; return TRUE; }
void CBotVar::debug() { // const char* p = static_cast<const char*>( m_token->GetString()); CBotString s = static_cast<const char*>( GetValString()); // const char* v = static_cast<const char*> (s); if ( m_type.Eq(CBotTypClass) ) { CBotVar* pv = (static_cast<CBotVarClass*>(this))->m_pVar; while (pv != NULL) { pv->debug(); pv = pv->GetNext(); } } }
// exécution BOOL rCPoint( CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception ) { CString s; if ( pVar == NULL )return TRUE; // constructeur sans paramètres est ok CBotVar* pX = pThis->GivItem("x"); pX->SetValFloat( pVar->GivValFloat() ); pVar = pVar->GivNext(); CBotVar* pY = pThis->GivItem("y"); pY->SetValFloat( pVar->GivValFloat() ); pVar = pVar->GivNext(); return TRUE; // pas d'interruption }
bool CBotAddExpr::Execute(CBotStack* &pStack) { CBotStack* pStk1 = pStack->AddStack(this); // adds an item to the stack // or is found in case of recovery // if ( pSk1 == EOX ) return TRUE; // according to recovery, it may be in one of two states if ( pStk1->GetState() == 0 && // first state, evaluates the left operand !m_leftop->Execute(pStk1) ) return FALSE; // interrupted here? // passes to the next step pStk1->SetState(1); // ready for further // requires a little more stack to not touch the result of the left // which is on the stack, precisely. CBotStack* pStk2 = pStk1->AddStack(); // adds an item to the stack // or is found in case of recovery // Second state, evaluates the right operand if ( !m_rightop->Execute(pStk2) ) return FALSE; // interrupted here? int type1 = pStk1->GetType(); // what kind of results? int type2 = pStk2->GetType(); // creates a temporary variable to put the result CBotVar* result = new CBotVar( nullptr, MAX(type1, type2)); // is the operation as requested switch (GetTokenType()) { case ID_ADD: result->Add(pStk1->GetVar(), pStk2->GetVar()); // addition break; case ID_SUB: result->Sub(pStk1->GetVar(), pStk2->GetVar()); // subtraction break; } pStk2->SetVar(result); // puts the result on the stack pStk1->Return(pStk2); // frees the stack return pStack->Return(pStk1); // transmits the result }
BOOL CBotAddExpr::Execute(CBotStack* &pStack) { CBotStack* pStk1 = pStack->AddStack(this); // ajoute un élément à la pile // ou le retrouve en cas de reprise // if ( pSk1 == EOX ) return TRUE; // selon la reprise, on peut être dans l'un des 2 états if ( pStk1->GetState() == 0 && // 1er état, évalue l'opérande de gauche !m_leftop->Execute(pStk1) ) return FALSE; // interrompu ici ? // passe à l'étape suivante pStk1->SetState(1); // prêt pour la suite // demande un peu plus de stack pour ne pas toucher le résultat de gauche // qui se trouve sur la pile, justement. CBotStack* pStk2 = pStk1->AddStack(); // ajoute un élément à la pile // ou le retrouve en cas de reprise // 2e état, évalue l'opérande de droite if ( !m_rightop->Execute(pStk2) ) return FALSE; // interrompu ici ? int type1 = pStk1->GetType(); // de quels types les résultats ? int type2 = pStk2->GetType(); // crée une variable temporaire pour y mettre le résultat CBotVar* result = new CBotVar( NULL, MAX(type1, type2)); // fait l'opération selon la demande switch (GetTokenType()) { case ID_ADD: result->Add(pStk1->GetVar(), pStk2->GetVar()); // additionne break; case ID_SUB: result->Sub(pStk1->GetVar(), pStk2->GetVar()); // soustrait break; } pStk2->SetVar(result); // met le résultat sur la pile pStk1->Return(pStk2); // libère la pile return pStack->Return(pStk1); // transmet le résultat }
CBotVar* CBotStack::FindVar(const char* name) { CBotStack* p = this; while (p != NULL) { CBotVar* pp = p->m_listVar; while ( pp != NULL) { if (pp->GetName() == name) { return pp; } pp = pp->m_next; } p = p->m_prev; } return NULL; }
bool CBotCStack::CheckVarLocal(CBotToken* &pToken) { CBotCStack* p = this; CBotString name = pToken->GetString(); while (p != NULL) { CBotVar* pp = p->m_listVar; while ( pp != NULL) { if (name == pp->GetName()) return true; pp = pp->m_next; } if ( p->m_bBlock ) return false; p = p->m_prev; } return false; }
CBotVar* CBotVar::Create( const char* name, int type, CBotClass* pClass) { CBotToken token( name, "" ); CBotVar* pVar = Create( &token, type ); if ( type == CBotTypPointer && pClass == NULL ) // pointer "null" ? return pVar; if ( type == CBotTypClass || type == CBotTypPointer || type == CBotTypIntrinsic ) { if (pClass == NULL) { delete pVar; return NULL; } pVar->SetClass( pClass ); } return pVar; }
CBotVar* CBotVar::Create(const std::string& name, CBotType type, CBotClass* pClass) { CBotToken token( name, "" ); CBotVar* pVar = Create( token, type ); if ( type == CBotTypPointer && pClass == nullptr ) // pointer "null" ? return pVar; if ( type == CBotTypClass || type == CBotTypPointer || type == CBotTypIntrinsic ) { if (pClass == nullptr) { delete pVar; return nullptr; } pVar->SetClass( pClass ); } return pVar; }
CBotVar* CBotCStack::FindVar(CBotToken* &pToken) { CBotCStack* p = this; CBotString name = pToken->GetString(); while (p != NULL) { CBotVar* pp = p->m_listVar; while ( pp != NULL) { if (name == pp->GetName()) { return pp; } pp = pp->m_next; } p = p->m_prev; } return NULL; }
bool CBotExprRetVar::Execute(CBotStack* &pj) { CBotStack* pile = pj->AddStack(); CBotStack* pile1 = pile; CBotVar* pVar; if (pile1->GetState() == 0) { pVar = pj->GetVar(); pVar->Update(pj->GetUserPtr()); if (pVar->GetType(CBotVar::GetTypeMode::CLASS_AS_POINTER) == CBotTypNullPointer) { pile1->SetError(CBotErrNull, &m_token); return pj->Return(pile1); } if ( !m_next3->ExecuteVar(pVar, pile, &m_token, true, false) ) return false; if (pVar) pile1->SetCopyVar(pVar); else return pj->Return(pile1); pile1->IncState(); } pVar = pile1->GetVar(); if (pVar == nullptr) { return pj->Return(pile1); } if (pVar->IsUndefined()) { pile1->SetError(CBotErrNotInit, &m_token); return pj->Return(pile1); } return pj->Return(pile1); }
CBotVar* CBotStack::FindVar(long ident, bool bUpdate, bool bModif) { CBotStack* p = this; while (p != NULL) { CBotVar* pp = p->m_listVar; while ( pp != NULL) { if (pp->GetUniqNum() == ident) { if ( bUpdate ) pp->Maj(m_pUser, false); return pp; } pp = pp->m_next; } p = p->m_prev; } return NULL; }
bool CBotClass::SaveStaticState(FILE* pf) { if (!WriteWord( pf, CBOTVERSION*2)) return false; // saves the state of static variables in classes CBotClass* p = m_ExClass; while ( p != NULL ) { if (!WriteWord( pf, 1)) return false; // save the name of the class if (!WriteString( pf, p->GetName() )) return false; CBotVar* pv = p->GetVar(); while( pv != NULL ) { if ( pv->IsStatic() ) { if (!WriteWord( pf, 1)) return false; if (!WriteString( pf, pv->GetName() )) return false; if ( !pv->Save0State(pf)) return false; // common header if ( !pv->Save1State(pf) ) return false; // saves as the child class if ( !WriteWord( pf, 0)) return false; } pv = pv->GetNext(); } if (!WriteWord( pf, 0)) return false; p = p->m_ExNext; } if (!WriteWord( pf, 0)) return false; return true; }
BOOL rRadar( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ) { pResult->SetPointer( NULL ); if ( pVar ) pVar->debug(); compt+=45671; if (compt&0x11) { return FALSE; // TRUE; } CBotVar* pAutre = CBotVar::Create("autre", CBotTypResult( CBotTypClass, "object" )); pAutre->SetUserPtr( (void*)2 ); pResult->SetPointer( pAutre ); if (!pResult->IsElemOfClass("object")) return TRUE; delete pAutre; return TRUE; }
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 CBotClass::AddItem(CBotString name, CBotTypResult type, int mPrivate) { CBotToken token(name, CBotString()); CBotClass* pClass = type.GetClass(); CBotVar* pVar = CBotVar::Create( name, type ); /// pVar->SetUniqNum(CBotVar::NextUniqNum()); pVar->SetPrivate( mPrivate ); if ( pClass != NULL ) { // pVar->SetClass(pClass); if ( type.Eq(CBotTypClass) ) { // adds a new statement for the object initialization pVar->m_InitExpr = new CBotNew() ; CBotToken nom( pClass->GetName() ); pVar->m_InitExpr->SetToken(&nom); } } return AddItem( pVar ); }
CBotVar* CBotStack::FindVar(CBotToken* &pToken, bool bUpdate, bool bModif) { CBotStack* p = this; CBotString name = pToken->GetString(); while (p != NULL) { CBotVar* pp = p->m_listVar; while ( pp != NULL) { if (pp->GetName() == name) { if ( bUpdate ) pp->Maj(m_pUser, false); return pp; } pp = pp->m_next; } p = p->m_prev; } return NULL; }
bool CBotClass::RestoreStaticState(FILE* pf) { CBotString ClassName, VarName; CBotClass* pClass; unsigned short w; if (!ReadWord( pf, w )) return false; if ( w != CBOTVERSION*2 ) return false; while (true) { if (!ReadWord( pf, w )) return false; if ( w == 0 ) return true; if (!ReadString( pf, ClassName )) return false; pClass = Find(ClassName); while (true) { if (!ReadWord( pf, w )) return false; if ( w == 0 ) break; CBotVar* pVar = NULL; CBotVar* pv = NULL; if (!ReadString( pf, VarName )) return false; if ( pClass != NULL ) pVar = pClass->GetItem(VarName); if (!CBotVar::RestoreState(pf, pv)) return false; // the temp variable if ( pVar != NULL ) pVar->Copy(pv); delete pv; } } return true; }
bool rSpace(CBotVar* var, CBotVar* result, int& exception, void* user) { CScript* script = ((CObject*)user)->RetRunScript(); CObject* pThis = (CObject*)user; CBotVar* pSub; Math::Vector center; float rMin, rMax, dist; rMin = 5.0f*UNIT; rMax = 50.0f*UNIT; dist = 4.0f*UNIT; if ( var == 0 ) { center = pThis->RetPosition(0); } else { if ( !GetPoint(var, exception, center) ) return true; if ( var != 0 ) { rMin = var->GivValFloat()*UNIT; var = var->GivNext(); if ( var != 0 ) { rMax = var->GivValFloat()*UNIT; var = var->GivNext(); if ( var != 0 ) { dist = var->GivValFloat()*UNIT; var = var->GivNext(); } } } } script->m_main->FreeSpace(center, rMin, rMax, dist, pThis); if ( result != 0 ) { pSub = result->GivItemList(); if ( pSub != 0 ) { pSub->SetValFloat(center.x/UNIT); pSub = pSub->GivNext(); // "y" pSub->SetValFloat(center.z/UNIT); pSub = pSub->GivNext(); // "z" pSub->SetValFloat(center.y/UNIT); } } return true; }
bool CBotDefParam::Execute(CBotVar** ppVars, CBotStack* &pj) { int i = 0; CBotDefParam* p = this; while ( p != NULL ) { // creates a local variable on the stack CBotVar* newvar = CBotVar::Create(p->m_token.GetString(), p->m_type); // serves to make the transformation of types: if ( ppVars != NULL && ppVars[i] != NULL ) { switch (p->m_type.GetType()) { case CBotTypInt: newvar->SetValInt(ppVars[i]->GetValInt()); break; case CBotTypFloat: newvar->SetValFloat(ppVars[i]->GetValFloat()); break; case CBotTypString: newvar->SetValString(ppVars[i]->GetValString()); break; case CBotTypBoolean: newvar->SetValInt(ppVars[i]->GetValInt()); break; case CBotTypIntrinsic: (static_cast<CBotVarClass*>(newvar))->Copy(ppVars[i], false); break; case CBotTypPointer: case CBotTypArrayPointer: { newvar->SetPointer(ppVars[i]->GetPointer()); } break; default: ASM_TRAP(); } } newvar->SetUniqNum(p->m_nIdent); pj->AddVar(newvar); // add a variable p = p->m_next; i++; } return true; }
bool CBotCompExpr::Execute(CBotStack* &pStack) { CBotStack* pStk1 = pStack->AddStack(this); // if ( pStk1 == EOX ) return TRUE; if ( pStk1->GetState() == 0 && !m_leftop->Execute(pStk1) ) return FALSE; // interrupted here ? pStk1->SetState(1); // finished // requires a little more stack to not touch the result of the left CBotStack* pStk2 = pStk1->AddStack(); if ( !m_rightop->Execute(pStk2) ) return FALSE; // interrupted here ? int type1 = pStk1->GetType(); int type2 = pStk2->GetType(); CBotVar* result = new CBotVar( NULL, CBotTypBoolean ); switch (GetTokenType()) { case ID_LO: result->Lo(pStk1->GetVar(), pStk2->GetVar()); // lower break; case ID_HI: result->Hi(pStk1->GetVar(), pStk2->GetVar()); // higher break; case ID_LS: result->Ls(pStk1->GetVar(), pStk2->GetVar()); // lower or equal break; case ID_HS: result->Hs(pStk1->GetVar(), pStk2->GetVar()); // higher of equal break; case ID_EQ: result->Eq(pStk1->GetVar(), pStk2->GetVar()); // equal break; case ID_NE: result->Ne(pStk1->GetVar(), pStk2->GetVar()); // not equal break; } pStk2->SetVar(result); // puts the result on the stack pStk1->Return(pStk2); // frees the stack return pStack->Return(pStk1); // transmit the result }
CBotInstr* CBotNew::Compile(CBotToken* &p, CBotCStack* pStack) { CBotToken* pp = p; if (!IsOfType(p, ID_NEW)) return nullptr; // verifies that the token is a class name if (p->GetType() != TokenTypVar) { pStack->SetError(CBotErrBadNew, p); return nullptr; } CBotClass* pClass = CBotClass::Find(p); if (pClass == nullptr) { pStack->SetError(CBotErrBadNew, p); return nullptr; } CBotNew* inst = new CBotNew(); inst->SetToken(pp); inst->m_vartoken = *p; p = p->GetNext(); // creates the object on the stack // with a pointer to the object CBotVar* pVar = CBotVar::Create("", pClass); // do the call of the creator CBotCStack* pStk = pStack->TokenStack(); { // check if there are parameters CBotVar* ppVars[1000]; inst->m_parameters = CompileParams(p, pStk, ppVars); if (!pStk->IsOk()) goto error; // constructor exist? CBotTypResult r = pClass->CompileMethode(pClass->GetName(), pVar, ppVars, pStk, inst->m_nMethodeIdent); delete pStk->TokenStack(); // release extra stack int typ = r.GetType(); // if there is no constructor, and no parameters either, it's ok if (typ == CBotErrUndefCall && inst->m_parameters == nullptr) typ = 0; pVar->SetInit(CBotVar::InitType::DEF); // mark the instance as init if (typ>20) { pStk->SetError(static_cast<CBotError>(typ), inst->m_vartoken.GetEnd()); goto error; } // if the constructor does not exist, but there are parameters if (typ<0 && inst->m_parameters != nullptr) { pStk->SetError(CBotErrNoConstruct, &inst->m_vartoken); goto error; } // makes pointer to the object on the stack pStk->SetVar(pVar); pp = p; // chained method ? if (nullptr != (inst->m_exprRetVar = CBotExprRetVar::Compile(p, pStk, true))) { inst->m_exprRetVar->SetToken(pp); delete pStk->TokenStack(); } if (pStack->IsOk()) return pStack->Return(inst, pStk); } error: delete inst; return pStack->Return(nullptr, pStk); }
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! } }