[colobot] 15/100: Refactor CBotClass and CBotFunction list to std::list

Didier Raboud odyx at moszumanska.debian.org
Thu Jun 1 18:10:14 UTC 2017


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

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

commit 191151eb7b4674d69a1d52d88c1261fd13d5a893
Author: krzys-h <krzys_h at interia.pl>
Date:   Fri Nov 11 19:35:43 2016 +0100

    Refactor CBotClass and CBotFunction list to std::list
---
 src/CBot/CBotCStack.cpp             |   4 +-
 src/CBot/CBotClass.cpp              |  38 +++++--------
 src/CBot/CBotClass.h                |  11 ++--
 src/CBot/CBotDebug.cpp              |   8 +--
 src/CBot/CBotInstr/CBotFunction.cpp | 104 +++++++++++++++++-------------------
 src/CBot/CBotInstr/CBotFunction.h   |  12 ++---
 src/CBot/CBotProgram.cpp            |  92 ++++++++++++++-----------------
 src/CBot/CBotProgram.h              |  13 ++---
 test/unit/CBot/CBot_test.cpp        |   2 +-
 9 files changed, 126 insertions(+), 158 deletions(-)

diff --git a/src/CBot/CBotCStack.cpp b/src/CBot/CBotCStack.cpp
index ef3c409..a2f191d 100644
--- a/src/CBot/CBotCStack.cpp
+++ b/src/CBot/CBotCStack.cpp
@@ -369,8 +369,7 @@ bool CBotCStack::CheckCall(CBotToken* &pToken, CBotDefParam* pParam)
 
     if ( m_prog->GetExternalCalls()->CheckCall(name) ) return true;
 
-    CBotFunction*    pp = m_prog->GetFunctions();
-    while ( pp != nullptr )
+    for (CBotFunction* pp : m_prog->GetFunctions())
     {
         if ( pToken->GetString() == pp->GetName() )
         {
@@ -378,7 +377,6 @@ bool CBotCStack::CheckCall(CBotToken* &pToken, CBotDefParam* pParam)
             if ( pp->CheckParam( pParam ) )
                 return true;
         }
-        pp = pp->GetNext();
     }
 
     for (CBotFunction* pp : CBotFunction::m_publicFunctions)
diff --git a/src/CBot/CBotClass.cpp b/src/CBot/CBotClass.cpp
index bd95605..77998b3 100644
--- a/src/CBot/CBotClass.cpp
+++ b/src/CBot/CBotClass.cpp
@@ -56,7 +56,6 @@ CBotClass::CBotClass(const std::string& name,
     m_name      = name;
     m_pVar      = nullptr;
     m_pCalls    = nullptr;
-    m_pMethod   = nullptr;
     m_rUpdate   = nullptr;
     m_IsDef     = true;
     m_bIntrinsic= bIntrinsic;
@@ -72,7 +71,6 @@ CBotClass::~CBotClass()
 
     delete  m_pVar;
     delete  m_pCalls;
-    delete  m_pMethod;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -98,14 +96,11 @@ void CBotClass::Purge()
     m_pVar      = nullptr;
     delete      m_pCalls;
     m_pCalls    = nullptr;
-    delete      m_pMethod;
-    m_pMethod   = nullptr;
+    for (CBotFunction* f : m_pMethod) delete f;
+    m_pMethod.clear();
     m_IsDef     = false;
 
     m_nbVar     = m_parent == nullptr ? 0 : m_parent->m_nbVar;
-
-    if (m_next != nullptr) m_next->Purge();
-    m_next = nullptr;          // no longer belongs to this chain
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -455,8 +450,7 @@ bool CBotClass::CheckCall(CBotProgram* program, CBotDefParam* pParam, CBotToken*
 
     if ( program->GetExternalCalls()->CheckCall(name) ) return true;
 
-    CBotFunction*   pp = m_pMethod;
-    while ( pp != nullptr )
+    for (CBotFunction* pp : m_pMethod)
     {
         if ( pToken->GetString() == pp->GetName() )
         {
@@ -464,7 +458,6 @@ bool CBotClass::CheckCall(CBotProgram* program, CBotDefParam* pParam, CBotToken*
             if ( pp->CheckParam( pParam ) )
                 return true;
         }
-        pp = pp->GetNext();
     }
 
     return false;
@@ -506,7 +499,7 @@ CBotClass* CBotClass::Compile1(CBotToken* &p, CBotCStack* pStack)
             }
         }
         CBotClass* classe = (pOld == nullptr) ? new CBotClass(name, pPapa) : pOld;
-        classe->Purge();                            // empty the old definitions // TODO: Doesn't this remove all classes of the current program?
+        classe->Purge();                            // empty the old definitions
         classe->m_IsDef = false;                    // current definition
 
         classe->m_pOpenblk = p;
@@ -536,9 +529,9 @@ CBotClass* CBotClass::Compile1(CBotToken* &p, CBotCStack* pStack)
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-void CBotClass::DefineClasses(CBotClass* pClass, CBotCStack* pStack)
+void CBotClass::DefineClasses(std::list<CBotClass*> pClassList, CBotCStack* pStack)
 {
-    while (pClass != nullptr)
+    for (CBotClass* pClass : pClassList)
     {
         CBotClass* pParent = pClass->m_parent;
         pClass->m_nbVar = (pParent == nullptr) ? 0 : pParent->m_nbVar;
@@ -550,8 +543,6 @@ void CBotClass::DefineClasses(CBotClass* pClass, CBotCStack* pStack)
         }
 
         if (!pStack->IsOk()) return;
-
-        pClass = pClass->GetNext();
     }
 }
 
