// 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); }