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 ); }
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; }
// compiles a new function // bLocal allows of the declaration of parameters on the same level // as the elements belonging to the class for methods CBotFunction* CBotFunction::Compile(CBotToken* &p, CBotCStack* pStack, CBotFunction* finput, bool bLocal) { CBotToken* pp; CBotFunction* func = finput; if ( func == NULL ) func = new CBotFunction(); CBotCStack* pStk = pStack->TokenStack(p, bLocal); // func->m_nFuncIdent = CBotVar::NextUniqNum(); while (true) { if ( IsOfType(p, ID_PUBLIC) ) { func->m_bPublic = true; continue; } pp = p; if ( IsOfType(p, ID_EXTERN) ) { func->m_extern = pp; // for the position of the word "extern" func->m_bExtern = true; // func->m_bPublic = true; // therefore also public! continue; } break; } func->m_retToken = *p; // CBotClass* pClass; func->m_retTyp = TypeParam(p, pStk); // type of the result if (func->m_retTyp.GetType() >= 0) { CBotToken* pp = p; func->m_token = *p; if ( IsOfType(p, ID_NOT) ) { CBotToken d("~" + p->GetString()); func->m_token = d; } // un nom de fonction est-il là ? if (IsOfType(p, TokenTypVar)) { if ( IsOfType( p, ID_DBLDOTS ) ) // method for a class { func->m_MasterClass = pp->GetString(); CBotClass* pClass = CBotClass::Find(pp); if ( pClass == NULL ) goto bad; // pp = p; func->m_token = *p; if (!IsOfType(p, TokenTypVar)) goto bad; } func->m_openpar = p; func->m_Param = CBotDefParam::Compile( p, pStk ); func->m_closepar = p->GetPrev(); if (pStk->IsOk()) { pStk->SetRetType(func->m_retTyp); // for knowledge what type returns if (!func->m_MasterClass.IsEmpty()) { // return "this" known CBotVar* pThis = CBotVar::Create("this", CBotTypResult( CBotTypClass, func->m_MasterClass )); pThis->SetInit(2); // pThis->SetUniqNum(func->m_nThisIdent = -2); //CBotVar::NextUniqNum() will not pThis->SetUniqNum(-2); pStk->AddVar(pThis); // initialize variables acording to This // only saves the pointer to the first, // the rest is chained CBotVar* pv = pThis->GetItemList(); // int num = 1; while (pv != NULL) { CBotVar* pcopy = CBotVar::Create(pv); // pcopy->SetInit(2); pcopy->Copy(pv); pcopy->SetPrivate(pv->GetPrivate()); // pcopy->SetUniqNum(pv->GetUniqNum()); //num++); pStk->AddVar(pcopy); pv = pv->GetNext(); } } // and compiles the following instruction block func->m_openblk = p; func->m_Block = CBotBlock::Compile(p, pStk, false); func->m_closeblk = p->GetPrev(); if ( pStk->IsOk() ) { if ( func->m_bPublic ) // public function, return known for all { CBotFunction::AddPublic(func); } return pStack->ReturnFunc(func, pStk); } } } bad: pStk->SetError(TX_NOFONC, p); } pStk->SetError(TX_NOTYP, p); if ( finput == NULL ) delete func; return pStack->ReturnFunc(NULL, pStk); }