[colobot] 24/74: Add support for circular references

Didier Raboud odyx at moszumanska.debian.org
Mon Nov 7 07:50:01 UTC 2016


This is an automated email from the git hooks/post-receive script.

odyx pushed a commit to branch debian/master
in repository colobot.

commit 66218319ddeb7aa5fd3a236c2c1641679e554237
Author: melex750 <melex750 at users.noreply.github.com>
Date:   Tue Aug 9 11:59:07 2016 -0400

    Add support for circular references
    
    Issue #433
---
 src/CBot/CBotClass.cpp   | 33 +++++++++++++++++++++++++++++++--
 src/CBot/CBotClass.h     | 10 ++++++++++
 src/CBot/CBotProgram.cpp |  4 ++++
 3 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/src/CBot/CBotClass.cpp b/src/CBot/CBotClass.cpp
index 70c72ef..4551076 100644
--- a/src/CBot/CBotClass.cpp
+++ b/src/CBot/CBotClass.cpp
@@ -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;
     }
@@ -522,6 +531,26 @@ CBotClass* CBotClass::Compile1(CBotToken* &p, CBotCStack* pStack)
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+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)
 {
     bool    bStatic = false;
diff --git a/src/CBot/CBotClass.h b/src/CBot/CBotClass.h
index 234f578..2fc494d 100644
--- a/src/CBot/CBotClass.h
+++ b/src/CBot/CBotClass.h
@@ -292,6 +292,14 @@ public:
                                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
      * \param pStack
@@ -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
diff --git a/src/CBot/CBotProgram.cpp b/src/CBot/CBotProgram.cpp
index d0284ea..77dac39 100644
--- a/src/CBot/CBotProgram.cpp
+++ b/src/CBot/CBotProgram.cpp
@@ -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);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/colobot.git



More information about the Pkg-games-commits mailing list