Add support for circular references

Issue 
dev-new-models
melex750 2016-08-09 11:59:07 -04:00
parent 210b5c295d
commit 66218319dd
3 changed files with 45 additions and 2 deletions

View File

@ -504,16 +504,25 @@ CBotClass* CBotClass::Compile1(CBotToken* &p, CBotCStack* pStack)
classe->Purge(); // empty the old definitions // TODO: Doesn't this remove all classes of the current program?
classe->m_IsDef = false; // current definition
classe->m_pOpenblk = p;
if ( !IsOfType( p, ID_OPBLK) )
{
pStack->SetError(CBotErrOpenBlock, p);
return nullptr;
}
while ( pStack->IsOk() && !IsOfType( p, ID_CLBLK ) )
int level = 1;
do // skip over the definition
{
classe->CompileDefItem(p, pStack, false);
int type = p->GetType();
p = p->GetNext();
if (type == ID_OPBLK) level++;
if (type == ID_CLBLK) level--;
}
while (level > 0 && p != nullptr);
if (level > 0) pStack->SetError(CBotErrCloseBlock, classe->m_pOpenblk);
if (pStack->IsOk()) return classe;
}
@ -521,6 +530,26 @@ CBotClass* CBotClass::Compile1(CBotToken* &p, CBotCStack* pStack)
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
void CBotClass::DefineClasses(CBotClass* pClass, CBotCStack* pStack)
{
while (pClass != nullptr)
{
CBotClass* pParent = pClass->m_parent;
pClass->m_nbVar = (pParent == nullptr) ? 0 : pParent->m_nbVar;
CBotToken* p = pClass->m_pOpenblk->GetNext();
while (pStack->IsOk() && !IsOfType(p, ID_CLBLK))
{
pClass->CompileDefItem(p, pStack, false);
}
if (!pStack->IsOk()) return;
pClass = pClass->GetNext();
}
}
////////////////////////////////////////////////////////////////////////////////
bool CBotClass::CompileDefItem(CBotToken* &p, CBotCStack* pStack, bool bSecond)
{

View File

@ -291,6 +291,14 @@ public:
static CBotClass* Compile1(CBotToken* &p,
CBotCStack* pStack);
/*!
* \brief DefineClasses Calls CompileDefItem for each class in a list
* of classes, defining fields and pre-compiling methods.
* \param pClass List of classes
* \param pStack
*/
static void DefineClasses(CBotClass* pClass, CBotCStack* pStack);
/*!
* \brief CompileDefItem
* \param p
@ -385,6 +393,8 @@ private:
CBotFunction* m_pMethod;
void (*m_rUpdate)(CBotVar* thisVar, void* user);
CBotToken* m_pOpenblk;
//! How many times the program currently holding the lock called Lock()
int m_lockCurrentCount = 0;
//! Programs waiting for lock. m_lockProg[0] is the program currently holding the lock, if any

View File

@ -99,6 +99,10 @@ bool CBotProgram::Compile(const std::string& program, std::vector<std::string>&
else m_functions->AddNext(next);
}
}
// Define fields and pre-compile methods for each class in this program
if (pStack->IsOk()) CBotClass::DefineClasses(m_classes, pStack.get());
if ( !pStack->IsOk() )
{
m_error = pStack->GetError(m_errorStart, m_errorEnd);