@@ -627,28 +618,25 @@ bool CBotClass::CompileDefItem(CBotToken* &p, CBotCStack* pStack, bool bSecond)
                 if ( !bSecond )
                 {
                     p = pBase;
-                    CBotFunction* f =
-                    CBotFunction::Compile1(p, pStack, this);
+                    CBotFunction* f = CBotFunction::Compile1(p, pStack, this);
 
                     if ( f == nullptr ) return false;
 
-                    if (m_pMethod == nullptr) m_pMethod = f;
-                    else m_pMethod->AddNext(f);
+                    m_pMethod.push_back(f);
                 }
                 else
                 {
                     // return a method precompiled in pass 1
-                    CBotFunction*   pf = m_pMethod;
                     CBotToken* ppp = p;
                     CBotCStack* pStk = pStack->TokenStack(nullptr, true);
                     CBotDefParam* params = CBotDefParam::Compile(p, pStk );
                     delete pStk;
                     p = ppp;
-                    while ( pf != nullptr )                             // search by name and parameters
-                    {
-                        if (pf->GetName() == pp && pf->CheckParam( params )) break;
-                        pf = pf->GetNext();
-                    }
+                    std::list<CBotFunction*>::iterator pfIter = std::find_if(m_pMethod.begin(), m_pMethod.end(), [&pp, &params](CBotFunction* x) {
+                        return x->GetName() == pp && x->CheckParam( params );
+                    });
+                    assert(pfIter != m_pMethod.end());
+                    CBotFunction* pf = *pfIter;
 
                     bool bConstructor = (pp == GetName());
                     CBotCStack* pile = pStack->TokenStack(nullptr, true);
diff --git a/src/CBot/CBotClass.h b/src/CBot/CBotClass.h
index 2fc494d..94ab341 100644
--- a/src/CBot/CBotClass.h
+++ b/src/CBot/CBotClass.h
@@ -26,6 +26,7 @@
 #include <string>
 #include <deque>
 #include <set>
+#include <list>
 
 namespace CBot
 {
@@ -102,7 +103,7 @@ class CBotCStack;
  *  float y = var->GetValFloat();
  *  \endcode
  */
-class CBotClass : public CBotLinkedList<CBotClass>
+class CBotClass
 {
 public:
     /*!
@@ -294,10 +295,10 @@ public:
     /*!
      * \brief DefineClasses Calls CompileDefItem for each class in a list
      * of classes, defining fields and pre-compiling methods.
-     * \param pClass List of classes
+     * \param pClassList List of classes
      * \param pStack
      */
-    static void DefineClasses(CBotClass* pClass, CBotCStack* pStack);
+    static void DefineClasses(std::list<CBotClass*> pClassList, CBotCStack* pStack);
 
     /*!
      * \brief CompileDefItem
@@ -389,8 +390,8 @@ private:
     CBotVar* m_pVar;
     //! Linked list of all class external calls
     CBotCallMethode* m_pCalls;
-    //! Linked list of all class methods
-    CBotFunction* m_pMethod;
+    //! List of all class methods
+    std::list<CBotFunction*> m_pMethod{};
     void (*m_rUpdate)(CBotVar* thisVar, void* user);
 
     CBotToken* m_pOpenblk;
diff --git a/src/CBot/CBotDebug.cpp b/src/CBot/CBotDebug.cpp
index d71eac3..db0c559 100644
--- a/src/CBot/CBotDebug.cpp
+++ b/src/CBot/CBotDebug.cpp
@@ -36,9 +36,8 @@ void CBotDebug::DumpCompiledProgram(CBotProgram* program)
     std::stringstream ss;
     ss << "digraph {" << std::endl;
 
-    CBotFunction* func = program->GetFunctions();
     std::map<long, CBotFunction*> funcIdMap;
-    while (func != nullptr)
+    for (CBotFunction* func : program->GetFunctions())
     {
         funcIdMap[func->m_nFuncIdent] = func;
         func = func->GetNext();
@@ -111,9 +110,8 @@ void CBotDebug::DumpCompiledProgram(CBotProgram* program)
     {
         DumpInstr(program->m_entryPoint);
     }
-    func = program->GetFunctions();
     std::string prev = GetPointerAsString(program->m_entryPoint);
-    while (func != nullptr)
+    for (CBotFunction* func : program->GetFunctions())
     {
         if (func != program->m_entryPoint)
         {
@@ -122,8 +120,6 @@ void CBotDebug::DumpCompiledProgram(CBotProgram* program)
             //ss << prev << " -> " << GetPointerAsString(func) << " [style=invis]" << std::endl;
             prev = GetPointerAsString(func);
         }
-
-        func = func->GetNext();
     }
 
     ss << "}" << std::endl;
diff --git a/src/CBot/CBotInstr/CBotFunction.cpp b/src/CBot/CBotInstr/CBotFunction.cpp
index 2d92910..c8db69a 100644
--- a/src/CBot/CBotInstr/CBotFunction.cpp
+++ b/src/CBot/CBotInstr/CBotFunction.cpp
@@ -410,7 +410,7 @@ void CBotFunction::RestoreState(CBotVar** ppVars, CBotStack* &pj, CBotVar* pInst
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-CBotTypResult CBotFunction::CompileCall(CBotFunction* localFunctionList, const std::string &name, CBotVar** ppVars, long &nIdent)
+CBotTypResult CBotFunction::CompileCall(const std::list<CBotFunction*>& localFunctionList, const std::string &name, CBotVar** ppVars, long &nIdent)
 {
     CBotTypResult type;
     if (!FindLocalOrPublic(localFunctionList, nIdent, name, ppVars, type))
@@ -422,17 +422,16 @@ CBotTypResult CBotFunction::CompileCall(CBotFunction* localFunctionList, const s
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-CBotFunction* CBotFunction::FindLocalOrPublic(CBotFunction* localFunctionList, long &nIdent, const std::string &name,
+CBotFunction* CBotFunction::FindLocalOrPublic(const std::list<CBotFunction*>& localFunctionList, long &nIdent, const std::string &name,
                                               CBotVar** ppVars, CBotTypResult &TypeOrError, bool bPublic)
 {
     TypeOrError.SetType(CBotErrUndefCall);      // no routine of the name
-    CBotFunction*   pt;
 
     if ( nIdent )
     {
-        if ( localFunctionList != nullptr ) for ( pt = localFunctionList ; pt != nullptr ; pt = pt->GetNext() )
+        for (CBotFunction* pt : localFunctionList)
         {
-            if ( pt->m_nFuncIdent == nIdent )
+            if (pt->m_nFuncIdent == nIdent)
             {
                 TypeOrError = pt->m_retTyp;
                 return pt;
@@ -454,62 +453,59 @@ CBotFunction* CBotFunction::FindLocalOrPublic(CBotFunction* localFunctionList, l
 
     std::map<CBotFunction*, int> funcMap;
 
-    if ( localFunctionList != nullptr )
+    for (CBotFunction* pt : localFunctionList)
     {
-        for ( pt = localFunctionList ; pt != nullptr ; pt = pt->GetNext() )
+        if ( pt->m_token.GetString() == name )
         {
-            if ( pt->m_token.GetString() == name )
+            int i = 0;
+            int alpha = 0;                          // signature of parameters
+            // parameters are compatible?
+            CBotDefParam* pv = pt->m_param;         // expected list of parameters
+            CBotVar* pw = ppVars[i++];              // provided list parameter
+            while ( pv != nullptr && pw != nullptr)
             {
-                int i = 0;
-                int alpha = 0;                          // signature of parameters
-                // parameters are compatible?
-                CBotDefParam* pv = pt->m_param;         // expected list of parameters
-                CBotVar* pw = ppVars[i++];              // provided list parameter
-                while ( pv != nullptr && pw != nullptr)
-                {
-                    CBotTypResult paramType = pv->GetTypResult();
-                    CBotTypResult argType = pw->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC);
+                CBotTypResult paramType = pv->GetTypResult();
+                CBotTypResult argType = pw->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC);
 
-                    if (!TypesCompatibles(paramType, argType))
-                    {
-                        if ( funcMap.empty() ) TypeOrError.SetType(CBotErrBadParam);
-                        break;
-                    }
+                if (!TypesCompatibles(paramType, argType))
+                {
+                    if ( funcMap.empty() ) TypeOrError.SetType(CBotErrBadParam);
+                    break;
+                }
 
-                    if (paramType.Eq(CBotTypPointer) && !argType.Eq(CBotTypNullPointer))
-                    {
-                        CBotClass* c1 = paramType.GetClass();
-                        CBotClass* c2 = argType.GetClass();
-                        while (c2 != c1 && c2 != nullptr)    // implicit cast
-                        {
-                            alpha += 10;
-                            c2 = c2->GetParent();
-                        }
-                    }
-                    else
+                if (paramType.Eq(CBotTypPointer) && !argType.Eq(CBotTypNullPointer))
+                {
+                    CBotClass* c1 = paramType.GetClass();
+                    CBotClass* c2 = argType.GetClass();
+                    while (c2 != c1 && c2 != nullptr)    // implicit cast
                     {
-                        int d = pv->GetType() - pw->GetType(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC);
-                        alpha += d>0 ? d : -10*d;       // quality loss, 10 times more expensive!
+                        alpha += 10;
+                        c2 = c2->GetParent();
                     }
-                    pv = pv->GetNext();
-                    pw = ppVars[i++];
                 }
-                if ( pw != nullptr )
-                {
-                    if ( !funcMap.empty() ) continue;
-                    if ( TypeOrError.Eq(CBotErrLowParam) ) TypeOrError.SetType(CBotErrNbParam);
-                    if ( TypeOrError.Eq(CBotErrUndefCall)) TypeOrError.SetType(CBotErrOverParam);
-                    continue;                   // too many parameters
-                }
-                if ( pv != nullptr )
+                else
                 {
-                    if ( !funcMap.empty() ) continue;
-                    if ( TypeOrError.Eq(CBotErrOverParam) ) TypeOrError.SetType(CBotErrNbParam);
-                    if ( TypeOrError.Eq(CBotErrUndefCall) ) TypeOrError.SetType(CBotErrLowParam);
-                    continue;                   // not enough parameters
+                    int d = pv->GetType() - pw->GetType(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC);
+                    alpha += d>0 ? d : -10*d;       // quality loss, 10 times more expensive!
                 }
-                funcMap.insert( std::pair<CBotFunction*, int>(pt, alpha) );
+                pv = pv->GetNext();
+                pw = ppVars[i++];
+            }
+            if ( pw != nullptr )
+            {
+                if ( !funcMap.empty() ) continue;
+                if ( TypeOrError.Eq(CBotErrLowParam) ) TypeOrError.SetType(CBotErrNbParam);
+                if ( TypeOrError.Eq(CBotErrUndefCall)) TypeOrError.SetType(CBotErrOverParam);
+                continue;                   // too many parameters
+            }
+            if ( pv != nullptr )
+            {
+                if ( !funcMap.empty() ) continue;
+                if ( TypeOrError.Eq(CBotErrOverParam) ) TypeOrError.SetType(CBotErrNbParam);
+                if ( TypeOrError.Eq(CBotErrUndefCall) ) TypeOrError.SetType(CBotErrLowParam);
+                continue;                   // not enough parameters
             }
+            funcMap.insert( std::pair<CBotFunction*, int>(pt, alpha) );
         }
     }
 
@@ -600,7 +596,7 @@ CBotFunction* CBotFunction::FindLocalOrPublic(CBotFunction* localFunctionList, l
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-int CBotFunction::DoCall(CBotProgram* program, CBotFunction* localFunctionList, long &nIdent, const std::string &name,
+int CBotFunction::DoCall(CBotProgram* program, const std::list<CBotFunction*>& localFunctionList, long &nIdent, const std::string &name,
                          CBotVar** ppVars, CBotStack* pStack, CBotToken* pToken)
 {
     CBotTypResult   type;
@@ -674,7 +670,7 @@ int CBotFunction::DoCall(CBotProgram* program, CBotFunction* localFunctionList,
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-void CBotFunction::RestoreCall(CBotFunction* localFunctionList,
+void CBotFunction::RestoreCall(const std::list<CBotFunction*>& localFunctionList,
                                long &nIdent, const std::string &name, CBotVar** ppVars, CBotStack* pStack)
 {
     CBotTypResult   type;
@@ -732,7 +728,7 @@ void CBotFunction::RestoreCall(CBotFunction* localFunctionList,
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-int CBotFunction::DoCall(CBotFunction* localFunctionList, long &nIdent, const std::string &name, CBotVar* pThis,
+int CBotFunction::DoCall(const std::list<CBotFunction*>& localFunctionList, long &nIdent, const std::string &name, CBotVar* pThis,
                          CBotVar** ppVars, CBotStack* pStack, CBotToken* pToken, CBotClass* pClass)
 {
     CBotTypResult   type;
@@ -814,7 +810,7 @@ int CBotFunction::DoCall(CBotFunction* localFunctionList, long &nIdent, const st
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-bool CBotFunction::RestoreCall(CBotFunction* localFunctionList, long &nIdent, const std::string &name, CBotVar* pThis,
+bool CBotFunction::RestoreCall(const std::list<CBotFunction*>& localFunctionList, long &nIdent, const std::string &name, CBotVar* pThis,
                                CBotVar** ppVars, CBotStack* pStack, CBotClass* pClass)
 {
     CBotTypResult   type;
diff --git a/src/CBot/CBotInstr/CBotFunction.h b/src/CBot/CBotInstr/CBotFunction.h
index 6a0180f..3221496 100644
--- a/src/CBot/CBotInstr/CBotFunction.h
+++ b/src/CBot/CBotInstr/CBotFunction.h
@@ -106,7 +106,7 @@ public:
      * \return Type returned by the function or error code
      * \see FindLocalOrPublic
      */
-    static CBotTypResult CompileCall(CBotFunction* localFunctionList,
+    static CBotTypResult CompileCall(const std::list<CBotFunction*>& localFunctionList,
                                      const std::string &name, CBotVar** ppVars, long &nIdent);
 
     /*!
@@ -125,7 +125,7 @@ public:
      * \param bPublic Whether to look in public functions or not
      * \return Pointer to found CBotFunction instance, or nullptr in case of no match or ambiguity (see TypeOrError for error code)
      */
-    static CBotFunction* FindLocalOrPublic(CBotFunction* localFunctionList, long &nIdent, const std::string &name,
+    static CBotFunction* FindLocalOrPublic(const std::list<CBotFunction*>& localFunctionList, long &nIdent, const std::string &name,
                                            CBotVar** ppVars, CBotTypResult &TypeOrError, bool bPublic = true);
 
     /*!
@@ -140,7 +140,7 @@ public:
      * \return
      */
 
-    static int DoCall(CBotProgram* program, CBotFunction* localFunctionList, long &nIdent, const std::string &name,
+    static int DoCall(CBotProgram* program, const std::list<CBotFunction*>& localFunctionList, long &nIdent, const std::string &name,
                       CBotVar** ppVars, CBotStack* pStack, CBotToken* pToken);
 
     /*!
@@ -151,7 +151,7 @@ public:
      * \param ppVars
      * \param pStack
      */
-    static void RestoreCall(CBotFunction* localFunctionList,
+    static void RestoreCall(const std::list<CBotFunction*>& localFunctionList,
                             long &nIdent, const std::string &name, CBotVar** ppVars, CBotStack* pStack);
 
     /*!
@@ -167,7 +167,7 @@ public:
      * \param pClass
      * \return
      */
-    static int DoCall(CBotFunction* localFunctionList, long &nIdent, const std::string &name, CBotVar* pThis,
+    static int DoCall(const std::list<CBotFunction*>& localFunctionList, long &nIdent, const std::string &name, CBotVar* pThis,
                       CBotVar** ppVars, CBotStack* pStack, CBotToken* pToken, CBotClass* pClass);
 
     /*!
@@ -181,7 +181,7 @@ public:
      * \param pClass
      * \return Returns true if the method call was restored.
      */
-    static bool RestoreCall(CBotFunction* localFunctionList, long &nIdent, const std::string &name, CBotVar* pThis,
+    static bool RestoreCall(const std::list<CBotFunction*>& localFunctionList, long &nIdent, const std::string &name, CBotVar* pThis,
                             CBotVar** ppVars, CBotStack* pStack, CBotClass* pClass);
 
     /*!
diff --git a/src/CBot/CBotProgram.cpp b/src/CBot/CBotProgram.cpp
index 6e8b6a6..978c641 100644
--- a/src/CBot/CBotProgram.cpp
+++ b/src/CBot/CBotProgram.cpp
@@ -30,6 +30,8 @@
 
 #include "CBot/stdlib/stdlib.h"
 
+#include <algorithm>
+
 namespace CBot
 {
 
@@ -47,27 +49,30 @@ CBotProgram::CBotProgram(CBotVar* thisVar)
 CBotProgram::~CBotProgram()
 {
 //  delete  m_classes;
-    if (m_classes != nullptr) m_classes->Purge();
-    m_classes = nullptr;
+    for (CBotClass* c : m_classes)
+        c->Purge();
+    m_classes.clear();
 
     CBotClass::FreeLock(this);
 
-    delete m_functions;
-    if (m_stack != nullptr) m_stack->Delete();
+    for (CBotFunction* f : m_functions) delete f;
+    m_functions.clear();
 }
 
-bool CBotProgram::Compile(const std::string& program, std::vector<std::string>& functions, void* pUser)
+bool CBotProgram::Compile(const std::string& program, std::vector<std::string>& externFunctions, void* pUser)
 {
     // Cleanup the previously compiled program
     Stop();
 
-//  delete      m_classes;
-    if (m_classes != nullptr) m_classes->Purge();      // purge the old definitions of classes
-                            // but without destroying the object
-    m_classes = nullptr;
-    delete m_functions; m_functions = nullptr;
+    for (CBotClass* c : m_classes)
+        c->Purge();      // purge the old definitions of classes
+                         // but without destroying the object
+
+    m_classes.clear();
+    for (CBotFunction* f : m_functions) delete f;
+    m_functions.clear();
 
-    functions.clear();
+    externFunctions.clear();
     m_error = CBotNoErr;
 
     // Step 1. Process the code into tokens
@@ -88,15 +93,11 @@ bool CBotProgram::Compile(const std::string& program, std::vector<std::string>&
         if ( p->GetType() == ID_CLASS ||
             ( p->GetType() == ID_PUBLIC && p->GetNext()->GetType() == ID_CLASS ))
         {
-            CBotClass*  nxt = CBotClass::Compile1(p, pStack.get());
-            if (m_classes == nullptr ) m_classes = nxt;
-            else m_classes->AddNext(nxt);
+            m_classes.push_back(CBotClass::Compile1(p, pStack.get()));
         }
         else
         {
-            CBotFunction*   next = CBotFunction::Compile1(p, pStack.get(), nullptr);
-            if (m_functions == nullptr ) m_functions = next;
-            else m_functions->AddNext(next);
+            m_functions.push_back(CBotFunction::Compile1(p, pStack.get(), nullptr));
         }
     }
 
@@ -106,17 +107,14 @@ bool CBotProgram::Compile(const std::string& program, std::vector<std::string>&
     if ( !pStack->IsOk() )
     {
         m_error = pStack->GetError(m_errorStart, m_errorEnd);
-        delete m_functions;
-        m_functions = nullptr;
+        for (CBotFunction* f : m_functions) delete f;
+        m_functions.clear();
         return false;
     }
 
     // Step 3. Real compilation
-//  CBotFunction*   temp = nullptr;
-    CBotFunction*   next = m_functions;      // rewind the list
-
+    std::list<CBotFunction*>::iterator next = m_functions.begin();
     p  = tokens.get()->GetNext();                             // returns to the beginning
-
     while ( pStack->IsOk() && p != nullptr && p->GetType() != 0 )
     {
         if ( IsOfType(p, ID_SEP) ) continue;                // semicolons lurking
@@ -128,43 +126,37 @@ bool CBotProgram::Compile(const std::string& program, std::vector<std::string>&
         }
         else
         {
-            CBotFunction::Compile(p, pStack.get(), next);
-            if (next->IsExtern()) functions.push_back(next->GetName()/* + next->GetParams()*/);
-            if (next->IsPublic()) CBotFunction::AddPublic(next);
-            next->m_pProg = this;                           // keeps pointers to the module
-            next = next->GetNext();
+            CBotFunction::Compile(p, pStack.get(), *next);
+            if ((*next)->IsExtern()) externFunctions.push_back((*next)->GetName()/* + next->GetParams()*/);
+            if ((*next)->IsPublic()) CBotFunction::AddPublic(*next);
+            (*next)->m_pProg = this;                           // keeps pointers to the module
+            ++next;
         }
     }
 
-//  delete m_Prog;          // the list of first pass
-//  m_Prog = temp;          // list of the second pass
-
     if ( !pStack->IsOk() )
     {
         m_error = pStack->GetError(m_errorStart, m_errorEnd);
-        delete m_functions;
-        m_functions = nullptr;
+        for (CBotFunction* f : m_functions) delete f;
+        m_functions.clear();
     }
 
-    return (m_functions != nullptr);
+    return !m_functions.empty();
 }
 
 bool CBotProgram::Start(const std::string& name)
 {
     Stop();
 
-    m_entryPoint = m_functions;
-    while (m_entryPoint != nullptr)
-    {
-        if (m_entryPoint->GetName() == name ) break;
-        m_entryPoint = m_entryPoint->GetNext();
-    }
-
-    if (m_entryPoint == nullptr)
+    auto it = std::find_if(m_functions.begin(), m_functions.end(), [&name](CBotFunction* x) {
+        return x->GetName() == name;
+    });
+    if (it == m_functions.end())
     {
         m_error = CBotErrNoRun;
         return false;
     }
+    m_entryPoint = *it;
 
     m_stack = CBotStack::AllocateStack();
     m_stack->SetProgram(this);
@@ -174,16 +166,12 @@ bool CBotProgram::Start(const std::string& name)
 
 bool CBotProgram::GetPosition(const std::string& name, int& start, int& stop, CBotGet modestart, CBotGet modestop)
 {
-    CBotFunction* p = m_functions;
-    while (p != nullptr)
-    {
-        if ( p->GetName() == name ) break;
-        p = p->GetNext();
-    }
-
-    if ( p == nullptr ) return false;
+    auto it = std::find_if(m_functions.begin(), m_functions.end(), [&name](CBotFunction* x) {
+        return x->GetName() == name;
+    });
+    if (it == m_functions.end()) return false;
 
-    p->GetPosition(start, stop, modestart, modestop);
+    (*it)->GetPosition(start, stop, modestart, modestop);
     return true;
 }
 
@@ -288,7 +276,7 @@ bool CBotProgram::GetError(CBotError& code, int& start, int& end, CBotProgram*&
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-CBotFunction* CBotProgram::GetFunctions()
+const std::list<CBotFunction*>& CBotProgram::GetFunctions()
 {
     return m_functions;
 }
diff --git a/src/CBot/CBotProgram.h b/src/CBot/CBotProgram.h
index 165defc..d90fb0e 100644
--- a/src/CBot/CBotProgram.h
+++ b/src/CBot/CBotProgram.h
@@ -23,6 +23,7 @@
 #include "CBot/CBotEnums.h"
 
 #include <vector>
+#include <list>
 
 namespace CBot
 {
@@ -124,12 +125,12 @@ public:
      * 3. Second pass - compiling definitions of all functions and classes
      *
      * \param program Code to compile
-     * \param[out] functions Returns the names of functions declared as extern
+     * \param[out] externFunctions Returns the names of functions declared as extern
      * \param pUser Optional pointer to be passed to compile function (see AddFunction())
      * \return true if compilation is successful, false if an compilation error occurs
      * \see GetError() to retrieve the error
      */
-    bool Compile(const std::string& program, std::vector<std::string>& functions, void* pUser = nullptr);
+    bool Compile(const std::string& program, std::vector<std::string>& externFunctions, void* pUser = nullptr);
 
     /**
      * \brief Returns the last error
@@ -328,9 +329,9 @@ public:
      *
      * This list includes all the functions (not only extern)
      *
-     * \return Linked list of CBotFunction instances
+     * \return List of CBotFunction instances
      */
-    CBotFunction* GetFunctions();
+    const std::list<CBotFunction*>& GetFunctions();
 
     /**
      * \brief Returns static list of all registered external calls
@@ -341,11 +342,11 @@ private:
     //! All external calls
     static CBotExternalCallList* m_externalCalls;
     //! All user-defined functions
-    CBotFunction* m_functions = nullptr;
+    std::list<CBotFunction*> m_functions{};
     //! The entry point function
     CBotFunction* m_entryPoint = nullptr;
     //! Classes defined in this program
-    CBotClass* m_classes = nullptr;
+    std::list<CBotClass*> m_classes{};
     //! Execution stack
     CBotStack* m_stack = nullptr;
     //! "this" variable
diff --git a/test/unit/CBot/CBot_test.cpp b/test/unit/CBot/CBot_test.cpp
index 797a674..0dae25e 100644
--- a/test/unit/CBot/CBot_test.cpp
+++ b/test/unit/CBot/CBot_test.cpp
@@ -1012,7 +1012,7 @@ TEST_F(CBotUT, ClassInheritanceAssignment)
         "public class BaseClass {}\n"
         "public class MidClass extends BaseClass {}\n"
         "public class SubClass extends MidClass {}\n"
-        "extern void ClassInheritanceVars()\n"
+        "extern void ClassInheritanceAssignment()\n"
         "{\n"
         "    BaseClass bc = new MidClass();\n"
         "    MidClass  mc = bc;\n"

-- 
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