CBotTypResult cSizeOf( CBotVar* &pVar, void* pUser ) { if ( pVar == nullptr ) return CBotTypResult( CBotErrLowParam ); if ( pVar->GetType() != CBotTypArrayPointer ) return CBotTypResult( CBotErrBadParam ); return CBotTypResult( CBotTypInt ); }
// compilation CBotTypResult cfread (CBotVar* pThis, CBotVar* &pVar) { // it should not be any parameter if ( pVar != nullptr ) return CBotTypResult( CBotErrOverParam ); // function returns a result "string" return CBotTypResult( CBotTypString ); }
// compilation CBotTypResult cfclose (CBotVar* pThis, CBotVar* &pVar) { // it shouldn't be any parameters if ( pVar != nullptr ) return CBotTypResult( CBotErrOverParam ); // function returns a result "void" return CBotTypResult( 0 ); }
CBotTypResult cOneFloat(CBotVar* &var, void* user) { if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); var = var->GetNext(); if ( var != nullptr ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypFloat); }
CBotTypResult cOneIntReturnBool(CBotVar* &var, void* user) { if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); if ( var->GetType() != CBotTypInt ) return CBotTypResult(CBotErrBadNum); var = var->GetNext(); if ( var != nullptr ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypBoolean); }
// compilation CBotTypResult cfeof (CBotVar* pThis, CBotVar* &pVar) { // it shouldn't be any parameter if ( pVar != nullptr ) return CBotTypResult( CBotErrOverParam ); // the function returns a boolean result return CBotTypResult( CBotTypBoolean ); }
CBotTypResult cStringString(CBotVar* &var, void* user) { if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); if ( var->GetType() != CBotTypString && var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); var = var->GetNext(); if ( var != nullptr ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypString); }
CBotTypResult cPoint(CBotVar* &var, void* user) { if ( var == 0 ) return CBotTypResult( CBotErrLowParam ); if ( var->GivType() <= CBotTypDouble ) { var = var->GivNext(); if ( var == 0 ) return CBotTypResult( CBotErrLowParam ); if ( var->GivType() > CBotTypDouble ) return CBotTypResult( CBotErrBadNum ); var = var->GivNext(); if ( var == 0 ) return CBotTypResult( CBotErrLowParam ); if ( var->GivType() > CBotTypDouble ) return CBotTypResult( CBotErrBadNum ); var = var->GivNext(); return CBotTypResult( 0 ); } if ( var->GivType() == CBotTypClass ) { if ( !var->IsElemOfClass("point") ) return CBotTypResult( CBotErrBadParam ); var = var->GivNext(); return CBotTypResult( 0 ); } return CBotTypResult( CBotErrBadParam ); }
CBotTypResult ArrayType(CBotToken* &p, CBotCStack* pile, CBotTypResult type) { while ( IsOfType( p, ID_OPBRK ) ) { if ( !IsOfType( p, ID_CLBRK ) ) { pile->SetError(CBotErrCloseIndex, p->GetStart()); return CBotTypResult( -1 ); } type = CBotTypResult( CBotTypArrayPointer, type ); } return type; }
// compilation CBotTypResult cfwrite (CBotVar* pThis, CBotVar* &pVar) { // there must be a parameter if ( pVar == nullptr ) return CBotTypResult( CBotErrLowParam ); // which must be a character string if ( pVar->GetType() != CBotTypString ) return CBotTypResult( CBotErrBadString ); // no other parameter if ( pVar->GetNext() != nullptr ) return CBotTypResult( CBotErrOverParam ); // the function returns a void result return CBotTypResult( 0 ); }
CBotTypResult cIntStr(CBotVar*& var, void* user) { // it takes a parameter if ( var == nullptr ) return CBotTypResult( CBotErrLowParam ); // to be a string if ( var->GetType() != CBotTypString ) return CBotTypResult( CBotErrBadParam ); // no second parameter if ( var->GetNext() != nullptr ) return CBotTypResult( CBotErrOverParam ); // the end result is an integer return CBotTypResult( CBotTypInt ); }
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 CBotVarPointer::SetPointer(CBotVar* pVarClass) { m_binit = CBotVar::InitType::DEF; // init, even on a null pointer if ( m_pVarClass == pVarClass) return; // special, not decrement and reincrement // because the decrement can destroy the object if ( pVarClass != nullptr ) { if ( pVarClass->GetType() == CBotTypPointer ) pVarClass = pVarClass->GetPointer(); // the real pointer to the object // if ( pVarClass->GetType() != CBotTypClass ) if ( !pVarClass->m_type.Eq(CBotTypClass) ) assert(0); (static_cast<CBotVarClass*>(pVarClass))->IncrementUse(); // increment the reference m_pClass = (static_cast<CBotVarClass*>(pVarClass))->m_pClass; m_pUserPtr = pVarClass->m_pUserPtr; // not really necessary m_type = CBotTypResult(CBotTypPointer, m_pClass); // what kind of a pointer } if ( m_pVarClass != nullptr ) m_pVarClass->DecrementUse(); m_pVarClass = static_cast<CBotVarClass*>(pVarClass); }
CBotVar* CBotVar::Create(const std::string& name, CBotClass* pClass) { CBotToken token( name, "" ); CBotVar* pVar = Create( token, CBotTypResult( CBotTypClass, pClass ) ); // pVar->SetClass( pClass ); return pVar; }
CBotVarClass::CBotVarClass( const CBotToken* name, const CBotTypResult& type) { /* // int nIdent = 0; InitCBotVarClass( name, type ) //, nIdent ); } CBotVarClass::CBotVarClass( const CBotToken* name, CBotTypResult& type) //, int &nIdent ) { InitCBotVarClass( name, type ); //, nIdent ); } void CBotVarClass::InitCBotVarClass( const CBotToken* name, CBotTypResult& type ) //, int &nIdent ) {*/ if ( !type.Eq(CBotTypClass) && !type.Eq(CBotTypIntrinsic) && // by convenience there accepts these types !type.Eq(CBotTypPointer) && !type.Eq(CBotTypArrayPointer) && !type.Eq(CBotTypArrayBody)) ASM_TRAP(); m_token = new CBotToken(name); m_next = NULL; m_pMyThis = NULL; m_pUserPtr = OBJECTCREATED;//NULL; m_InitExpr = NULL; m_LimExpr = NULL; m_pVar = NULL; m_type = type; if ( type.Eq(CBotTypArrayPointer) ) m_type.SetType( CBotTypArrayBody ); else if ( !type.Eq(CBotTypArrayBody) ) m_type.SetType( CBotTypClass ); // officel type for this object m_pClass = NULL; m_pParent = NULL; m_binit = false; m_bStatic = false; m_mPrivate = 0; m_bConstructor = false; m_CptUse = 0; m_ItemIdent = type.Eq(CBotTypIntrinsic) ? 0 : CBotVar::NextUniqNum(); // se place tout seul dans la liste // TODO stands alone in the list (stands only in a list) if (m_ExClass) m_ExClass->m_ExPrev = this; m_ExNext = m_ExClass; m_ExPrev = NULL; m_ExClass = this; CBotClass* pClass = type.GetClass(); CBotClass* pClass2 = pClass->GetParent(); if ( pClass2 != NULL ) { // also creates an instance of the parent class m_pParent = new CBotVarClass(name, CBotTypResult(type.GetType(),pClass2) ); //, nIdent); } SetClass( pClass ); //, nIdent ); }
CBotTypResult cStrStrIntInt(CBotVar*& var, void* user) { // it takes a parameter if ( var == nullptr ) return CBotTypResult( CBotErrLowParam ); // to be a string if ( var->GetType() != CBotTypString ) return CBotTypResult( CBotErrBadString ); // it takes a second parameter var = var->GetNext(); if ( var == nullptr ) return CBotTypResult( CBotErrLowParam ); // which must be a number if ( var->GetType() > CBotTypDouble ) return CBotTypResult( CBotErrBadNum ); // third parameter optional if ( var->GetNext() != nullptr ) { var = var->GetNext(); // which must be a number if ( var->GetType() > CBotTypDouble ) return CBotTypResult( CBotErrBadNum ); // no fourth parameter if ( var->GetNext() != nullptr ) return CBotTypResult( CBotErrOverParam ); } // the end result is a string return CBotTypResult( CBotTypString ); }
CBotTypResult cCPoint( CBotVar* pThis, CBotVar* &pVar) { // ok si aucun paramètres ! if ( pVar == NULL ) return CBotTypResult(0); // paramètre de type numérique svp if ( pVar->GivType() > CBotTypDouble ) return CBotTypResult(5011); pVar = pVar->GivNext(); // il doit y avoir un second paramètre if ( pVar == NULL ) return 5028; // également de type numérique if ( pVar->GivType() > CBotTypDouble )return CBotTypResult(5011); pVar = pVar->GivNext(); // et pas plus de 2 paramètres svp if ( pVar != NULL ) return CBotTypResult(5026); return CBotTypResult(0); // cette fonction retourne void }
CBotTypResult cSpace(CBotVar* &var, void* user) { CBotTypResult ret; if ( var == 0 ) return CBotTypResult( CBotTypIntrinsic, "point" ); ret = cPoint(var, user); if ( !ret.Eq(0) ) return ret; if ( var == 0 ) return CBotTypIntrinsic; if ( var->GivType() > CBotTypDouble ) return CBotTypResult( CBotErrBadNum ); var = var->GivNext(); if ( var == 0 ) return CBotTypIntrinsic; if ( var->GivType() > CBotTypDouble ) return CBotTypResult( CBotErrBadNum ); var = var->GivNext(); if ( var == 0 ) return CBotTypIntrinsic; if ( var->GivType() > CBotTypDouble ) return CBotTypResult( CBotErrBadNum ); var = var->GivNext(); if ( var != 0 ) return CBotErrOverParam; return CBotTypResult( CBotTypIntrinsic, "point" ); }
// compilation CBotTypResult cfconstruct (CBotVar* pThis, CBotVar* &pVar) { // accepts no parameters if ( pVar == nullptr ) return CBotTypResult( 0 ); // must be a character string if ( pVar->GetType() != CBotTypString ) return CBotTypResult( CBotErrBadString ); // there may be a second parameter pVar = pVar->GetNext(); if ( pVar != nullptr ) { // which must be a string if ( pVar->GetType() != CBotTypString ) return CBotTypResult( CBotErrBadString ); // no third parameter if ( pVar->GetNext() != nullptr ) return CBotTypResult( CBotErrOverParam ); } // the result is void (constructor) return CBotTypResult( 0 ); }
// compilation CBotTypResult cfopen (CBotVar* pThis, CBotVar* &pVar) { // there must be a parameter if ( pVar == nullptr ) return CBotTypResult( CBotErrLowParam ); // which must be a string if ( pVar->GetType() != CBotTypString ) return CBotTypResult( CBotErrBadString ); // there may be a second parameter pVar = pVar->GetNext(); if ( pVar != nullptr ) { // which must be a string if ( pVar->GetType() != CBotTypString ) return CBotTypResult( CBotErrBadString ); // no third parameter if ( pVar->GetNext() != nullptr ) return CBotTypResult( CBotErrOverParam ); } // the result is bool return CBotTypResult(CBotTypBoolean); }
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; }
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; }
CBotTypResult TypeParam(CBotToken* &p, CBotCStack* pile) { CBotClass* pClass = nullptr; switch (p->GetType()) { case ID_INT: p = p->GetNext(); return ArrayType(p, pile, CBotTypResult( CBotTypInt )); case ID_FLOAT: p = p->GetNext(); return ArrayType(p, pile, CBotTypResult( CBotTypFloat )); case ID_BOOLEAN: case ID_BOOL: p = p->GetNext(); return ArrayType(p, pile, CBotTypResult( CBotTypBoolean )); case ID_STRING: p = p->GetNext(); return ArrayType(p, pile, CBotTypResult( CBotTypString )); case ID_VOID: p = p->GetNext(); return CBotTypResult( 0 ); case TokenTypVar: pClass = CBotClass::Find(p); if ( pClass != nullptr) { p = p->GetNext(); return ArrayType(p, pile, pClass->IsIntrinsic() ? CBotTypResult( CBotTypIntrinsic, pClass ) : CBotTypResult( CBotTypPointer, pClass ) ); } } return CBotTypResult( -1 ); }
// type of instruction on the stack CBotTypResult CBotCStack::GetTypResult(int mode) { if (m_var == NULL) return CBotTypResult(99); return m_var->GetTypResult(mode); }
BOOL CTestCBotApp::InitInstance() { ////////////////////////////////////////////// // défini les mots clefs supplémentaires // ------------------------------------------- CBotProgram::Init(); ////////////////////////////////////////////// // défini les fonctions "show()" et "print()" // ------------------------------------------- CBotProgram::AddFunction("show", rShow, cShow); CBotProgram::AddFunction("print", rPrint, cPrint); CBotProgram::AddFunction("println", rPrintLn, cPrint); /////////////////////////////////// // définie la classe globale CPoint // -------------------------------- m_pClassPoint = new CBotClass("CPoint", NULL); // ajoute le composant ".x" m_pClassPoint->AddItem("x", CBotTypFloat); // ajoute le composant ".y" m_pClassPoint->AddItem("y", CBotTypFloat); // ajoute le constructeur pour cette classe m_pClassPoint->AddFunction("CPoint", rCPoint, cCPoint); m_pClassPointIntr = new CBotClass("point", NULL, TRUE); // ajoute le composant ".x" m_pClassPointIntr->AddItem("x", CBotTypFloat); // ajoute le composant ".y" m_pClassPointIntr->AddItem("y", CBotTypFloat); // ajoute le composant ".z" m_pClassPointIntr->AddItem("z", CBotTypFloat); // ajoute le constructeur pour cette classe m_pClassPointIntr->AddFunction("point", rCPoint, cCPoint); // défini la classe "object" CBotClass* pClassObject = new CBotClass( "object", NULL ) ; pClassObject->AddItem( "xx", CBotTypFloat ); pClassObject->AddItem( "position", CBotTypResult( CBotTypIntrinsic, "point" ) ); pClassObject->AddItem( "transport", CBotTypResult( CBotTypPointer, "object" ) ); pClassObject->AddUpdateFunc( rMajObject ); InitClassFILE(); AfxEnableControlContainer(); // Standard initialization #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif // Change the registry key under which our settings are stored. SetRegistryKey(_T("Local AppWizard-Generated Applications")); LoadStdProfileSettings(); // Load standard INI file options (including MRU) // Register document templates CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_TESTCBTYPE, RUNTIME_CLASS(CTestCBotDoc), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(CTestCBotView)); AddDocTemplate(pDocTemplate); // create main MDI Frame window CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame; // Parse command line for standard shell commands, DDE, file open CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); if (m_lpCmdLine[0] == 0) { CString Filename = GetProfileString(szSection, szFilename); if (Filename.IsEmpty()) Filename = "TstCbot.txt"; else OpenDocumentFile(Filename); } else // Dispatch commands specified on the command line if (!ProcessShellCommand(cmdInfo)) return FALSE; pMainFrame->ShowWindow(m_nCmdShow); pMainFrame->UpdateWindow(); return TRUE; }
bool CBotTwoOpExpr::Execute(CBotStack* &pStack) { CBotStack* pStk1 = pStack->AddStack(this); // adds an item to the stack // or return in case of recovery // if ( pStk1 == EOX ) return true; // according to recovery, it may be in one of two states if ( pStk1->GetState() == 0 ) // first state, evaluates the left operand { if (!m_leftop->Execute(pStk1) ) return false; // interrupted here? // for OR and AND logic does not evaluate the second expression if not necessary if ( (GetTokenType() == ID_LOG_AND || GetTokenType() == ID_TXT_AND ) && pStk1->GetVal() == false ) { CBotVar* res = CBotVar::Create("", CBotTypBoolean); res->SetValInt(false); pStk1->SetVar(res); return pStack->Return(pStk1); // transmits the result } if ( (GetTokenType() == ID_LOG_OR||GetTokenType() == ID_TXT_OR) && pStk1->GetVal() == true ) { CBotVar* res = CBotVar::Create("", CBotTypBoolean); res->SetValInt(true); pStk1->SetVar(res); return pStack->Return(pStk1); // transmits the result } // passes to the next step pStk1->SetState(1); // ready for further } // requires a little more stack to avoid touching the result // of which is left on the stack, precisely CBotStack* pStk2 = pStk1->AddStack(); // adds an item to the stack // or return in case of recovery // 2e état, évalue l'opérande de droite if ( pStk2->GetState() == 0 ) { if ( !m_rightop->Execute(pStk2) ) return false; // interrupted here? pStk2->IncState(); } assert(pStk1->GetVar() != nullptr && pStk2->GetVar() != nullptr); CBotTypResult type1 = pStk1->GetVar()->GetTypResult(); // what kind of results? CBotTypResult type2 = pStk2->GetVar()->GetTypResult(); CBotStack* pStk3 = pStk2->AddStack(this); // adds an item to the stack if ( pStk3->IfStep() ) return false; // shows the operation if step by step // creates a temporary variable to put the result // what kind of result? int TypeRes = std::max(type1.GetType(), type2.GetType()); // see "any type convertible chain" in compile method if ( GetTokenType() == ID_ADD && (type1.Eq(CBotTypString) || type2.Eq(CBotTypString)) ) { TypeRes = CBotTypString; } switch ( GetTokenType() ) { case ID_LOG_OR: case ID_LOG_AND: case ID_TXT_OR: case ID_TXT_AND: case ID_EQ: case ID_NE: case ID_HI: case ID_LO: case ID_HS: case ID_LS: TypeRes = CBotTypBoolean; break; case ID_DIV: TypeRes = std::max(TypeRes, static_cast<int>(CBotTypFloat)); } // creates a variable for the result CBotVar* result = CBotVar::Create("", TypeRes); // get left and right operands CBotVar* left = pStk1->GetVar(); CBotVar* right = pStk2->GetVar(); // creates a variable to perform the calculation in the appropriate type if ( TypeRes != CBotTypString ) // keep string conversion { TypeRes = std::max(type1.GetType(), type2.GetType()); } else { left->Update(nullptr); right->Update(nullptr); } if ( GetTokenType() == ID_ADD && type1.Eq(CBotTypString) ) { TypeRes = CBotTypString; } CBotVar* temp; if ( TypeRes == CBotTypPointer ) TypeRes = CBotTypNullPointer; if ( TypeRes == CBotTypClass ) temp = CBotVar::Create("", CBotTypResult(CBotTypIntrinsic, type1.GetClass() ) ); else temp = CBotVar::Create("", TypeRes ); CBotError err = CBotNoErr; // is a operation according to request switch (GetTokenType()) { case ID_ADD: if ( !IsNan(left, right, &err) ) result->Add(left , right); // addition break; case ID_SUB: if ( !IsNan(left, right, &err) ) result->Sub(left , right); // substraction break; case ID_MUL: if ( !IsNan(left, right, &err) ) result->Mul(left , right); // multiplies break; case ID_POWER: if ( !IsNan(left, right, &err) ) result->Power(left , right); // power break; case ID_DIV: if ( !IsNan(left, right, &err) ) err = result->Div(left , right);// division break; case ID_MODULO: if ( !IsNan(left, right, &err) ) err = result->Modulo(left , right);// remainder of division break; case ID_LO: if ( !IsNan(left, right, &err) ) result->SetValInt(temp->Lo(left , right)); // lower break; case ID_HI: if ( !IsNan(left, right, &err) ) result->SetValInt(temp->Hi(left , right)); // top break; case ID_LS: if ( !IsNan(left, right, &err) ) result->SetValInt(temp->Ls(left , right)); // less than or equal break; case ID_HS: if ( !IsNan(left, right, &err) ) result->SetValInt(temp->Hs(left , right)); // greater than or equal break; case ID_EQ: if ( IsNan(left, right) ) result->SetValInt(left->GetInit() == right->GetInit()) ; else result->SetValInt(temp->Eq(left , right)); // equal break; case ID_NE: if ( IsNan(left, right) ) result->SetValInt(left ->GetInit() != right->GetInit()) ; else result->SetValInt(temp->Ne(left , right)); // different break; case ID_TXT_AND: case ID_LOG_AND: case ID_AND: if ( !IsNan(left, right, &err) ) result->And(left , right); // AND break; case ID_TXT_OR: case ID_LOG_OR: case ID_OR: if ( !IsNan(left, right, &err) ) result->Or(left , right); // OR break; case ID_XOR: if ( !IsNan(left, right, &err) ) result->XOr(left , right); // exclusive OR break; case ID_ASR: if ( !IsNan(left, right, &err) ) result->ASR(left , right); break; case ID_SR: if ( !IsNan(left, right, &err) ) result->SR(left , right); break; case ID_SL: if ( !IsNan(left, right, &err) ) result->SL(left , right); break; default: assert(0); } delete temp; pStk2->SetVar(result); // puts the result on the stack if ( err ) pStk2->SetError(err, &m_token); // and the possible error (division by zero) // pStk1->Return(pStk2); // releases the stack return pStack->Return(pStk2); // transmits the result }
CBotTypResult cShow( CBotVar* &pVar, void* pUser) { if ( pVar == NULL ) return CBotTypResult(5028); return CBotTypResult(0); // tous paramètres acceptés, void en retour }
CBotTypResult cPrint( CBotVar* &pVar, void* pUser) { return CBotTypResult(0); // tous paramètres acceptés, un entier en retour }
bool CBotVar::RestoreState(FILE* pf, CBotVar* &pVar) { unsigned short w, wi, prv, st; float ww; CBotString name, s; delete pVar; pVar = NULL; CBotVar* pNew = NULL; CBotVar* pPrev = NULL; while ( true ) // retrieves a list { if (!ReadWord(pf, w)) return false; // private or type? if ( w == 0 ) return true; CBotString defnum; if ( w == 200 ) { if (!ReadString(pf, defnum)) return false; // number with identifier if (!ReadWord(pf, w)) return false; // type } prv = 100; st = 0; if ( w >= 100 ) { prv = w; if (!ReadWord(pf, st)) return false; // static if (!ReadWord(pf, w)) return false; // type } if ( w == CBotTypClass ) w = CBotTypIntrinsic; // necessarily intrinsic if (!ReadWord(pf, wi)) return false; // init ? if (!ReadString(pf, name)) return false; // variable name CBotToken token(name, CBotString()); switch (w) { case CBotTypInt: case CBotTypBoolean: pNew = CBotVar::Create(&token, w); // creates a variable if (!ReadWord(pf, w)) return false; pNew->SetValInt(static_cast<short>(w), defnum); break; case CBotTypFloat: pNew = CBotVar::Create(&token, w); // creates a variable if (!ReadFloat(pf, ww)) return false; pNew->SetValFloat(ww); break; case CBotTypString: pNew = CBotVar::Create(&token, w); // creates a variable if (!ReadString(pf, s)) return false; pNew->SetValString(s); break; // returns an intrinsic object or element of an array case CBotTypIntrinsic: case CBotTypArrayBody: { CBotTypResult r; long id; if (!ReadType(pf, r)) return false; // complete type if (!ReadLong(pf, id) ) return false; // if (!ReadString(pf, s)) return false; { CBotVar* p = NULL; if ( id ) p = CBotVarClass::Find(id) ; pNew = new CBotVarClass(&token, r); // directly creates an instance // attention cptuse = 0 if ( !RestoreState(pf, (static_cast<CBotVarClass*>(pNew))->m_pVar)) return false; pNew->SetIdent(id); if ( p != NULL ) { delete pNew; pNew = p; // resume known element } } } break; case CBotTypPointer: case CBotTypNullPointer: if (!ReadString(pf, s)) return false; { pNew = CBotVar::Create(&token, CBotTypResult(w, s));// creates a variable // CBotVarClass* p = NULL; long id; ReadLong(pf, id); // if ( id ) p = CBotVarClass::Find(id); // found the instance (made by RestoreInstance) // returns a copy of the original instance CBotVar* pInstance = NULL; if ( !CBotVar::RestoreState( pf, pInstance ) ) return false; (static_cast<CBotVarPointer*>(pNew))->SetPointer( pInstance ); // and point over // if ( p != NULL ) (static_cast<CBotVarPointer*>(pNew))->SetPointer( p ); // rather this one } break; case CBotTypArrayPointer: { CBotTypResult r; if (!ReadType(pf, r)) return false; pNew = CBotVar::Create(&token, r); // creates a variable // returns a copy of the original instance CBotVar* pInstance = NULL; if ( !CBotVar::RestoreState( pf, pInstance ) ) return false; (static_cast<CBotVarPointer*>(pNew))->SetPointer( pInstance ); // and point over } break; default: ASM_TRAP(); } if ( pPrev != NULL ) pPrev->m_next = pNew; if ( pVar == NULL ) pVar = pNew; pNew->m_binit = wi; // pNew->SetInit(wi); pNew->SetStatic(st); pNew->SetPrivate(prv-100); pPrev = pNew; } return true; }
CBotTypResult cNull(CBotVar* &var, void* user) { if ( var != nullptr ) return CBotErrOverParam; return CBotTypResult(CBotTypFloat); }