[colobot] 214/377: CBot compiled instruction graphs; some code cleanup

Didier Raboud odyx at moszumanska.debian.org
Wed Mar 30 13:34:18 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 e3c53f99122baac215cbc934bfccde26a5988f00
Author: krzys-h <krzys_h at interia.pl>
Date:   Sun Dec 27 16:51:57 2015 +0100

    CBot compiled instruction graphs; some code cleanup
---
 src/CBot/CBotDebug.cpp                          | 152 ++++++++++++++++++++++++
 src/CBot/{CBotInstr/CBotEmpty.h => CBotDebug.h} |  25 +---
 src/CBot/CBotInstr/CBotBoolean.cpp              |  12 +-
 src/CBot/CBotInstr/CBotBoolean.h                |   4 +
 src/CBot/CBotInstr/CBotBreak.cpp                |   6 +-
 src/CBot/CBotInstr/CBotBreak.h                  |   3 +
 src/CBot/CBotInstr/CBotCase.cpp                 |  20 ++--
 src/CBot/CBotInstr/CBotCase.h                   |   6 +-
 src/CBot/CBotInstr/CBotCatch.cpp                |  37 +++---
 src/CBot/CBotInstr/CBotCatch.h                  |   7 +-
 src/CBot/CBotInstr/CBotClassInst.cpp            |  22 ++--
 src/CBot/CBotInstr/CBotClassInst.h              |   9 +-
 src/CBot/CBotInstr/CBotDo.cpp                   |  36 ++++--
 src/CBot/CBotInstr/CBotDo.h                     |   9 +-
 src/CBot/CBotInstr/CBotEmpty.h                  |   3 +
 src/CBot/CBotInstr/CBotExprAlpha.cpp            |   6 +-
 src/CBot/CBotInstr/CBotExprAlpha.h              |   4 +
 src/CBot/CBotInstr/CBotExprBool.cpp             |   1 -
 src/CBot/CBotInstr/CBotExprBool.h               |   3 +
 src/CBot/CBotInstr/CBotExprNan.cpp              |   1 -
 src/CBot/CBotInstr/CBotExprNan.h                |   4 +
 src/CBot/CBotInstr/CBotExprNull.cpp             |   1 -
 src/CBot/CBotInstr/CBotExprNull.h               |   4 +
 src/CBot/CBotInstr/CBotExprNum.cpp              |   9 +-
 src/CBot/CBotInstr/CBotExprNum.h                |   7 +-
 src/CBot/CBotInstr/CBotExprUnaire.cpp           |  18 ++-
 src/CBot/CBotInstr/CBotExprUnaire.h             |   6 +-
 src/CBot/CBotInstr/CBotExprVar.cpp              |  10 +-
 src/CBot/CBotInstr/CBotExprVar.h                |   4 +
 src/CBot/CBotInstr/CBotExpression.cpp           |  11 +-
 src/CBot/CBotInstr/CBotExpression.h             |   4 +
 src/CBot/CBotInstr/CBotFieldExpr.cpp            |   9 +-
 src/CBot/CBotInstr/CBotFieldExpr.h              |   4 +
 src/CBot/CBotInstr/CBotFloat.cpp                |  13 +-
 src/CBot/CBotInstr/CBotFloat.h                  |   4 +
 src/CBot/CBotInstr/CBotFor.cpp                  |  70 ++++++-----
 src/CBot/CBotInstr/CBotFor.h                    |  16 ++-
 src/CBot/CBotInstr/CBotFunction.cpp             |  72 ++++++-----
 src/CBot/CBotInstr/CBotFunction.h               |  10 +-
 src/CBot/CBotInstr/CBotIString.cpp              |  13 +-
 src/CBot/CBotInstr/CBotIString.h                |   4 +
 src/CBot/CBotInstr/CBotIf.cpp                   |  48 ++++----
 src/CBot/CBotInstr/CBotIf.h                     |  10 +-
 src/CBot/CBotInstr/CBotIndexExpr.cpp            |   8 +-
 src/CBot/CBotInstr/CBotIndexExpr.h              |   3 +
 src/CBot/CBotInstr/CBotInstArray.cpp            |  19 ++-
 src/CBot/CBotInstr/CBotInstArray.h              |   6 +-
 src/CBot/CBotInstr/CBotInstr.cpp                |  11 +-
 src/CBot/CBotInstr/CBotInstr.h                  |   9 +-
 src/CBot/CBotInstr/CBotInstrCall.cpp            |  30 +++--
 src/CBot/CBotInstr/CBotInstrCall.h              |   8 +-
 src/CBot/CBotInstr/CBotInstrMethode.cpp         |  52 +++++---
 src/CBot/CBotInstr/CBotInstrMethode.h           |  11 +-
 src/CBot/CBotInstr/CBotInt.cpp                  |  11 +-
 src/CBot/CBotInstr/CBotInt.h                    |   5 +-
 src/CBot/CBotInstr/CBotLeftExpr.cpp             |  10 +-
 src/CBot/CBotInstr/CBotLeftExpr.h               |   4 +
 src/CBot/CBotInstr/CBotLeftExprVar.cpp          |  11 +-
 src/CBot/CBotInstr/CBotLeftExprVar.h            |   5 +-
 src/CBot/CBotInstr/CBotListArray.cpp            |  10 +-
 src/CBot/CBotInstr/CBotListArray.h              |   4 +
 src/CBot/CBotInstr/CBotListExpression.cpp       |  20 ++--
 src/CBot/CBotInstr/CBotListExpression.h         |   6 +-
 src/CBot/CBotInstr/CBotListInstr.cpp            |  20 ++--
 src/CBot/CBotInstr/CBotListInstr.h              |   6 +-
 src/CBot/CBotInstr/CBotLogicExpr.cpp            |  16 ++-
 src/CBot/CBotInstr/CBotLogicExpr.h              |   5 +-
 src/CBot/CBotInstr/CBotNew.cpp                  |  28 +++--
 src/CBot/CBotInstr/CBotNew.h                    |   7 +-
 src/CBot/CBotInstr/CBotParExpr.cpp              |   4 +-
 src/CBot/CBotInstr/CBotPostIncExpr.cpp          |  16 ++-
 src/CBot/CBotInstr/CBotPostIncExpr.h            |   6 +-
 src/CBot/CBotInstr/CBotPreIncExpr.cpp           |  18 ++-
 src/CBot/CBotInstr/CBotPreIncExpr.h             |   6 +-
 src/CBot/CBotInstr/CBotReturn.cpp               |  18 ++-
 src/CBot/CBotInstr/CBotReturn.h                 |   6 +-
 src/CBot/CBotInstr/CBotSwitch.cpp               |  41 ++++---
 src/CBot/CBotInstr/CBotSwitch.h                 |  10 +-
 src/CBot/CBotInstr/CBotThrow.cpp                |  19 +--
 src/CBot/CBotInstr/CBotThrow.h                  |   6 +-
 src/CBot/CBotInstr/CBotTry.cpp                  |  48 ++++----
 src/CBot/CBotInstr/CBotTry.h                    |  11 +-
 src/CBot/CBotInstr/CBotTwoOpExpr.cpp            |  18 ++-
 src/CBot/CBotInstr/CBotTwoOpExpr.h              |   5 +
 src/CBot/CBotInstr/CBotWhile.cpp                |  36 ++++--
 src/CBot/CBotInstr/CBotWhile.h                  |  10 +-
 src/CBot/CBotProgram.h                          |   1 +
 src/CBot/CBotTypResult.cpp                      |  19 +++
 src/CBot/CBotTypResult.h                        |   2 +
 src/CBot/CMakeLists.txt                         | 141 +++++++++++-----------
 test/cbot/CMakeLists.txt                        |  20 +++-
 test/cbot/compile_graph.cpp                     |  88 ++++++++++++++
 test/cbot/{console/main.cpp => console.cpp}     |  19 +++
 test/cbot/console/CMakeLists.txt                |  22 ----
 94 files changed, 1190 insertions(+), 442 deletions(-)

diff --git a/src/CBot/CBotDebug.cpp b/src/CBot/CBotDebug.cpp
new file mode 100644
index 0000000..fc8c874
--- /dev/null
+++ b/src/CBot/CBotDebug.cpp
@@ -0,0 +1,152 @@
+/*
+ * This file is part of the Colobot: Gold Edition source code
+ * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
+ * http://epsitec.ch; http://colobot.info; http://github.com/colobot
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://gnu.org/licenses
+ */
+
+#include "CBot/CBotDebug.h"
+
+#include "CBot/CBotProgram.h"
+#include "CBot/CBotInstr/CBotFunction.h"
+#include "CBot/CBotInstr/CBotInstrCall.h"
+
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+#include <boost/algorithm/string/replace.hpp>
+
+namespace CBot
+{
+
+namespace
+{
+std::string GetPointerAsString(void* ptr)
+{
+    char buffer[20];
+    sprintf(buffer, "instr%016lX", reinterpret_cast<unsigned long>(ptr));
+    return std::string(buffer);
+}
+}
+
+void CBotDebug::DumpCompiledProgram(CBotProgram* program)
+{
+    std::stringstream ss;
+    ss << "digraph {" << std::endl;
+
+    CBotFunction* func = program->GetFunctions();
+    std::map<long, CBotFunction*> funcIdMap;
+    while (func != nullptr)
+    {
+        funcIdMap[func->m_nFuncIdent] = func;
+        func = func->Next();
+    }
+
+    std::set<CBotInstr*> finished;
+    std::function<void(CBotInstr*)> DumpInstr = [&](CBotInstr* instr) {
+        if (finished.find(instr) != finished.end()) return;
+        finished.insert(instr);
+
+        std::string label = "<b>"+instr->GetDebugName()+"</b>\n";
+        std::string data = instr->GetDebugData();
+        boost::algorithm::replace_all(data, "&", "&");
+        boost::algorithm::replace_all(data, "<", "<");
+        boost::algorithm::replace_all(data, ">", ">");
+        label += data;
+        boost::algorithm::replace_all(label, "\n", "<br/>");
+
+        std::string additional = "";
+        if (instr->GetDebugName() == "CBotFunction")
+        {
+            label = instr->GetDebugData(); // hide the title
+            CBotFunction* function = static_cast<CBotFunction*>(instr);
+            if (function == program->m_entryPoint) additional += " shape=box3d";
+            else additional += " shape=box";
+            if (function->IsExtern()) additional += " color=cyan";
+            else additional += " color=blue";
+            additional += " group=func";
+        }
+
+        ss << GetPointerAsString(instr) << " [label=<" << label << ">" << additional << "]" << std::endl;
+
+        if (instr->GetDebugName() == "CBotInstrCall")
+        {
+            CBotInstrCall* call = static_cast<CBotInstrCall*>(instr);
+            if (funcIdMap.count(call->m_nFuncIdent) > 0)
+            {
+                ss << GetPointerAsString(instr) << " -> " << GetPointerAsString(funcIdMap[call->m_nFuncIdent]) << " [style=dotted color=gray weight=15]" << std::endl;
+            }
+        }
+
+        for (const auto& it : instr->GetDebugLinks())
+        {
+            if (it.second == nullptr) continue;
+            if (it.second->GetDebugName() == "CBotFunction") continue;
+            DumpInstr(it.second);
+            ss << GetPointerAsString(instr) << " -> " << GetPointerAsString(it.second) << " [label=\"" << it.first << "\"" << (it.first == "m_next" ? " weight=1" : " weight=5") << "]" << std::endl;
+            if (it.first == "m_next" || (instr->GetDebugName() == "CBotFunction" && it.first == "m_block") || (instr->GetDebugName() == "CBotListInstr" && it.first == "m_instr"))
+            {
+                ss << "{ rank=same; " << GetPointerAsString(instr) << "; " << GetPointerAsString(it.second) << "; }" << std::endl;
+            }
+        }
+    };
+
+    if (program->m_entryPoint != nullptr)
+    {
+        DumpInstr(program->m_entryPoint);
+    }
+    func = program->GetFunctions();
+    std::string prev = GetPointerAsString(program->m_entryPoint);
+    while (func != nullptr)
+    {
+        if (func != program->m_entryPoint)
+        {
+            DumpInstr(func);
+
+            //ss << prev << " -> " << GetPointerAsString(func) << " [style=invis]" << std::endl;
+            prev = GetPointerAsString(func);
+        }
+
+        func = func->Next();
+    }
+
+    ss << "}" << std::endl;
+    std::cout << ss.str() << std::endl;
+
+    /* // Terrible platform-dependent code :P
+    std::stringstream filename;
+    filename << "compiled" << (program->m_entryPoint != nullptr ? "_"+program->m_entryPoint->GetName() : "") << ".png";
+
+    int pipeOut[2];
+    pipe(pipeOut);
+    if (fork())
+    {
+        close(pipeOut[0]);
+        write(pipeOut[1], ss.str().c_str(), ss.str().size());
+        close(pipeOut[1]);
+        int rv;
+        wait(&rv);
+        if(rv != 0) exit(rv);
+    }
+    else
+    {
+        dup2(pipeOut[0], 0);
+        close(pipeOut[1]);
+        execl("/usr/bin/dot", "dot", "-Tpng", "-o", filename.str().c_str(), nullptr);
+        exit(1); // failed to start
+    } */
+}
+
+} // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotEmpty.h b/src/CBot/CBotDebug.h
similarity index 69%
copy from src/CBot/CBotInstr/CBotEmpty.h
copy to src/CBot/CBotDebug.h
index e48456d..6019c2d 100644
--- a/src/CBot/CBotInstr/CBotEmpty.h
+++ b/src/CBot/CBotDebug.h
@@ -19,29 +19,16 @@
 
 #pragma once
 
-#include "CBot/CBotInstr/CBotInstr.h"
-
 namespace CBot
 {
+class CBotProgram;
 
-/*!
- * \brief The CBotEmpty class
- */
-class CBotEmpty : public CBotInstr
+class CBotDebug
 {
-    /*!
-     * \brief Execute Special case for empty indexes.
-     * \param pj
-     * \return
-     */
-    bool Execute(CBotStack* &pj) override;
-
-    /*!
-     * \brief RestoreState
-     * \param pj
-     * \param bMain
-     */
-    void RestoreState(CBotStack* &pj, bool bMain) override;
+public:
+    static void DumpCompiledProgram(CBotProgram* program);
 };
 
 } // namespace CBot
+
+
diff --git a/src/CBot/CBotInstr/CBotBoolean.cpp b/src/CBot/CBotInstr/CBotBoolean.cpp
index c3dcadc..3f87a8c 100644
--- a/src/CBot/CBotInstr/CBotBoolean.cpp
+++ b/src/CBot/CBotInstr/CBotBoolean.cpp
@@ -33,9 +33,7 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotBoolean::CBotBoolean()
 {
-    m_var    =
-    m_expr    = nullptr;
-    name = "CBotBoolean";
+    m_var = m_expr = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -174,4 +172,12 @@ void CBotBoolean::RestoreState(CBotStack* &pj, bool bMain)
          m_next2b->RestoreState(pile, bMain);                // other(s) definition(s)
 }
 
+std::map<std::string, CBotInstr*> CBotBoolean::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_var"] = m_var;
+    links["m_expr"] = m_expr;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotBoolean.h b/src/CBot/CBotInstr/CBotBoolean.h
index 1197db8..e6ad789 100644
--- a/src/CBot/CBotInstr/CBotBoolean.h
+++ b/src/CBot/CBotInstr/CBotBoolean.h
@@ -65,6 +65,10 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotBoolean"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! Variable to initialise.
     CBotInstr* m_var;
diff --git a/src/CBot/CBotInstr/CBotBreak.cpp b/src/CBot/CBotInstr/CBotBreak.cpp
index 524a50e..db950f3 100644
--- a/src/CBot/CBotInstr/CBotBreak.cpp
+++ b/src/CBot/CBotInstr/CBotBreak.cpp
@@ -28,7 +28,6 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotBreak::CBotBreak()
 {
-    name = "CBotBreak";     // debug
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -93,4 +92,9 @@ void CBotBreak :: RestoreState(CBotStack* &pj, bool bMain)
     if ( bMain ) pj->RestoreStack(this);
 }
 
+std::string CBotBreak::GetDebugData()
+{
+    return !m_label.empty() ? "m_label = "+m_label : "";
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotBreak.h b/src/CBot/CBotInstr/CBotBreak.h
index d7ad068..2f1a8de 100644
--- a/src/CBot/CBotInstr/CBotBreak.h
+++ b/src/CBot/CBotInstr/CBotBreak.h
@@ -64,6 +64,9 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotBreak"; }
+    virtual std::string GetDebugData();
 
 private:
     //! A label if there is
diff --git a/src/CBot/CBotInstr/CBotCase.cpp b/src/CBot/CBotInstr/CBotCase.cpp
index b612fa1..8edc36e 100644
--- a/src/CBot/CBotInstr/CBotCase.cpp
+++ b/src/CBot/CBotInstr/CBotCase.cpp
@@ -29,14 +29,13 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotCase::CBotCase()
 {
-    m_Value     = nullptr;     // nullptr so that delete is not possible further
-    name = "CBotCase";      // debug
+    m_value = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotCase::~CBotCase()
 {
-    delete  m_Value;        // frees the value
+    delete m_value;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -51,8 +50,8 @@ CBotInstr* CBotCase::Compile(CBotToken* &p, CBotCStack* pStack)
     if ( pp->GetType() == ID_CASE )
     {
         pp = p;
-        inst->m_Value = CBotExprNum::Compile(p, pStack);
-        if ( inst->m_Value == nullptr )
+        inst->m_value = CBotExprNum::Compile(p, pStack);
+        if (inst->m_value == nullptr )
         {
             pStack->SetError( CBotErrBadNum, pp );
             delete inst;
@@ -83,10 +82,17 @@ void CBotCase::RestoreState(CBotStack* &pj, bool bMain)
 ////////////////////////////////////////////////////////////////////////////////
 bool CBotCase::CompCase(CBotStack* &pile, int val)
 {
-    if ( m_Value == nullptr ) return true;         // "default" case
+    if (m_value == nullptr ) return true;         // "default" case
 
-    while (!m_Value->Execute(pile));            // puts the value on the correspondent stack (without interruption)
+    while (!m_value->Execute(pile));            // puts the value on the correspondent stack (without interruption)
     return (pile->GetVal() == val);             // compared with the given value
 }
 
+std::map<std::string, CBotInstr*> CBotCase::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_value"] = m_value;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotCase.h b/src/CBot/CBotInstr/CBotCase.h
index e0445ea..fcc7fa8 100644
--- a/src/CBot/CBotInstr/CBotCase.h
+++ b/src/CBot/CBotInstr/CBotCase.h
@@ -74,9 +74,13 @@ public:
      */
     bool CompCase(CBotStack* &pj, int val) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotCase"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! Value to compare.
-    CBotInstr*    m_Value;
+    CBotInstr* m_value;
 };
 
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotCatch.cpp b/src/CBot/CBotInstr/CBotCatch.cpp
index 5aca41e..b1866af 100644
--- a/src/CBot/CBotInstr/CBotCatch.cpp
+++ b/src/CBot/CBotInstr/CBotCatch.cpp
@@ -32,19 +32,17 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotCatch::CBotCatch()
 {
-    m_Cond      =
-    m_Block     = nullptr;     // nullptr so that delete is not possible further
-    m_next      = nullptr;
-
-    name = "CBotCatch";     // debug
+    m_cond = nullptr;
+    m_block = nullptr;
+    m_next = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotCatch::~CBotCatch()
 {
-    delete  m_Cond;         // frees the list
-    delete  m_Block;        // frees the instruction block
-    delete  m_next;         // and subsequent
+    delete m_cond;         // frees the list
+    delete m_block;        // frees the instruction block
+    delete m_next;         // and subsequent
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -58,13 +56,13 @@ CBotCatch* CBotCatch::Compile(CBotToken* &p, CBotCStack* pStack)
 
     if (IsOfType(p, ID_OPENPAR))
     {
-        inst->m_Cond = CBotExpression::Compile(p, pStack);
+        inst->m_cond = CBotExpression::Compile(p, pStack);
         if (( pStack->GetType() < CBotTypLong ||
               pStack->GetTypResult().Eq(CBotTypBoolean) )&& pStack->IsOk() )
         {
             if (IsOfType(p, ID_CLOSEPAR))
             {
-                inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStack );
+                inst->m_block = CBotBlock::CompileBlkOrInst(p, pStack );
                 if ( pStack->IsOk() )
                     return inst;                // return an object to the application
             }
@@ -80,26 +78,26 @@ CBotCatch* CBotCatch::Compile(CBotToken* &p, CBotCStack* pStack)
 ////////////////////////////////////////////////////////////////////////////////
 bool CBotCatch :: Execute(CBotStack* &pj)
 {
-    if ( m_Block == nullptr ) return true;
-    return m_Block->Execute(pj);                // executes the associated block
+    if (m_block == nullptr ) return true;
+    return m_block->Execute(pj);                // executes the associated block
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 void CBotCatch :: RestoreState(CBotStack* &pj, bool bMain)
 {
-    if ( bMain && m_Block != nullptr ) m_Block->RestoreState(pj, bMain);
+    if ( bMain && m_block != nullptr ) m_block->RestoreState(pj, bMain);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 void CBotCatch :: RestoreCondState(CBotStack* &pj, bool bMain)
 {
-    m_Cond->RestoreState(pj, bMain);
+    m_cond->RestoreState(pj, bMain);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 bool CBotCatch :: TestCatch(CBotStack* &pile, int val)
 {
-    if ( !m_Cond->Execute(pile) ) return false;
+    if ( !m_cond->Execute(pile) ) return false;
 
     if ( val > 0 || pile->GetVar() == nullptr || pile->GetVar()->GetType() != CBotTypBoolean )
     {
@@ -111,4 +109,13 @@ bool CBotCatch :: TestCatch(CBotStack* &pile, int val)
     return true;
 }
 
+std::map<std::string, CBotInstr*> CBotCatch::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_block"] = m_block;
+    links["m_cond"] = m_cond;
+    links["m_next"] = m_next;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotCatch.h b/src/CBot/CBotInstr/CBotCatch.h
index d5f7405..24d12ca 100644
--- a/src/CBot/CBotInstr/CBotCatch.h
+++ b/src/CBot/CBotInstr/CBotCatch.h
@@ -78,12 +78,15 @@ public:
      */
     void RestoreCondState(CBotStack* &pj, bool bMain);
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotCatch"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
 
 private:
     //! Instructions
-    CBotInstr* m_Block;
+    CBotInstr* m_block;
     //! Condition
-    CBotInstr* m_Cond;
+    CBotInstr* m_cond;
     //! Following catch
     CBotCatch* m_next;
 
diff --git a/src/CBot/CBotInstr/CBotClassInst.cpp b/src/CBot/CBotInstr/CBotClassInst.cpp
index 26662b8..bffbdcd 100644
--- a/src/CBot/CBotInstr/CBotClassInst.cpp
+++ b/src/CBot/CBotInstr/CBotClassInst.cpp
@@ -40,11 +40,10 @@ CBotClassInst::CBotClassInst()
 {
     m_next          = nullptr;
     m_var           = nullptr;
-    m_Parameters    = nullptr;
+    m_parameters    = nullptr;
     m_expr          = nullptr;
     m_hasParams     = false;
     m_nMethodeIdent = 0;
-    name = "CBotClassInst";
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -123,14 +122,14 @@ CBotInstr* CBotClassInst::Compile(CBotToken* &p, CBotCStack* pStack, CBotClass*
         inst->m_hasParams = (p->GetType() == ID_OPENPAR);
 
         CBotVar*    ppVars[1000];
-        inst->m_Parameters = CompileParams(p, pStk, ppVars);
+        inst->m_parameters = CompileParams(p, pStk, ppVars);
         if ( !pStk->IsOk() ) goto error;
 
         // if there are parameters, is the equivalent to the stament "new"
         // CPoint A ( 0, 0 ) is equivalent to
         // CPoint A = new CPoint( 0, 0 )
 
-//      if ( nullptr != inst->m_Parameters )
+//      if ( nullptr != inst->m_parameters )
         if ( inst->m_hasParams )
         {
             // the constructor is there?
@@ -142,7 +141,7 @@ CBotInstr* CBotClassInst::Compile(CBotToken* &p, CBotCStack* pStack, CBotClass*
             if (typ == CBotErrUndefCall)
             {
                 // si le constructeur n'existe pas
-                if (inst->m_Parameters != nullptr)                 // with parameters
+                if (inst->m_parameters != nullptr)                 // with parameters
                 {
                     pStk->SetError(CBotErrNoConstruct, vartoken);
                     goto error;
@@ -310,7 +309,7 @@ bool CBotClassInst::Execute(CBotStack* &pj)
 
             int     i = 0;
 
-            CBotInstr*  p = m_Parameters;
+            CBotInstr*  p = m_parameters;
             // evaluates the parameters
             // and places the values ​​on the stack
             // to (can) be interrupted (broken) at any time
@@ -404,7 +403,7 @@ void CBotClassInst::RestoreState(CBotStack* &pj, bool bMain)
 
             int     i = 0;
 
-            CBotInstr*  p = m_Parameters;
+            CBotInstr*  p = m_parameters;
             // evaluates the parameters
             // and the values an the stack
             // for the ability to be interrupted at any time (\TODO pour pouvoir être interrompu n'importe quand)
@@ -437,4 +436,13 @@ void CBotClassInst::RestoreState(CBotStack* &pj, bool bMain)
          m_next2b->RestoreState(pile, bMain);                   // other(s) definition(s)
 }
 
+std::map<std::string, CBotInstr*> CBotClassInst::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_var"] = m_var;
+    links["m_parameters"] = m_parameters;
+    links["m_expr"] = m_expr;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotClassInst.h b/src/CBot/CBotInstr/CBotClassInst.h
index dd7375a..431c421 100644
--- a/src/CBot/CBotInstr/CBotClassInst.h
+++ b/src/CBot/CBotInstr/CBotClassInst.h
@@ -66,18 +66,21 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotClassInstr"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
 
     //! Variable to initialise.
     CBotInstr* m_var;
-    //! Reference to the class.
-    CBotClass* m_pClass;
     //! Parameters to be evaluated for the contructor.
-    CBotInstr* m_Parameters;
+    CBotInstr* m_parameters;
     //! A value to put, if there is.
     CBotInstr* m_expr;
     //! Has it parameters.
     bool m_hasParams;
+    //! Constructor method unique identifier
     long m_nMethodeIdent;
 
 };
diff --git a/src/CBot/CBotInstr/CBotDo.cpp b/src/CBot/CBotInstr/CBotDo.cpp
index 4c51f7d..453ad88 100644
--- a/src/CBot/CBotInstr/CBotDo.cpp
+++ b/src/CBot/CBotInstr/CBotDo.cpp
@@ -30,16 +30,15 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotDo::CBotDo()
 {
-    m_Condition =
-    m_Block     = nullptr;     // nullptr so that delete is not possible further
-    name = "CBotDo";        // debug
+    m_condition = nullptr;
+    m_block = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotDo::~CBotDo()
 {
-    delete  m_Condition;    // frees the condition
-    delete  m_Block;        // frees the instruction block
+    delete m_condition;    // frees the condition
+    delete m_block;        // frees the instruction block
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -63,14 +62,14 @@ CBotInstr* CBotDo::Compile(CBotToken* &p, CBotCStack* pStack)
 
     // looking for a statement block after the do
     IncLvl(inst->m_label);
-    inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true );
+    inst->m_block = CBotBlock::CompileBlkOrInst(p, pStk, true );
     DecLvl();
 
     if ( pStk->IsOk() )
     {
         if (IsOfType(p, ID_WHILE))
         {
-            if ( nullptr != (inst->m_Condition = CBotCondition::Compile( p, pStk )) )
+            if ( nullptr != (inst->m_condition = CBotCondition::Compile(p, pStk )) )
             {
                 // the condition exists
                 if (IsOfType(p, ID_SEP))
@@ -100,8 +99,8 @@ bool CBotDo :: Execute(CBotStack* &pj)
     {                                                   // there are two possible states (depending on recovery)
     case 0:
         // evaluates the associated statement block
-        if ( m_Block != nullptr &&
-            !m_Block->Execute(pile) )
+        if (m_block != nullptr &&
+            !m_block->Execute(pile) )
         {
             if (pile->IfContinue(1, m_label)) continue; // if continued, will return to test
             return pj->BreakReturn(pile, m_label);      // sends the results and releases the stack
@@ -117,7 +116,7 @@ bool CBotDo :: Execute(CBotStack* &pj)
 
     case 1:
         // evaluates the condition
-        if ( !m_Condition->Execute(pile) ) return false; // interrupted here ?
+        if ( !m_condition->Execute(pile) ) return false; // interrupted here ?
 
         // the result of the condition is on the stack
 
@@ -145,14 +144,27 @@ void CBotDo :: RestoreState(CBotStack* &pj, bool bMain)
     {                                                   // there are two possible states (depending on recovery)
     case 0:
         // restores the assosiated statement's block
-        if ( m_Block != nullptr ) m_Block->RestoreState(pile, bMain);
+        if (m_block != nullptr ) m_block->RestoreState(pile, bMain);
         return;
 
     case 1:
         // restores the condition
-        m_Condition->RestoreState(pile, bMain);
+        m_condition->RestoreState(pile, bMain);
         return;
     }
 }
 
+std::string CBotDo::GetDebugData()
+{
+    return !m_label.empty() ? "m_label = "+m_label : "";
+}
+
+std::map<std::string, CBotInstr*> CBotDo::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_block"] = m_block;
+    links["m_condition"] = m_condition;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotDo.h b/src/CBot/CBotInstr/CBotDo.h
index cdf06c9..ffe6287 100644
--- a/src/CBot/CBotInstr/CBotDo.h
+++ b/src/CBot/CBotInstr/CBotDo.h
@@ -60,11 +60,16 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotDo"; }
+    virtual std::string GetDebugData();
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! Instruction
-    CBotInstr* m_Block;
+    CBotInstr* m_block;
     //! Conditions
-    CBotInstr* m_Condition;
+    CBotInstr* m_condition;
     //! A label if there is
     std::string m_label;
 };
diff --git a/src/CBot/CBotInstr/CBotEmpty.h b/src/CBot/CBotInstr/CBotEmpty.h
index e48456d..0f2c328 100644
--- a/src/CBot/CBotInstr/CBotEmpty.h
+++ b/src/CBot/CBotInstr/CBotEmpty.h
@@ -42,6 +42,9 @@ class CBotEmpty : public CBotInstr
      * \param bMain
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
+
+protected:
+    virtual const std::string GetDebugName() { return "CBotEmpty"; }
 };
 
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotExprAlpha.cpp b/src/CBot/CBotInstr/CBotExprAlpha.cpp
index 71fcdfe..8bd24c8 100644
--- a/src/CBot/CBotInstr/CBotExprAlpha.cpp
+++ b/src/CBot/CBotInstr/CBotExprAlpha.cpp
@@ -30,7 +30,6 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotExprAlpha::CBotExprAlpha()
 {
-    name    = "CBotExprAlpha";
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -79,4 +78,9 @@ void CBotExprAlpha::RestoreState(CBotStack* &pj, bool bMain)
     if (bMain) pj->RestoreStack(this);
 }
 
+std::string CBotExprAlpha::GetDebugData()
+{
+    return m_token.GetString();
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotExprAlpha.h b/src/CBot/CBotInstr/CBotExprAlpha.h
index d7d5bf3..c61d44b 100644
--- a/src/CBot/CBotInstr/CBotExprAlpha.h
+++ b/src/CBot/CBotInstr/CBotExprAlpha.h
@@ -62,6 +62,10 @@ public:
      * \param bMain
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
+
+protected:
+    virtual const std::string GetDebugName() { return "CBotExprAlpha"; }
+    virtual std::string GetDebugData();
 };
 
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotExprBool.cpp b/src/CBot/CBotInstr/CBotExprBool.cpp
index 6160e82..0aeb68d 100644
--- a/src/CBot/CBotInstr/CBotExprBool.cpp
+++ b/src/CBot/CBotInstr/CBotExprBool.cpp
@@ -30,7 +30,6 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotExprBool::CBotExprBool()
 {
-    name = "CBotExprBool";
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/CBot/CBotInstr/CBotExprBool.h b/src/CBot/CBotInstr/CBotExprBool.h
index 1c9f8e9..1923742 100644
--- a/src/CBot/CBotInstr/CBotExprBool.h
+++ b/src/CBot/CBotInstr/CBotExprBool.h
@@ -62,6 +62,9 @@ public:
      * \param bMain
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
+
+protected:
+    virtual const std::string GetDebugName() { return "CBotExprBool"; }
 };
 
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotExprNan.cpp b/src/CBot/CBotInstr/CBotExprNan.cpp
index 7c1a411..24d1c72 100644
--- a/src/CBot/CBotInstr/CBotExprNan.cpp
+++ b/src/CBot/CBotInstr/CBotExprNan.cpp
@@ -29,7 +29,6 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotExprNan::CBotExprNan()
 {
-    name = "CBotExprNan";
 }
 ////////////////////////////////////////////////////////////////////////////////
 CBotExprNan::~CBotExprNan()
diff --git a/src/CBot/CBotInstr/CBotExprNan.h b/src/CBot/CBotInstr/CBotExprNan.h
index b2268e8..1741381 100644
--- a/src/CBot/CBotInstr/CBotExprNan.h
+++ b/src/CBot/CBotInstr/CBotExprNan.h
@@ -54,6 +54,10 @@ public:
      * \param bMain
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
+
+protected:
+    virtual const std::string GetDebugName() { return "CBotExprNan"; }
+    virtual std::string GetDebugData() { return "nan"; }
 };
 
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotExprNull.cpp b/src/CBot/CBotInstr/CBotExprNull.cpp
index 2292379..c859e99 100644
--- a/src/CBot/CBotInstr/CBotExprNull.cpp
+++ b/src/CBot/CBotInstr/CBotExprNull.cpp
@@ -29,7 +29,6 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotExprNull::CBotExprNull()
 {
-    name = "CBotExprNull";
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/CBot/CBotInstr/CBotExprNull.h b/src/CBot/CBotInstr/CBotExprNull.h
index bd7ce1b..527158a 100644
--- a/src/CBot/CBotInstr/CBotExprNull.h
+++ b/src/CBot/CBotInstr/CBotExprNull.h
@@ -54,6 +54,10 @@ public:
      * \param bMain
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
+
+protected:
+    virtual const std::string GetDebugName() { return "CBotExprNull"; }
+    virtual std::string GetDebugData() { return "null"; }
 };
 
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotExprNum.cpp b/src/CBot/CBotInstr/CBotExprNum.cpp
index c711ea8..c2addbf 100644
--- a/src/CBot/CBotInstr/CBotExprNum.cpp
+++ b/src/CBot/CBotInstr/CBotExprNum.cpp
@@ -17,6 +17,7 @@
  * along with this program. If not, see http://gnu.org/licenses
  */
 
+#include <sstream>
 #include "CBot/CBotInstr/CBotExprNum.h"
 
 #include "CBot/CBotStack.h"
@@ -32,7 +33,6 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotExprNum::CBotExprNum()
 {
-    name    = "CBotExprNum";
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -115,4 +115,11 @@ void CBotExprNum::RestoreState(CBotStack* &pj, bool bMain)
     if (bMain) pj->RestoreStack(this);
 }
 
+std::string CBotExprNum::GetDebugData()
+{
+    std::stringstream ss;
+    ss << "(" << (m_numtype == CBotTypFloat ? "float" : "int") << ") " << (m_numtype == CBotTypFloat ? m_valfloat : m_valint);
+    return ss.str();
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotExprNum.h b/src/CBot/CBotInstr/CBotExprNum.h
index 7ec76bf..dc3bc85 100644
--- a/src/CBot/CBotInstr/CBotExprNum.h
+++ b/src/CBot/CBotInstr/CBotExprNum.h
@@ -64,10 +64,13 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
-private:
+protected:
+    virtual const std::string GetDebugName() { return "CBotExprNum"; }
+    virtual std::string GetDebugData();
 
+private:
     //! The type of number.
-    int m_numtype;
+    CBotType m_numtype;
     //! Value for an int.
     long m_valint;
     //! Value for a float.
diff --git a/src/CBot/CBotInstr/CBotExprUnaire.cpp b/src/CBot/CBotInstr/CBotExprUnaire.cpp
index 92130e1..94275b2 100644
--- a/src/CBot/CBotInstr/CBotExprUnaire.cpp
+++ b/src/CBot/CBotInstr/CBotExprUnaire.cpp
@@ -31,14 +31,13 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotExprUnaire::CBotExprUnaire()
 {
-    m_Expr = nullptr;
-    name = "CBotExprUnaire";
+    m_expr = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotExprUnaire::~CBotExprUnaire()
 {
-    delete m_Expr;
+    delete m_expr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -53,7 +52,7 @@ CBotInstr* CBotExprUnaire::Compile(CBotToken* &p, CBotCStack* pStack)
     CBotExprUnaire* inst = new CBotExprUnaire();
     inst->SetToken(pp);
 
-    if (nullptr != (inst->m_Expr = CBotParExpr::Compile( p, pStk )))
+    if (nullptr != (inst->m_expr = CBotParExpr::Compile(p, pStk )))
     {
         if (op == ID_ADD && pStk->GetType() < CBotTypBoolean)        // only with the number
             return pStack->Return(inst, pStk);
@@ -80,7 +79,7 @@ bool CBotExprUnaire::Execute(CBotStack* &pj)
 
     if (pile->GetState() == 0)
     {
-        if (!m_Expr->Execute(pile)) return false;                    // interrupted ?
+        if (!m_expr->Execute(pile)) return false;                    // interrupted ?
         pile->IncState();
     }
 
@@ -115,9 +114,16 @@ void CBotExprUnaire::RestoreState(CBotStack* &pj, bool bMain)
 
     if (pile->GetState() == 0)
     {
-        m_Expr->RestoreState(pile, bMain);                        // interrupted here!
+        m_expr->RestoreState(pile, bMain);                        // interrupted here!
         return;
     }
 }
 
+std::map<std::string, CBotInstr*> CBotExprUnaire::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_expr"] = m_expr;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotExprUnaire.h b/src/CBot/CBotInstr/CBotExprUnaire.h
index 6a3653d..4a53d43 100644
--- a/src/CBot/CBotInstr/CBotExprUnaire.h
+++ b/src/CBot/CBotInstr/CBotExprUnaire.h
@@ -64,9 +64,13 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotExprUnaire"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! Expression to be evaluated.
-    CBotInstr* m_Expr;
+    CBotInstr* m_expr;
 };
 
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotExprVar.cpp b/src/CBot/CBotInstr/CBotExprVar.cpp
index 44431db..05c98f2 100644
--- a/src/CBot/CBotInstr/CBotExprVar.cpp
+++ b/src/CBot/CBotInstr/CBotExprVar.cpp
@@ -17,6 +17,7 @@
  * along with this program. If not, see http://gnu.org/licenses
  */
 
+#include <sstream>
 #include "CBot/CBotInstr/CBotExprVar.h"
 #include "CBot/CBotInstr/CBotInstrMethode.h"
 #include "CBot/CBotInstr/CBotExpression.h"
@@ -34,7 +35,6 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotExprVar::CBotExprVar()
 {
-    name    = "CBotExprVar";
     m_nIdent = 0;
 }
 
@@ -304,4 +304,12 @@ void CBotExprVar::RestoreStateVar(CBotStack* &pj, bool bMain)
          m_next3->RestoreStateVar(pj, bMain);
 }
 
+std::string CBotExprVar::GetDebugData()
+{
+    std::stringstream ss;
+    ss << m_token.GetString() << std::endl;
+    //ss << "VarID = " << m_nIdent;
+    return ss.str();
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotExprVar.h b/src/CBot/CBotInstr/CBotExprVar.h
index 76b72d7..73062d6 100644
--- a/src/CBot/CBotInstr/CBotExprVar.h
+++ b/src/CBot/CBotInstr/CBotExprVar.h
@@ -94,6 +94,10 @@ public:
      */
     void RestoreStateVar(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotExprVar"; }
+    virtual std::string GetDebugData();
+
 private:
     long m_nIdent;
     friend class CBotPostIncExpr;
diff --git a/src/CBot/CBotInstr/CBotExpression.cpp b/src/CBot/CBotInstr/CBotExpression.cpp
index 2556056..21c7953 100644
--- a/src/CBot/CBotInstr/CBotExpression.cpp
+++ b/src/CBot/CBotInstr/CBotExpression.cpp
@@ -37,8 +37,7 @@ namespace CBot
 CBotExpression::CBotExpression()
 {
     m_leftop    = nullptr;
-    m_rightop    = nullptr;
-    name = "CBotExpression";
+    m_rightop   = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -296,4 +295,12 @@ void CBotExpression::RestoreState(CBotStack* &pj, bool bMain)
     }
 }
 
+std::map<std::string, CBotInstr*> CBotExpression::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_leftop"] = m_leftop;
+    links["m_rightop"] = m_rightop;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotExpression.h b/src/CBot/CBotInstr/CBotExpression.h
index 613cc51..95ae427 100644
--- a/src/CBot/CBotInstr/CBotExpression.h
+++ b/src/CBot/CBotInstr/CBotExpression.h
@@ -76,6 +76,10 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotExpression"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! Left operand
     CBotLeftExpr* m_leftop;
diff --git a/src/CBot/CBotInstr/CBotFieldExpr.cpp b/src/CBot/CBotInstr/CBotFieldExpr.cpp
index ae720af..f240f86 100644
--- a/src/CBot/CBotInstr/CBotFieldExpr.cpp
+++ b/src/CBot/CBotInstr/CBotFieldExpr.cpp
@@ -26,6 +26,7 @@
 #include "CBot/CBotVar/CBotVarClass.h"
 
 #include <cassert>
+#include <sstream>
 
 namespace CBot
 {
@@ -33,7 +34,6 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotFieldExpr::CBotFieldExpr()
 {
-    name        = "CBotFieldExpr";
     m_nIdent    = 0;
 }
 
@@ -128,4 +128,11 @@ void CBotFieldExpr::RestoreStateVar(CBotStack* &pj, bool bMain)
          m_next3->RestoreStateVar(pj, bMain);
 }
 
+std::string CBotFieldExpr::GetDebugData()
+{
+    std::stringstream ss;
+    ss << "VarID = " << m_nIdent;
+    return ss.str();
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotFieldExpr.h b/src/CBot/CBotInstr/CBotFieldExpr.h
index 1c0d39d..566b2f8 100644
--- a/src/CBot/CBotInstr/CBotFieldExpr.h
+++ b/src/CBot/CBotInstr/CBotFieldExpr.h
@@ -74,6 +74,10 @@ public:
      */
     void RestoreStateVar(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotFieldExpr"; }
+    virtual std::string GetDebugData();
+
 private:
     friend class CBotExpression;
     int m_nIdent;
diff --git a/src/CBot/CBotInstr/CBotFloat.cpp b/src/CBot/CBotInstr/CBotFloat.cpp
index dbf061d..9374057 100644
--- a/src/CBot/CBotInstr/CBotFloat.cpp
+++ b/src/CBot/CBotInstr/CBotFloat.cpp
@@ -33,9 +33,8 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotFloat::CBotFloat()
 {
-    m_var    =
-    m_expr    = nullptr;
-    name = "CBotFloat";
+    m_var    = nullptr;
+    m_expr   = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -172,4 +171,12 @@ void CBotFloat::RestoreState(CBotStack* &pj, bool bMain)
          m_next2b->RestoreState(pile, bMain);
 }
 
+std::map<std::string, CBotInstr*> CBotFloat::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_var"] = m_var;
+    links["m_expr"] = m_expr;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotFloat.h b/src/CBot/CBotInstr/CBotFloat.h
index 9d333bc..2af2016 100644
--- a/src/CBot/CBotInstr/CBotFloat.h
+++ b/src/CBot/CBotInstr/CBotFloat.h
@@ -65,6 +65,10 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotFloat"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! Variable to initialise.
     CBotInstr* m_var;
diff --git a/src/CBot/CBotInstr/CBotFor.cpp b/src/CBot/CBotInstr/CBotFor.cpp
index 62f5ac9..c1c075a 100644
--- a/src/CBot/CBotInstr/CBotFor.cpp
+++ b/src/CBot/CBotInstr/CBotFor.cpp
@@ -31,20 +31,19 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotFor::CBotFor()
 {
-    m_Init      =
-    m_Test      =
-    m_Incr      =
-    m_Block     = nullptr;     // nullptr so that delete is not possible further
-    name = "CBotFor";       // debug
+    m_init = nullptr;
+    m_test = nullptr;
+    m_incr = nullptr;
+    m_block = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotFor::~CBotFor()
 {
-    delete  m_Init;
-    delete  m_Test;
-    delete  m_Incr;
-    delete  m_Block;        // frees the instruction block
+    delete m_init;
+    delete m_test;
+    delete m_incr;
+    delete m_block;        // frees the instruction block
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -71,7 +70,7 @@ CBotInstr* CBotFor::Compile(CBotToken* &p, CBotCStack* pStack)
     CBotCStack* pStk = pStack->TokenStack(pp, true);    // un petit bout de pile svp
 
     // compiles instructions for initialization
-    inst->m_Init = CBotListExpression::Compile( p, pStk );
+    inst->m_init = CBotListExpression::Compile(p, pStk );
     if ( pStk->IsOk() )
     {
         if ( !IsOfType(p, ID_SEP))                      // lack the semicolon?
@@ -80,7 +79,7 @@ CBotInstr* CBotFor::Compile(CBotToken* &p, CBotCStack* pStack)
             delete inst;
             return pStack->Return(nullptr, pStk);          // no object, the error is on the stack
         }
-        inst->m_Test = CBotBoolExpr::Compile( p, pStk );
+        inst->m_test = CBotBoolExpr::Compile(p, pStk );
         if ( pStk->IsOk() )
         {
             if ( !IsOfType(p, ID_SEP))                      // lack the semicolon?
@@ -89,13 +88,13 @@ CBotInstr* CBotFor::Compile(CBotToken* &p, CBotCStack* pStack)
                 delete inst;
                 return pStack->Return(nullptr, pStk);          // no object, the error is on the stack
             }
-            inst->m_Incr = CBotListExpression::Compile( p, pStk );
+            inst->m_incr = CBotListExpression::Compile(p, pStk );
             if ( pStk->IsOk() )
             {
                 if ( IsOfType(p, ID_CLOSEPAR))              // missing parenthesis ?
                 {
                     IncLvl(inst->m_label);
-                    inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true );
+                    inst->m_block = CBotBlock::CompileBlkOrInst(p, pStk, true );
                     DecLvl();
                     if ( pStk->IsOk() )
                         return pStack->Return(inst, pStk);;
@@ -123,15 +122,15 @@ bool CBotFor :: Execute(CBotStack* &pj)
     {                                           // there are four possible states (depending on recovery)
     case 0:
         // initialize
-        if ( m_Init != nullptr &&
-             !m_Init->Execute(pile) ) return false;     // interrupted here ?
+        if (m_init != nullptr &&
+            !m_init->Execute(pile) ) return false;     // interrupted here ?
         if (!pile->SetState(1)) return false;           // ready for further
 
     case 1:
         // evaluates the condition
-        if ( m_Test != nullptr )                           // no strings attached? -> True!
+        if (m_test != nullptr )                           // no strings attached? -> True!
         {
-            if (!m_Test->Execute(pile) ) return false;  // interrupted here ?
+            if (!m_test->Execute(pile) ) return false;  // interrupted here ?
 
             // the result of the condition is on the stack
 
@@ -147,8 +146,8 @@ bool CBotFor :: Execute(CBotStack* &pj)
 
     case 2:
         // evaluates the associated statement block
-        if ( m_Block != nullptr &&
-            !m_Block->Execute(pile) )
+        if (m_block != nullptr &&
+            !m_block->Execute(pile) )
         {
             if (pile->IfContinue(3, m_label)) continue; // if continued, going on to incrementation
             return pj->BreakReturn(pile, m_label);      // sends the results and releases the stack
@@ -164,8 +163,8 @@ bool CBotFor :: Execute(CBotStack* &pj)
 
     case 3:
         // evalutate the incrementation
-        if ( m_Incr != nullptr &&
-            !m_Incr->Execute(pile) ) return false;      // interrupted here ?
+        if (m_incr != nullptr &&
+            !m_incr->Execute(pile) ) return false;      // interrupted here ?
 
         // returns to the test again
         if (!pile->SetState(1, 0)) return false;            // returns to the test
@@ -185,30 +184,45 @@ void CBotFor :: RestoreState(CBotStack* &pj, bool bMain)
     {                                           // there are four possible states (depending on recovery)
     case 0:
         // initialize
-        if ( m_Init != nullptr ) m_Init->RestoreState(pile, true);     // interrupted here !
+        if (m_init != nullptr ) m_init->RestoreState(pile, true);     // interrupted here !
         return;
 
     case 1:
-        if ( m_Init != nullptr ) m_Init->RestoreState(pile, false);    // variables definitions
+        if (m_init != nullptr ) m_init->RestoreState(pile, false);    // variables definitions
 
         // evaluates the condition
-        if ( m_Test != nullptr ) m_Test->RestoreState(pile, true);     // interrupted here !
+        if (m_test != nullptr ) m_test->RestoreState(pile, true);     // interrupted here !
         return;
 
     case 2:
-        if ( m_Init != nullptr ) m_Init->RestoreState(pile, false);    // variable definitions
+        if (m_init != nullptr ) m_init->RestoreState(pile, false);    // variable definitions
 
         // evaluates the associated statement block
-        if ( m_Block != nullptr ) m_Block->RestoreState(pile, true);
+        if (m_block != nullptr ) m_block->RestoreState(pile, true);
         return;
 
     case 3:
-        if ( m_Init != nullptr ) m_Init->RestoreState(pile, false);    // variable definitions
+        if (m_init != nullptr ) m_init->RestoreState(pile, false);    // variable definitions
 
         // evaluate the incrementation
-        if ( m_Incr != nullptr ) m_Incr->RestoreState(pile, true);     // interrupted here !
+        if (m_incr != nullptr ) m_incr->RestoreState(pile, true);     // interrupted here !
         return;
     }
 }
 
+std::string CBotFor::GetDebugData()
+{
+    return !m_label.empty() ? "m_label = "+m_label : "";
+}
+
+std::map<std::string, CBotInstr*> CBotFor::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_init"] = m_init;
+    links["m_test"] = m_test;
+    links["m_incr"] = m_incr;
+    links["m_block"] = m_block;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotFor.h b/src/CBot/CBotInstr/CBotFor.h
index bed1fde..4f72db9 100644
--- a/src/CBot/CBotInstr/CBotFor.h
+++ b/src/CBot/CBotInstr/CBotFor.h
@@ -63,18 +63,22 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
-private:
+protected:
+    virtual const std::string GetDebugName() { return "CBotFor"; }
+    virtual std::string GetDebugData();
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
 
+private:
     //! Initial intruction
-    CBotInstr*    m_Init;
+    CBotInstr* m_init;
     //! Test Condition
-    CBotInstr*    m_Test;
+    CBotInstr* m_test;
     //! instruction for increment
-    CBotInstr*    m_Incr;
+    CBotInstr* m_incr;
     //! Instructions
-    CBotInstr*    m_Block;
+    CBotInstr* m_block;
     //! A label if there is
-    std::string    m_label;
+    std::string m_label;
 };
 
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotFunction.cpp b/src/CBot/CBotInstr/CBotFunction.cpp
index f2855d0..ae68a85 100644
--- a/src/CBot/CBotInstr/CBotFunction.cpp
+++ b/src/CBot/CBotInstr/CBotFunction.cpp
@@ -36,6 +36,7 @@
 #include "CBot/CBotVar/CBotVar.h"
 
 #include <cassert>
+#include <sstream>
 
 namespace CBot
 {
@@ -43,8 +44,8 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotFunction::CBotFunction()
 {
-    m_Param      = nullptr;            // empty parameter list
-    m_Block      = nullptr;            // the instruction block
+    m_param = nullptr;            // empty parameter list
+    m_block = nullptr;            // the instruction block
     m_next       = nullptr;            // functions can be chained
     m_bPublic    = false;           // function not public
     m_bExtern    = false;           // function not extern
@@ -60,8 +61,8 @@ std::set<CBotFunction*> CBotFunction::m_publicFunctions{};
 ////////////////////////////////////////////////////////////////////////////////
 CBotFunction::~CBotFunction()
 {
-    delete  m_Param;                // empty parameter list
-    delete  m_Block;                // the instruction block
+    delete m_param;                // empty parameter list
+    delete m_block;                // the instruction block
     delete  m_next;
 
     // remove public list if there is
@@ -185,7 +186,7 @@ CBotFunction* CBotFunction::Compile(CBotToken* &p, CBotCStack* pStack, CBotFunct
 
             }
             func->m_openpar = *p;
-            func->m_Param = CBotDefParam::Compile( p, pStk );
+            func->m_param = CBotDefParam::Compile(p, pStk );
             func->m_closepar = *(p->GetPrev());
             if (pStk->IsOk())
             {
@@ -219,7 +220,7 @@ CBotFunction* CBotFunction::Compile(CBotToken* &p, CBotCStack* pStack, CBotFunct
 
                 // and compiles the following instruction block
                 func->m_openblk = *p;
-                func->m_Block   = CBotBlock::Compile(p, pStk, false);
+                func->m_block = CBotBlock::Compile(p, pStk, false);
                 func->m_closeblk = (p != nullptr && p->GetPrev() != nullptr) ? *(p->GetPrev()) : CBotToken();
                 if ( pStk->IsOk() )
                 {
@@ -294,12 +295,12 @@ CBotFunction* CBotFunction::Compile1(CBotToken* &p, CBotCStack* pStack, CBotClas
                 if (!IsOfType(p, TokenTypVar)) goto bad;
 
             }
-            func->m_Param = CBotDefParam::Compile( p, pStk );
+            func->m_param = CBotDefParam::Compile(p, pStk );
             if (pStk->IsOk())
             {
                 // looks if the function exists elsewhere
-                if (( pClass != nullptr || !pStack->CheckCall(pp, func->m_Param)) &&
-                    ( pClass == nullptr || !pClass->CheckCall(pStack->GetProgram(), func->m_Param, pp)) )
+                if (( pClass != nullptr || !pStack->CheckCall(pp, func->m_param)) &&
+                    ( pClass == nullptr || !pClass->CheckCall(pStack->GetProgram(), func->m_param, pp)) )
                 {
                     if (IsOfType(p, ID_OPBLK))
                     {
@@ -339,7 +340,7 @@ bool CBotFunction::Execute(CBotVar** ppVars, CBotStack* &pj, CBotVar* pInstance)
 
     if ( pile->GetState() == 0 )
     {
-        if ( !m_Param->Execute(ppVars, pile) ) return false;    // define parameters
+        if ( !m_param->Execute(ppVars, pile) ) return false;    // define parameters
         pile->IncState();
     }
 
@@ -374,7 +375,7 @@ bool CBotFunction::Execute(CBotVar** ppVars, CBotStack* &pj, CBotVar* pInstance)
 
     if ( pile->IfStep() ) return false;
 
-    if ( !m_Block->Execute(pile) )
+    if ( !m_block->Execute(pile) )
     {
         if ( pile->GetError() < 0 )
             pile->SetError( CBotNoErr );
@@ -402,7 +403,7 @@ void CBotFunction::RestoreState(CBotVar** ppVars, CBotStack* &pj, CBotVar* pInst
         pile2->Delete();
     }
 
-    m_Param->RestoreState(pile2, true);                 // parameters
+    m_param->RestoreState(pile2, true);                 // parameters
 
     if ( !m_MasterClass.empty() )
     {
@@ -411,7 +412,7 @@ void CBotFunction::RestoreState(CBotVar** ppVars, CBotStack* &pj, CBotVar* pInst
         pThis->SetUniqNum(-2);
     }
 
-    m_Block->RestoreState(pile2, true);
+    m_block->RestoreState(pile2, true);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -477,7 +478,7 @@ CBotFunction* CBotFunction::FindLocalOrPublic(long& nIdent, const std::string& n
                 int i = 0;
                 int alpha = 0;                          // signature of parameters
                 // parameters are compatible?
-                CBotDefParam* pv = pt->m_Param;         // expected list of parameters
+                CBotDefParam* pv = pt->m_param;         // expected list of parameters
                 CBotVar* pw = ppVars[i++];              // provided list parameter
                 while ( pv != nullptr && pw != nullptr)
                 {
@@ -532,7 +533,7 @@ CBotFunction* CBotFunction::FindLocalOrPublic(long& nIdent, const std::string& n
                 int i = 0;
                 int alpha = 0;                          // signature of parameters
                 // parameters sont-ils compatibles ?
-                CBotDefParam* pv = pt->m_Param;         // list of expected parameters
+                CBotDefParam* pv = pt->m_param;         // list of expected parameters
                 CBotVar* pw = ppVars[i++];              // list of provided parameters
                 while ( pv != nullptr && pw != nullptr)
                 {
@@ -638,7 +639,7 @@ int CBotFunction::DoCall(long& nIdent, const std::string& name, CBotVar** ppVars
             }
 
             // initializes the variables as parameters
-            pt->m_Param->Execute(ppVars, pStk3);            // cannot be interrupted
+            pt->m_param->Execute(ppVars, pStk3);            // cannot be interrupted
 
             pStk1->IncState();
         }
@@ -646,7 +647,7 @@ int CBotFunction::DoCall(long& nIdent, const std::string& name, CBotVar** ppVars
         // finally execution of the found function
 
         if ( !pStk3->GetRetVar(                     // puts the result on the stack
-            pt->m_Block->Execute(pStk3) ))          // GetRetVar said if it is interrupted
+            pt->m_block->Execute(pStk3) ))          // GetRetVar said if it is interrupted
         {
             if ( !pStk3->IsOk() && pt->m_pProg != m_pProg )
             {
@@ -707,13 +708,13 @@ void CBotFunction::RestoreCall(long& nIdent, const std::string& name, CBotVar**
 
         if ( pStk1->GetState() == 0 )
         {
-            pt->m_Param->RestoreState(pStk3, true);
+            pt->m_param->RestoreState(pStk3, true);
             return;
         }
 
         // initializes the variables as parameters
-        pt->m_Param->RestoreState(pStk3, false);
-        pt->m_Block->RestoreState(pStk3, true);
+        pt->m_param->RestoreState(pStk3, false);
+        pt->m_block->RestoreState(pStk3, true);
     }
 }
 
@@ -756,7 +757,7 @@ int CBotFunction::DoCall(long& nIdent, const std::string& name, CBotVar* pThis,
                 pStk->AddVar(psuper);
             }
             // initializes the variables as parameters
-            pt->m_Param->Execute(ppVars, pStk3);            // cannot be interrupted
+            pt->m_param->Execute(ppVars, pStk3);            // cannot be interrupted
             pStk->IncState();
         }
 
@@ -772,7 +773,7 @@ int CBotFunction::DoCall(long& nIdent, const std::string& name, CBotVar* pThis,
         // finally calls the found function
 
         if ( !pStk3->GetRetVar(                         // puts the result on the stack
-            pt->m_Block->Execute(pStk3) ))          // GetRetVar said if it is interrupted
+            pt->m_block->Execute(pStk3) ))          // GetRetVar said if it is interrupted
         {
             if ( !pStk3->IsOk() )
             {
@@ -818,7 +819,7 @@ void CBotFunction::RestoreCall(long& nIdent, const std::string& name, CBotVar* p
         CBotStack*  pStk3 = pStk->RestoreStack(nullptr);   // to set parameters passed
         if ( pStk3 == nullptr ) return;
 
-        pt->m_Param->RestoreState(pStk3, true);                 // parameters
+        pt->m_param->RestoreState(pStk3, true);                 // parameters
 
         if ( pStk->GetState() > 1 &&                        // latching is effective?
              pt->m_bSynchro )
@@ -829,14 +830,14 @@ void CBotFunction::RestoreCall(long& nIdent, const std::string& name, CBotVar* p
 
         // finally calls the found function
 
-        pt->m_Block->RestoreState(pStk3, true);                 // interrupt !
+        pt->m_block->RestoreState(pStk3, true);                 // interrupt !
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 bool CBotFunction::CheckParam(CBotDefParam* pParam)
 {
-    CBotDefParam*   pp = m_Param;
+    CBotDefParam*   pp = m_param;
     while ( pp != nullptr && pParam != nullptr )
     {
         CBotTypResult type1 = pp->GetType();
@@ -857,10 +858,10 @@ std::string CBotFunction::GetName()
 ////////////////////////////////////////////////////////////////////////////////
 std::string CBotFunction::GetParams()
 {
-    if ( m_Param == nullptr ) return std::string("()");
+    if (m_param == nullptr ) return std::string("()");
 
     std::string      params = "( ";
-    CBotDefParam*   p = m_Param;        // list of parameters
+    CBotDefParam*   p = m_param;        // list of parameters
 
     while (p != nullptr)
     {
@@ -885,4 +886,21 @@ void CBotFunction::AddPublic(CBotFunction* func)
     m_publicFunctions.insert(func);
 }
 
+std::string CBotFunction::GetDebugData()
+{
+    std::stringstream ss;
+    if (IsPublic()) ss << "public ";
+    if (IsExtern()) ss << "extern ";
+    ss << GetName() << GetParams();
+    //ss << "FuncID = " << m_nFuncIdent;
+    return ss.str();
+}
+
+std::map<std::string, CBotInstr*> CBotFunction::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_block"] = m_block;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotFunction.h b/src/CBot/CBotInstr/CBotFunction.h
index 76b31b3..3cc051d 100644
--- a/src/CBot/CBotInstr/CBotFunction.h
+++ b/src/CBot/CBotInstr/CBotFunction.h
@@ -241,15 +241,21 @@ public:
                      CBotGet modestart,
                      CBotGet modestop);
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotFunction"; }
+    virtual std::string GetDebugData();
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
+    friend class CBotDebug;
     long m_nFuncIdent;
     //! Synchronized method.
     bool m_bSynchro;
 
     //! Parameter list.
-    CBotDefParam* m_Param;
+    CBotDefParam* m_param;
     //! The instruction block.
-    CBotInstr* m_Block;
+    CBotInstr* m_block;
     CBotFunction* m_next;
     //! If returns CBotTypClass.
     CBotToken m_retToken;
diff --git a/src/CBot/CBotInstr/CBotIString.cpp b/src/CBot/CBotInstr/CBotIString.cpp
index d01fab9..2eac0e5 100644
--- a/src/CBot/CBotInstr/CBotIString.cpp
+++ b/src/CBot/CBotInstr/CBotIString.cpp
@@ -32,9 +32,8 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotIString::CBotIString()
 {
-    m_var    =
-    m_expr    = nullptr;
-    name = "CBotIString";
+    m_var    = nullptr;
+    m_expr   = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -157,4 +156,12 @@ void CBotIString::RestoreState(CBotStack* &pj, bool bMain)
          m_next2b->RestoreState(pile, bMain);
 }
 
+std::map<std::string, CBotInstr*> CBotIString::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_var"] = m_var;
+    links["m_expr"] = m_expr;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotIString.h b/src/CBot/CBotInstr/CBotIString.h
index f6d3b63..7f7f456 100644
--- a/src/CBot/CBotInstr/CBotIString.h
+++ b/src/CBot/CBotInstr/CBotIString.h
@@ -65,6 +65,10 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotIString"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! Variable to initialise.
     CBotInstr* m_var;
diff --git a/src/CBot/CBotInstr/CBotIf.cpp b/src/CBot/CBotInstr/CBotIf.cpp
index cdf0a7d..9386756 100644
--- a/src/CBot/CBotInstr/CBotIf.cpp
+++ b/src/CBot/CBotInstr/CBotIf.cpp
@@ -30,18 +30,17 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotIf::CBotIf()
 {
-    m_Condition =
-    m_Block     =
-    m_BlockElse = nullptr;         // nullptr so that delete is not possible further
-    name = "CBotIf";            // debug
+    m_condition = nullptr;
+    m_block = nullptr;
+    m_blockElse = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotIf::~CBotIf()
 {
-    delete  m_Condition;        // frees the condition
-    delete  m_Block;            // frees the block of instruction1
-    delete  m_BlockElse;        // frees the block of instruction2
+    delete m_condition;        // frees the condition
+    delete m_block;            // frees the block of instruction1
+    delete m_blockElse;        // frees the block of instruction2
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -56,11 +55,11 @@ CBotInstr* CBotIf::Compile(CBotToken* &p, CBotCStack* pStack)
     CBotIf* inst = new CBotIf();                // create the object
     inst->SetToken( pp );
 
-    if ( nullptr != (inst->m_Condition = CBotCondition::Compile( p, pStk )) )
+    if ( nullptr != (inst->m_condition = CBotCondition::Compile(p, pStk )) )
     {
         // the condition does exist
 
-        inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true );
+        inst->m_block = CBotBlock::CompileBlkOrInst(p, pStk, true );
         if ( pStk->IsOk() )
         {
             // the statement block is ok (can be empty)
@@ -69,7 +68,7 @@ CBotInstr* CBotIf::Compile(CBotToken* &p, CBotCStack* pStack)
             if (IsOfType(p, ID_ELSE))
             {
                 // if so, compiles the following statement block
-                inst->m_BlockElse = CBotBlock::CompileBlkOrInst( p, pStk, true );
+                inst->m_blockElse = CBotBlock::CompileBlkOrInst(p, pStk, true );
                 if (!pStk->IsOk())
                 {
                     // there is no correct block after the else
@@ -103,7 +102,7 @@ bool CBotIf :: Execute(CBotStack* &pj)
     if( pile->GetState() == 0 )
     {
         // evaluates the condition
-        if ( !m_Condition->Execute(pile) ) return false;    // interrupted here?
+        if ( !m_condition->Execute(pile) ) return false;    // interrupted here?
 
         // terminates if there is an error
         if ( !pile->IsOk() )
@@ -120,13 +119,13 @@ bool CBotIf :: Execute(CBotStack* &pj)
 
     if ( pile->GetVal() == true )                           // condition was true?
     {
-        if ( m_Block != nullptr &&                             // block may be absent
-            !m_Block->Execute(pile) ) return false;         // interrupted here?
+        if (m_block != nullptr &&                             // block may be absent
+            !m_block->Execute(pile) ) return false;         // interrupted here?
     }
     else
     {
-        if ( m_BlockElse != nullptr &&                         // if there is an alternate block
-            !m_BlockElse->Execute(pile) ) return false; // interrupted here
+        if (m_blockElse != nullptr &&                         // if there is an alternate block
+            !m_blockElse->Execute(pile) ) return false; // interrupted here
     }
 
     // sends the results and releases the stack
@@ -145,7 +144,7 @@ void CBotIf :: RestoreState(CBotStack* &pj, bool bMain)
     if( pile->GetState() == 0 )
     {
         // evaluates the condition
-        m_Condition->RestoreState(pile, bMain); // interrupted here!
+        m_condition->RestoreState(pile, bMain); // interrupted here!
         return;
     }
 
@@ -154,14 +153,23 @@ void CBotIf :: RestoreState(CBotStack* &pj, bool bMain)
 
     if ( pile->GetVal() == true )                           // condition was true?
     {
-        if ( m_Block != nullptr )                              // block may be absent
-             m_Block->RestoreState(pile, bMain);            // interrupted here!
+        if (m_block != nullptr )                              // block may be absent
+             m_block->RestoreState(pile, bMain);            // interrupted here!
     }
     else
     {
-        if ( m_BlockElse != nullptr )                          // if there is an alternate block
-             m_BlockElse->RestoreState(pile, bMain);        // interrupted here!
+        if (m_blockElse != nullptr )                          // if there is an alternate block
+             m_blockElse->RestoreState(pile, bMain);        // interrupted here!
     }
 }
 
+std::map<std::string, CBotInstr*> CBotIf::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_condition"] = m_condition;
+    links["m_block"] = m_block;
+    links["m_blockElse"] = m_blockElse;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotIf.h b/src/CBot/CBotInstr/CBotIf.h
index b479fde..f83a55a 100644
--- a/src/CBot/CBotInstr/CBotIf.h
+++ b/src/CBot/CBotInstr/CBotIf.h
@@ -64,13 +64,17 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotIf"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! Condition
-    CBotInstr*    m_Condition;
+    CBotInstr* m_condition;
     //! Instruction
-    CBotInstr*    m_Block;
+    CBotInstr* m_block;
     //! Instruction
-    CBotInstr*    m_BlockElse;
+    CBotInstr* m_blockElse;
 };
 
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotIndexExpr.cpp b/src/CBot/CBotInstr/CBotIndexExpr.cpp
index 1629c26..cf81390 100644
--- a/src/CBot/CBotInstr/CBotIndexExpr.cpp
+++ b/src/CBot/CBotInstr/CBotIndexExpr.cpp
@@ -33,7 +33,6 @@ namespace CBot
 CBotIndexExpr::CBotIndexExpr()
 {
     m_expr    = nullptr;
-    name    = "CBotIndexExpr";
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -118,4 +117,11 @@ void CBotIndexExpr::RestoreStateVar(CBotStack* &pile, bool bMain)
          m_next3->RestoreStateVar(pile, bMain);
 }
 
+std::map<std::string, CBotInstr*> CBotIndexExpr::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_expr"] = m_expr;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotIndexExpr.h b/src/CBot/CBotInstr/CBotIndexExpr.h
index 713a9d6..ad0bd08 100644
--- a/src/CBot/CBotInstr/CBotIndexExpr.h
+++ b/src/CBot/CBotInstr/CBotIndexExpr.h
@@ -70,6 +70,9 @@ public:
      */
     void RestoreStateVar(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotIndexExpr"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
 
 private:
     //! Expression for calculating the index.
diff --git a/src/CBot/CBotInstr/CBotInstArray.cpp b/src/CBot/CBotInstr/CBotInstArray.cpp
index 455de83..24805b5 100644
--- a/src/CBot/CBotInstr/CBotInstArray.cpp
+++ b/src/CBot/CBotInstr/CBotInstArray.cpp
@@ -17,6 +17,7 @@
  * along with this program. If not, see http://gnu.org/licenses
  */
 
+#include <sstream>
 #include "CBot/CBotInstr/CBotInstArray.h"
 
 #include "CBot/CBotInstr/CBotLeftExprVar.h"
@@ -37,9 +38,8 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotInstArray::CBotInstArray()
 {
-    m_var      = nullptr;
+    m_var     = nullptr;
     m_listass = nullptr;
-    name = "CBotInstArray";
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -227,4 +227,19 @@ void CBotInstArray::RestoreState(CBotStack* &pj, bool bMain)
     if (m_next2b ) m_next2b->RestoreState( pile1, bMain);
 }
 
+std::string CBotInstArray::GetDebugData()
+{
+    std::stringstream ss;
+    ss << m_typevar.ToString();
+    return ss.str();
+}
+
+std::map<std::string, CBotInstr*> CBotInstArray::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_var"] = m_var;
+    links["m_listass"] = m_listass;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotInstArray.h b/src/CBot/CBotInstr/CBotInstArray.h
index 46ebc4d..1f55c22 100644
--- a/src/CBot/CBotInstr/CBotInstArray.h
+++ b/src/CBot/CBotInstr/CBotInstArray.h
@@ -67,8 +67,12 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
-private:
+protected:
+    virtual const std::string GetDebugName() { return "CBotInstrArray"; }
+    virtual std::string GetDebugData();
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
 
+private:
     //! The variables to initialize.
     CBotInstr* m_var;
     //! List of assignments for array.
diff --git a/src/CBot/CBotInstr/CBotInstr.cpp b/src/CBot/CBotInstr/CBotInstr.cpp
index e402275..b5c6279 100644
--- a/src/CBot/CBotInstr/CBotInstr.cpp
+++ b/src/CBot/CBotInstr/CBotInstr.cpp
@@ -53,7 +53,6 @@ std::vector<std::string> CBotInstr::m_labelLvl = std::vector<std::string>();
 ////////////////////////////////////////////////////////////////////////////////
 CBotInstr::CBotInstr()
 {
-    name     = "CBotInstr";
     m_next   = nullptr;
     m_next2b = nullptr;
     m_next3  = nullptr;
@@ -360,4 +359,14 @@ CBotInstr* CBotInstr::CompileArray(CBotToken* &p, CBotCStack* pStack, CBotTypRes
     return nullptr;
 }
 
+std::map<std::string, CBotInstr*> CBotInstr::GetDebugLinks()
+{
+    return {
+        {"m_next", m_next},
+        {"m_next2b", m_next2b},
+        {"m_next3", m_next3},
+        {"m_next3b", m_next3b}
+    };
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotInstr.h b/src/CBot/CBotInstr/CBotInstr.h
index 70a69b2..a92470c 100644
--- a/src/CBot/CBotInstr/CBotInstr.h
+++ b/src/CBot/CBotInstr/CBotInstr.h
@@ -26,6 +26,7 @@
 
 namespace CBot
 {
+class CBotDebug;
 
 /*
     for example, the following program
@@ -248,11 +249,15 @@ public:
     static bool ChkLvl(const std::string& label, int type);
 
 protected:
+    friend class CBotDebug;
+    virtual const std::string GetDebugName() = 0;
+    virtual std::string GetDebugData() { return ""; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
+protected:
 
     //! Keeps the token.
     CBotToken m_token;
-    //! Debug.
-    std::string name;
     //! Linked command.
     CBotInstr* m_next;
     //! Second list definition chain.
diff --git a/src/CBot/CBotInstr/CBotInstrCall.cpp b/src/CBot/CBotInstr/CBotInstrCall.cpp
index da3512a..a8d77ba 100644
--- a/src/CBot/CBotInstr/CBotInstrCall.cpp
+++ b/src/CBot/CBotInstr/CBotInstrCall.cpp
@@ -17,6 +17,7 @@
  * along with this program. If not, see http://gnu.org/licenses
  */
 
+#include <sstream>
 #include "CBotInstrCall.h"
 #include "CBot/CBotInstr/CBotExpression.h"
 
@@ -31,15 +32,14 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotInstrCall::CBotInstrCall()
 {
-    m_Parameters = nullptr;
+    m_parameters = nullptr;
     m_nFuncIdent = 0;
-    name = "CBotInstrCall";
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotInstrCall::~CBotInstrCall()
 {
-    delete  m_Parameters;
+    delete m_parameters;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -69,8 +69,8 @@ CBotInstr* CBotInstrCall::Compile(CBotToken* &p, CBotCStack* pStack)
 
             CBotInstr*  param = CBotExpression::Compile(p, pile);
             end   = p->GetStart();
-            if ( inst->m_Parameters == nullptr ) inst->m_Parameters = param;
-            else inst->m_Parameters->AddNext(param);            // constructs the list
+            if (inst->m_parameters == nullptr ) inst->m_parameters = param;
+            else inst->m_parameters->AddNext(param);            // constructs the list
 
             if ( !pile->IsOk() )
             {
@@ -140,7 +140,7 @@ bool CBotInstrCall::Execute(CBotStack* &pj)
 
     int     i = 0;
 
-    CBotInstr*  p = m_Parameters;
+    CBotInstr*  p = m_parameters;
     // evaluates parameters
     // and places the values ​​on the stack
     // for allow of interruption at any time
@@ -178,7 +178,7 @@ void CBotInstrCall::RestoreState(CBotStack* &pj, bool bMain)
 
     int         i = 0;
     CBotVar*    ppVars[1000];
-    CBotInstr*  p = m_Parameters;
+    CBotInstr*  p = m_parameters;
     // evaluate parameters
     // and place the values on the stack
     // for allow of interruption at any time
@@ -203,4 +203,20 @@ void CBotInstrCall::RestoreState(CBotStack* &pj, bool bMain)
     pile2->RestoreCall(m_nFuncIdent, GetToken(), ppVars);
 }
 
+std::string CBotInstrCall::GetDebugData()
+{
+    std::stringstream ss;
+    ss << m_token.GetString() << std::endl;
+    //ss << "FuncID = " << m_nFuncIdent << std::endl;
+    ss << "resultType = " << m_typRes.ToString();
+    return ss.str();
+}
+
+std::map<std::string, CBotInstr*> CBotInstrCall::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_parameters"] = m_parameters;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotInstrCall.h b/src/CBot/CBotInstr/CBotInstrCall.h
index 223d777..9343f78 100644
--- a/src/CBot/CBotInstr/CBotInstrCall.h
+++ b/src/CBot/CBotInstr/CBotInstrCall.h
@@ -63,13 +63,19 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotInstrCall"; }
+    virtual std::string GetDebugData();
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! The parameters to be evaluated.
-    CBotInstr*  m_Parameters;
+    CBotInstr* m_parameters;
     //! Complete type of the result.
     CBotTypResult m_typRes;
     //! Id of a function.
     long m_nFuncIdent;
+    friend class CBotDebug;
 };
 
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotInstrMethode.cpp b/src/CBot/CBotInstr/CBotInstrMethode.cpp
index 3c891de..05998d2 100644
--- a/src/CBot/CBotInstr/CBotInstrMethode.cpp
+++ b/src/CBot/CBotInstr/CBotInstrMethode.cpp
@@ -17,6 +17,7 @@
  * along with this program. If not, see http://gnu.org/licenses
  */
 
+#include <sstream>
 #include "CBot/CBotInstr/CBotInstrMethode.h"
 
 #include "CBot/CBotInstr/CBotInstrUtils.h"
@@ -33,15 +34,14 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotInstrMethode::CBotInstrMethode()
 {
-    m_Parameters    = nullptr;
-    m_MethodeIdent  = 0;
-    name = "CBotInstrMethode";
+    m_parameters = nullptr;
+    m_MethodeIdent = 0;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotInstrMethode::~CBotInstrMethode()
 {
-    delete    m_Parameters;
+    delete m_parameters;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -57,17 +57,17 @@ CBotInstr* CBotInstrMethode::Compile(CBotToken* &p, CBotCStack* pStack, CBotVar*
 
         if (p->GetType() == ID_OPENPAR)
         {
-            inst->m_NomMethod = pp->GetString();
+            inst->m_methodName = pp->GetString();
 
             // compiles the list of parameters
             CBotVar*    ppVars[1000];
-            inst->m_Parameters = CompileParams(p, pStack, ppVars);
+            inst->m_parameters = CompileParams(p, pStack, ppVars);
 
             if (pStack->IsOk())
             {
                 CBotClass* pClass = var->GetClass();    // pointer to the class
-                inst->m_ClassName = pClass->GetName();  // name of the class
-                CBotTypResult r = pClass->CompileMethode(inst->m_NomMethod, var, ppVars,
+                inst->m_className = pClass->GetName();  // name of the class
+                CBotTypResult r = pClass->CompileMethode(inst->m_methodName, var, ppVars,
                                                          pStack, inst->m_MethodeIdent);
                 delete pStack->TokenStack();    // release parameters on the stack
                 inst->m_typRes = r;
@@ -129,7 +129,7 @@ bool CBotInstrMethode::ExecuteVar(CBotVar* &pVar, CBotStack* &pj, CBotToken* pre
     }
     int        i = 0;
 
-    CBotInstr*    p = m_Parameters;
+    CBotInstr*    p = m_parameters;
     // evaluate the parameters
     // and places the values on the stack
     // to be interrupted at any time
@@ -148,7 +148,7 @@ bool CBotInstrMethode::ExecuteVar(CBotVar* &pVar, CBotStack* &pj, CBotToken* pre
     }
     ppVars[i] = nullptr;
 
-    CBotClass*    pClass = CBotClass::Find(m_ClassName);
+    CBotClass*    pClass = CBotClass::Find(m_className);
     CBotVar*    pThis  = pile1->FindVar(-2, false);
     CBotVar*    pResult = nullptr;
     if (m_typRes.GetType() > 0) pResult = CBotVar::Create("", m_typRes);
@@ -158,7 +158,7 @@ bool CBotInstrMethode::ExecuteVar(CBotVar* &pVar, CBotStack* &pj, CBotToken* pre
     }
     CBotVar*    pRes = pResult;
 
-    if ( !pClass->ExecuteMethode(m_MethodeIdent, m_NomMethod,
+    if ( !pClass->ExecuteMethode(m_MethodeIdent, m_methodName,
                                  pThis, ppVars,
                                  pResult, pile2, GetToken())) return false;
     if (pRes != pResult) delete pRes;
@@ -184,7 +184,7 @@ void CBotInstrMethode::RestoreStateVar(CBotStack* &pile, bool bMain)
 
     int        i = 0;
 
-    CBotInstr*    p = m_Parameters;
+    CBotInstr*    p = m_parameters;
     // evaluate the parameters
     // and places the values on the stack
     // to be interrupted at any time
@@ -205,13 +205,13 @@ void CBotInstrMethode::RestoreStateVar(CBotStack* &pile, bool bMain)
     }
     ppVars[i] = nullptr;
 
-    CBotClass*    pClass = CBotClass::Find(m_ClassName);
+    CBotClass*    pClass = CBotClass::Find(m_className);
 //    CBotVar*    pResult = nullptr;
 
 //    CBotVar*    pRes = pResult;
 
-    pClass->RestoreMethode(m_MethodeIdent, m_NomMethod,
-                                 pThis, ppVars, pile2);
+    pClass->RestoreMethode(m_MethodeIdent, m_methodName,
+                           pThis, ppVars, pile2);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -236,7 +236,7 @@ bool CBotInstrMethode::Execute(CBotStack* &pj)
     }
     int        i = 0;
 
-    CBotInstr*    p = m_Parameters;
+    CBotInstr*    p = m_parameters;
     // evaluate the parameters
     // and places the values on the stack
     // to be interrupted at any time
@@ -254,7 +254,7 @@ bool CBotInstrMethode::Execute(CBotStack* &pj)
     }
     ppVars[i] = nullptr;
 
-    CBotClass*    pClass = CBotClass::Find(m_ClassName);
+    CBotClass*    pClass = CBotClass::Find(m_className);
     CBotVar*    pThis  = pile1->FindVar("this");
     CBotVar*    pResult = nullptr;
     if (m_typRes.GetType()>0) pResult = CBotVar::Create("", m_typRes);
@@ -264,7 +264,7 @@ bool CBotInstrMethode::Execute(CBotStack* &pj)
     }
     CBotVar*    pRes = pResult;
 
-    if ( !pClass->ExecuteMethode(m_MethodeIdent, m_NomMethod,
+    if ( !pClass->ExecuteMethode(m_MethodeIdent, m_methodName,
                                  pThis, ppVars,
                                  pResult, pile2, GetToken())) return false;    // interupted
 
@@ -277,4 +277,20 @@ bool CBotInstrMethode::Execute(CBotStack* &pj)
     return pj->Return(pile2);    // release the entire stack
 }
 
+std::string CBotInstrMethode::GetDebugData()
+{
+    std::stringstream ss;
+    ss << m_methodName << std::endl;
+    ss << "MethodID = " << m_MethodeIdent << std::endl;
+    ss << "result = " << m_typRes.GetType(); // TODO: Type to string?
+    return ss.str();
+}
+
+std::map<std::string, CBotInstr*> CBotInstrMethode::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_parameters"] = m_parameters;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotInstrMethode.h b/src/CBot/CBotInstr/CBotInstrMethode.h
index e78b492..75b8360 100644
--- a/src/CBot/CBotInstr/CBotInstrMethode.h
+++ b/src/CBot/CBotInstr/CBotInstrMethode.h
@@ -75,17 +75,22 @@ public:
      */
     void RestoreStateVar(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotInstrMethode"; }
+    virtual std::string GetDebugData();
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! The parameters to be evaluated.
-    CBotInstr *m_Parameters;
+    CBotInstr* m_parameters;
     //! Complete type of the result.
     CBotTypResult m_typRes;
     //! Name of the method.
-    std::string m_NomMethod;
+    std::string m_methodName;
     //! Identifier of the method.
     long m_MethodeIdent;
     //! Name of the class.
-    std::string m_ClassName;
+    std::string m_className;
 };
 
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotInt.cpp b/src/CBot/CBotInstr/CBotInt.cpp
index 3cc7d9e..d711385 100644
--- a/src/CBot/CBotInstr/CBotInt.cpp
+++ b/src/CBot/CBotInstr/CBotInt.cpp
@@ -35,9 +35,8 @@ namespace CBot
 CBotInt::CBotInt()
 {
     m_next    = nullptr;            // for multiple definitions
-    m_var    =
+    m_var     = nullptr;
     m_expr    = nullptr;
-    name = "CBotInt";
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -186,4 +185,12 @@ void CBotInt::RestoreState(CBotStack* &pj, bool bMain)
     if (m_next2b) m_next2b->RestoreState(pile, bMain);            // other(s) definition(s)
 }
 
+std::map<std::string, CBotInstr*> CBotInt::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_var"] = m_var;
+    links["m_expr"] = m_expr;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotInt.h b/src/CBot/CBotInstr/CBotInt.h
index 2dbe3be..df4de32 100644
--- a/src/CBot/CBotInstr/CBotInt.h
+++ b/src/CBot/CBotInstr/CBotInt.h
@@ -66,8 +66,11 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
-private:
+protected:
+    virtual const std::string GetDebugName() { return "CBotInt"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
 
+private:
     //! The variable to initialize.
     CBotInstr* m_var;
     //! A value to put, if there is.
diff --git a/src/CBot/CBotInstr/CBotLeftExpr.cpp b/src/CBot/CBotInstr/CBotLeftExpr.cpp
index 0256601..753500b 100644
--- a/src/CBot/CBotInstr/CBotLeftExpr.cpp
+++ b/src/CBot/CBotInstr/CBotLeftExpr.cpp
@@ -17,6 +17,7 @@
  * along with this program. If not, see http://gnu.org/licenses
  */
 
+#include <sstream>
 #include "CBot/CBotInstr/CBotLeftExpr.h"
 #include "CBot/CBotInstr/CBotFieldExpr.h"
 #include "CBot/CBotInstr/CBotIndexExpr.h"
@@ -34,7 +35,6 @@ namespace CBot
 //////////////////////////////////////////////////////////////////////////////////////
 CBotLeftExpr::CBotLeftExpr()
 {
-    name    = "CBotLeftExpr";
     m_nIdent = 0;
 }
 
@@ -241,4 +241,12 @@ void CBotLeftExpr::RestoreStateVar(CBotStack* &pile, bool bMain)
          m_next3->RestoreStateVar(pile, bMain);
 }
 
+std::string CBotLeftExpr::GetDebugData()
+{
+    std::stringstream ss;
+    ss << m_token.GetString();
+    //ss << "VarID = " << m_nIdent;
+    return ss.str();
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotLeftExpr.h b/src/CBot/CBotInstr/CBotLeftExpr.h
index b99e747..989c3c2 100644
--- a/src/CBot/CBotInstr/CBotLeftExpr.h
+++ b/src/CBot/CBotInstr/CBotLeftExpr.h
@@ -93,6 +93,10 @@ public:
      */
     void RestoreStateVar(CBotStack* &pile, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotLeftExpr"; }
+    virtual std::string GetDebugData();
+
 private:
     long m_nIdent;
 };
diff --git a/src/CBot/CBotInstr/CBotLeftExprVar.cpp b/src/CBot/CBotInstr/CBotLeftExprVar.cpp
index c563bcd..4f4b18d 100644
--- a/src/CBot/CBotInstr/CBotLeftExprVar.cpp
+++ b/src/CBot/CBotInstr/CBotLeftExprVar.cpp
@@ -25,13 +25,13 @@
 #include "CBot/CBotVar/CBotVar.h"
 
 #include <cassert>
+#include <sstream>
 
 namespace CBot
 {
 
 CBotLeftExprVar::CBotLeftExprVar()
 {
-    name = "CBotLeftExprVar";
 }
 
 CBotLeftExprVar::~CBotLeftExprVar()
@@ -80,4 +80,13 @@ void CBotLeftExprVar::RestoreState(CBotStack* &pj, bool bMain)
     var1->SetUniqNum(m_nIdent); // Restore the identifier
 }
 
+std::string CBotLeftExprVar::GetDebugData()
+{
+    std::stringstream ss;
+    ss << m_token.GetString() << std::endl;
+    //ss << "VarID = " << m_nIdent << std::endl;
+    ss << "type = " << m_typevar.ToString();
+    return ss.str();
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotLeftExprVar.h b/src/CBot/CBotInstr/CBotLeftExprVar.h
index 984aebb..59c2157 100644
--- a/src/CBot/CBotInstr/CBotLeftExprVar.h
+++ b/src/CBot/CBotInstr/CBotLeftExprVar.h
@@ -50,8 +50,11 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
-public:
+protected:
+    virtual const std::string GetDebugName() { return "CBotLeftExprVar"; }
+    virtual std::string GetDebugData();
 
+public:
     //! Type of variable declared.
     CBotTypResult m_typevar = -1;
     //! Unique identifier of that variable
diff --git a/src/CBot/CBotInstr/CBotListArray.cpp b/src/CBot/CBotInstr/CBotListArray.cpp
index 00ae062..0151f29 100644
--- a/src/CBot/CBotInstr/CBotListArray.cpp
+++ b/src/CBot/CBotInstr/CBotListArray.cpp
@@ -35,8 +35,7 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotListArray::CBotListArray()
 {
-    m_expr    = nullptr;
-    name = "CBotListArray";
+    m_expr = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -179,4 +178,11 @@ void CBotListArray::RestoreState(CBotStack* &pj, bool bMain)
     }
 }
 
+std::map<std::string, CBotInstr*> CBotListArray::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_expr"] = m_expr;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotListArray.h b/src/CBot/CBotInstr/CBotListArray.h
index 33b0bd7..c019845 100644
--- a/src/CBot/CBotInstr/CBotListArray.h
+++ b/src/CBot/CBotInstr/CBotListArray.h
@@ -67,6 +67,10 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotListArray"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! An expression for an element others are linked with CBotInstr :: m_next3;
     CBotInstr* m_expr;
diff --git a/src/CBot/CBotInstr/CBotListExpression.cpp b/src/CBot/CBotInstr/CBotListExpression.cpp
index 363f21e..e621d67 100644
--- a/src/CBot/CBotInstr/CBotListExpression.cpp
+++ b/src/CBot/CBotInstr/CBotListExpression.cpp
@@ -48,14 +48,13 @@ static CBotInstr* CompileInstrOrDefVar(CBotToken* &p, CBotCStack* pStack)
 ////////////////////////////////////////////////////////////////////////////////
 CBotListExpression::CBotListExpression()
 {
-    m_Expr  = nullptr;
-    name = "CBotListExpression";
+    m_expr = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotListExpression::~CBotListExpression()
 {
-    delete  m_Expr;
+    delete m_expr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -63,13 +62,13 @@ CBotInstr* CBotListExpression::Compile(CBotToken* &p, CBotCStack* pStack)
 {
     CBotListExpression* inst = new CBotListExpression();
 
-    inst->m_Expr = CompileInstrOrDefVar( p, pStack );           // compile the first expression in a list
+    inst->m_expr = CompileInstrOrDefVar(p, pStack );           // compile the first expression in a list
     if (pStack->IsOk())
     {
         while ( IsOfType(p, ID_COMMA) )                         // more instructions?
         {
             CBotInstr*  i = CompileInstrOrDefVar( p, pStack );      // Is this a declaration of an integer?
-            inst->m_Expr->AddNext(i);                           // added after
+            inst->m_expr->AddNext(i);                           // added after
             if ( !pStack->IsOk() )
             {
                 delete inst;
@@ -86,7 +85,7 @@ CBotInstr* CBotListExpression::Compile(CBotToken* &p, CBotCStack* pStack)
 bool CBotListExpression::Execute(CBotStack* &pj)
 {
     CBotStack*  pile = pj->AddStack();                          // essential
-    CBotInstr*  p = m_Expr;                                     // the first expression
+    CBotInstr*  p = m_expr;                                     // the first expression
 
     int     state = pile->GetState();
     while (state-->0) p = p->GetNext();                         // returns to the interrupted operation
@@ -114,7 +113,7 @@ void CBotListExpression::RestoreState(CBotStack* &pj, bool bMain)
         state = pile->GetState();
     }
 
-    CBotInstr*  p = m_Expr;                                     // the first expression
+    CBotInstr*  p = m_expr;                                     // the first expression
 
     while (p != nullptr && state-->0)
     {
@@ -128,4 +127,11 @@ void CBotListExpression::RestoreState(CBotStack* &pj, bool bMain)
     }
 }
 
+std::map<std::string, CBotInstr*> CBotListExpression::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_expr"] = m_expr;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotListExpression.h b/src/CBot/CBotInstr/CBotListExpression.h
index e559e0d..2208f37 100644
--- a/src/CBot/CBotInstr/CBotListExpression.h
+++ b/src/CBot/CBotInstr/CBotListExpression.h
@@ -64,9 +64,13 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotListExpression"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! The first expression to be evaluated
-    CBotInstr* m_Expr;
+    CBotInstr* m_expr;
 };
 
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotListInstr.cpp b/src/CBot/CBotInstr/CBotListInstr.cpp
index 6eaa1bc..802f2b4 100644
--- a/src/CBot/CBotInstr/CBotListInstr.cpp
+++ b/src/CBot/CBotInstr/CBotListInstr.cpp
@@ -29,14 +29,13 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotListInstr::CBotListInstr()
 {
-    m_Instr        = nullptr;
-    name = "CBotListInstr";
+    m_instr = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotListInstr::~CBotListInstr()
 {
-    delete    m_Instr;
+    delete m_instr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -68,8 +67,8 @@ CBotInstr* CBotListInstr::Compile(CBotToken* &p, CBotCStack* pStack, bool bLocal
             return pStack->Return(nullptr, pStk);
         }
 
-        if (inst->m_Instr == nullptr) inst->m_Instr = i;
-        else inst->m_Instr->AddNext(i);                            // added a result
+        if (inst->m_instr == nullptr) inst->m_instr = i;
+        else inst->m_instr->AddNext(i);                            // added a result
     }
     return pStack->Return(inst, pStk);
 }
@@ -82,7 +81,7 @@ bool CBotListInstr::Execute(CBotStack* &pj)
     if (pile->StackOver() ) return pj->Return( pile);
 
 
-    CBotInstr*    p = m_Instr;                                    // the first expression
+    CBotInstr*    p = m_instr;                                    // the first expression
 
     int        state = pile->GetState();
     while (state-->0) p = p->GetNext();                            // returns to the interrupted operation
@@ -106,7 +105,7 @@ void CBotListInstr::RestoreState(CBotStack* &pj, bool bMain)
     CBotStack*    pile = pj->RestoreStack(this);
     if (pile == nullptr) return;
 
-    CBotInstr*    p = m_Instr;                                    // the first expression
+    CBotInstr*    p = m_instr;                                    // the first expression
 
     int        state = pile->GetState();
     while ( p != nullptr && state-- > 0)
@@ -118,4 +117,11 @@ void CBotListInstr::RestoreState(CBotStack* &pj, bool bMain)
     if (p != nullptr) p->RestoreState(pile, true);
 }
 
+std::map<std::string, CBotInstr*> CBotListInstr::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_instr"] = m_instr;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotListInstr.h b/src/CBot/CBotInstr/CBotListInstr.h
index 3623461..9c25271 100644
--- a/src/CBot/CBotInstr/CBotListInstr.h
+++ b/src/CBot/CBotInstr/CBotListInstr.h
@@ -65,9 +65,13 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotListInstr"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! Instructions to do.
-    CBotInstr*    m_Instr;
+    CBotInstr* m_instr;
 };
 
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotLogicExpr.cpp b/src/CBot/CBotInstr/CBotLogicExpr.cpp
index 22f2c23..de1035c 100644
--- a/src/CBot/CBotInstr/CBotLogicExpr.cpp
+++ b/src/CBot/CBotInstr/CBotLogicExpr.cpp
@@ -27,10 +27,9 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotLogicExpr::CBotLogicExpr()
 {
-    m_condition =
-    m_op1       =
-    m_op2       = nullptr;         // nullptr to be able to delete without other
-    name = "CBotLogicExpr";     // debug
+    m_condition = nullptr;
+    m_op1       = nullptr;
+    m_op2       = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -90,4 +89,13 @@ void CBotLogicExpr::RestoreState(CBotStack* &pStack, bool bMain)
     }
 }
 
+std::map<std::string, CBotInstr*> CBotLogicExpr::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_op1"] = m_op1;
+    links["m_condition"] = m_condition;
+    links["m_op2"] = m_op2;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotLogicExpr.h b/src/CBot/CBotInstr/CBotLogicExpr.h
index a1a0ec0..fde57da 100644
--- a/src/CBot/CBotInstr/CBotLogicExpr.h
+++ b/src/CBot/CBotInstr/CBotLogicExpr.h
@@ -55,8 +55,11 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
-private:
+protected:
+    virtual const std::string GetDebugName() { return "CBotLogicExpr"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
 
+private:
     //! Test to evaluate
     CBotInstr*    m_condition;
     //! Left element
diff --git a/src/CBot/CBotInstr/CBotNew.cpp b/src/CBot/CBotInstr/CBotNew.cpp
index ad98167..4354f24 100644
--- a/src/CBot/CBotInstr/CBotNew.cpp
+++ b/src/CBot/CBotInstr/CBotNew.cpp
@@ -17,6 +17,7 @@
  * along with this program. If not, see http://gnu.org/licenses
  */
 
+#include <sstream>
 #include "CBot/CBotInstr/CBotNew.h"
 
 #include "CBot/CBotStack.h"
@@ -33,8 +34,7 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotNew::CBotNew()
 {
-    name            = "CBotNew";
-    m_Parameters    = nullptr;
+    m_parameters = nullptr;
     m_nMethodeIdent = 0;
 }
 
@@ -74,7 +74,7 @@ CBotInstr* CBotNew::Compile(CBotToken* &p, CBotCStack* pStack)
     {
         // check if there are parameters
         CBotVar*    ppVars[1000];
-        inst->m_Parameters = CompileParams(p, pStk, ppVars);
+        inst->m_parameters = CompileParams(p, pStk, ppVars);
         if (!pStk->IsOk()) goto error;
 
         // constructor exist?
@@ -83,7 +83,7 @@ CBotInstr* CBotNew::Compile(CBotToken* &p, CBotCStack* pStack)
         int typ = r.GetType();
 
         // if there is no constructor, and no parameters either, it's ok
-        if (typ == CBotErrUndefCall && inst->m_Parameters == nullptr) typ = 0;
+        if (typ == CBotErrUndefCall && inst->m_parameters == nullptr) typ = 0;
         pVar->SetInit(CBotVar::InitType::DEF);    // mark the instance as init
 
         if (typ>20)
@@ -93,7 +93,7 @@ CBotInstr* CBotNew::Compile(CBotToken* &p, CBotCStack* pStack)
         }
 
         // if the constructor does not exist, but there are parameters
-        if (typ<0 && inst->m_Parameters != nullptr)
+        if (typ<0 && inst->m_parameters != nullptr)
         {
             pStk->SetError(CBotErrNoConstruct, &inst->m_vartoken);
             goto error;
@@ -153,7 +153,7 @@ bool CBotNew::Execute(CBotStack* &pj)
 
         int        i = 0;
 
-        CBotInstr*    p = m_Parameters;
+        CBotInstr*    p = m_parameters;
         // evaluate the parameters
         // and places the values on the stack
         // to be interrupted at any time
@@ -218,7 +218,7 @@ void CBotNew::RestoreState(CBotStack* &pj, bool bMain)
 
         int        i = 0;
 
-        CBotInstr*    p = m_Parameters;
+        CBotInstr*    p = m_parameters;
         // evaluate the parameters
         // and places the values on the stack
         // to be interrupted at any time
@@ -244,4 +244,18 @@ void CBotNew::RestoreState(CBotStack* &pj, bool bMain)
     }
 }
 
+std::string CBotNew::GetDebugData()
+{
+    std::stringstream ss;
+    ss << "ConstructorID = " << m_nMethodeIdent;
+    return ss.str();
+}
+
+std::map<std::string, CBotInstr*> CBotNew::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_parameters"] = m_parameters;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotNew.h b/src/CBot/CBotInstr/CBotNew.h
index f1eaf27..9a0e94e 100644
--- a/src/CBot/CBotInstr/CBotNew.h
+++ b/src/CBot/CBotInstr/CBotNew.h
@@ -63,9 +63,14 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotNew"; }
+    virtual std::string GetDebugData();
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! The parameters to be evaluated
-    CBotInstr* m_Parameters;
+    CBotInstr* m_parameters;
     long m_nMethodeIdent;
     CBotToken m_vartoken;
 
diff --git a/src/CBot/CBotInstr/CBotParExpr.cpp b/src/CBot/CBotInstr/CBotParExpr.cpp
index 9be8012..ec8fc45 100644
--- a/src/CBot/CBotInstr/CBotParExpr.cpp
+++ b/src/CBot/CBotInstr/CBotParExpr.cpp
@@ -104,7 +104,7 @@ CBotInstr* CBotParExpr::Compile(CBotToken* &p, CBotCStack* pStack)
 
             CBotPostIncExpr* i = new CBotPostIncExpr();
             i->SetToken(pp);
-            i->m_Instr = inst;    // associated statement
+            i->m_instr = inst;    // associated statement
             return pStack->Return(i, pStk);
         }
         return pStack->Return(inst, pStk);
@@ -119,7 +119,7 @@ CBotInstr* CBotParExpr::Compile(CBotToken* &p, CBotCStack* pStack)
 
         if (p->GetType() == TokenTypVar)
         {
-            if (nullptr != (i->m_Instr =  CBotExprVar::Compile(p, pStk, CBotVar::ProtectionLevel::ReadOnly)))
+            if (nullptr != (i->m_instr =  CBotExprVar::Compile(p, pStk, CBotVar::ProtectionLevel::ReadOnly)))
             {
                 if (pStk->GetType() >= CBotTypBoolean)
                 {
diff --git a/src/CBot/CBotInstr/CBotPostIncExpr.cpp b/src/CBot/CBotInstr/CBotPostIncExpr.cpp
index aecbd84..00ea55c 100644
--- a/src/CBot/CBotInstr/CBotPostIncExpr.cpp
+++ b/src/CBot/CBotInstr/CBotPostIncExpr.cpp
@@ -30,14 +30,13 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotPostIncExpr::CBotPostIncExpr()
 {
-    m_Instr = nullptr;
-    name    = "CBotPostIncExpr";
+    m_instr = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotPostIncExpr::~CBotPostIncExpr()
 {
-    delete    m_Instr;
+    delete m_instr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -49,7 +48,7 @@ bool CBotPostIncExpr::Execute(CBotStack* &pj)
     CBotVar*    var1 = nullptr;
 
     // retrieves the variable fields and indexes according
-    if (!(static_cast<CBotExprVar*>(m_Instr))->ExecuteVar(var1, pile2, nullptr, true)) return false;
+    if (!(static_cast<CBotExprVar*>(m_instr))->ExecuteVar(var1, pile2, nullptr, true)) return false;
 
     pile1->SetState(1);
     pile1->SetCopyVar(var1);                                // places the result (before incrementation);
@@ -81,9 +80,16 @@ void CBotPostIncExpr::RestoreState(CBotStack* &pj, bool bMain)
     CBotStack*    pile1 = pj->RestoreStack(this);
     if (pile1 == nullptr) return;
 
-    (static_cast<CBotExprVar*>(m_Instr))->RestoreStateVar(pile1, bMain);
+    (static_cast<CBotExprVar*>(m_instr))->RestoreStateVar(pile1, bMain);
 
     if (pile1 != nullptr) pile1->RestoreStack(this);
 }
 
+std::map<std::string, CBotInstr*> CBotPostIncExpr::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_instr"] = m_instr;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotPostIncExpr.h b/src/CBot/CBotInstr/CBotPostIncExpr.h
index 5ccf32b..0acc014 100644
--- a/src/CBot/CBotInstr/CBotPostIncExpr.h
+++ b/src/CBot/CBotInstr/CBotPostIncExpr.h
@@ -61,8 +61,12 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotPostIncExpr"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
-    CBotInstr*    m_Instr;
+    CBotInstr* m_instr;
     friend class CBotParExpr;
 };
 
diff --git a/src/CBot/CBotInstr/CBotPreIncExpr.cpp b/src/CBot/CBotInstr/CBotPreIncExpr.cpp
index e1bedf7..c5d76c1 100644
--- a/src/CBot/CBotInstr/CBotPreIncExpr.cpp
+++ b/src/CBot/CBotInstr/CBotPreIncExpr.cpp
@@ -30,14 +30,13 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotPreIncExpr::CBotPreIncExpr()
 {
-    m_Instr = nullptr;
-    name    = "CBotPreIncExpr";
+    m_instr = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotPreIncExpr::~CBotPreIncExpr()
 {
-    delete    m_Instr;
+    delete m_instr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -54,7 +53,7 @@ bool CBotPreIncExpr::Execute(CBotStack* &pj)
         CBotStack*    pile2 = pile;
         // retrieves the variable fields and indexes according
         // pile2 is modified on return
-        if (!(static_cast<CBotExprVar*>(m_Instr))->ExecuteVar(var1, pile2, nullptr, true)) return false;
+        if (!(static_cast<CBotExprVar*>(m_instr))->ExecuteVar(var1, pile2, nullptr, true)) return false;
 
         if (var1->IsNAN())
         {
@@ -74,7 +73,7 @@ bool CBotPreIncExpr::Execute(CBotStack* &pj)
         pile->IncState();
     }
 
-    if (!m_Instr->Execute(pile)) return false;
+    if (!m_instr->Execute(pile)) return false;
     return pj->Return(pile);    // operation performed
 }
 
@@ -91,7 +90,14 @@ void CBotPreIncExpr::RestoreState(CBotStack* &pj, bool bMain)
         return;
     }
 
-    m_Instr->RestoreState(pile, bMain);
+    m_instr->RestoreState(pile, bMain);
+}
+
+std::map<std::string, CBotInstr*> CBotPreIncExpr::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_instr"] = m_instr;
+    return links;
 }
 
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotPreIncExpr.h b/src/CBot/CBotInstr/CBotPreIncExpr.h
index 957c3c4..0aff5f6 100644
--- a/src/CBot/CBotInstr/CBotPreIncExpr.h
+++ b/src/CBot/CBotInstr/CBotPreIncExpr.h
@@ -56,8 +56,12 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotPreIncExpr"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
-    CBotInstr* m_Instr;
+    CBotInstr* m_instr;
     friend class CBotParExpr;
 };
 
diff --git a/src/CBot/CBotInstr/CBotReturn.cpp b/src/CBot/CBotInstr/CBotReturn.cpp
index 51c9ba6..8a95a1b 100644
--- a/src/CBot/CBotInstr/CBotReturn.cpp
+++ b/src/CBot/CBotInstr/CBotReturn.cpp
@@ -32,14 +32,13 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotReturn::CBotReturn()
 {
-    m_Instr = nullptr;
-    name = "CBotReturn";        // debug
+    m_instr = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotReturn::~CBotReturn()
 {
-    delete  m_Instr;
+    delete m_instr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -61,7 +60,7 @@ CBotInstr* CBotReturn::Compile(CBotToken* &p, CBotCStack* pStack)
         return nullptr;
     }
 
-    inst->m_Instr = CBotExpression::Compile(p, pStack);
+    inst->m_instr = CBotExpression::Compile(p, pStack);
     if ( pStack->IsOk() )
     {
         CBotTypResult   retType = pStack->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC);
@@ -87,7 +86,7 @@ bool CBotReturn::Execute(CBotStack* &pj)
 
     if ( pile->GetState() == 0 )
     {
-        if ( m_Instr != nullptr && !m_Instr->Execute(pile) ) return false; // evaluate the result
+        if (m_instr != nullptr && !m_instr->Execute(pile) ) return false; // evaluate the result
         // the result is on the stack
         pile->IncState();
     }
@@ -107,9 +106,16 @@ void CBotReturn::RestoreState(CBotStack* &pj, bool bMain)
 
     if ( pile->GetState() == 0 )
     {
-        if ( m_Instr != nullptr ) m_Instr->RestoreState(pile, bMain);  // evaluate the result
+        if (m_instr != nullptr ) m_instr->RestoreState(pile, bMain);  // evaluate the result
         return;
     }
 }
 
+std::map<std::string, CBotInstr*> CBotReturn::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_instr"] = m_instr;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotReturn.h b/src/CBot/CBotInstr/CBotReturn.h
index cc64c26..34304e7 100644
--- a/src/CBot/CBotInstr/CBotReturn.h
+++ b/src/CBot/CBotInstr/CBotReturn.h
@@ -63,9 +63,13 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotReturn"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! Parameter of return
-    CBotInstr *m_Instr;
+    CBotInstr* m_instr;
 
 };
 
diff --git a/src/CBot/CBotInstr/CBotSwitch.cpp b/src/CBot/CBotInstr/CBotSwitch.cpp
index 08108f3..d381a52 100644
--- a/src/CBot/CBotInstr/CBotSwitch.cpp
+++ b/src/CBot/CBotInstr/CBotSwitch.cpp
@@ -31,16 +31,15 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotSwitch::CBotSwitch()
 {
-    m_Value     =
-    m_Block     = nullptr;         // nullptr so that delete is not possible further
-    name = "CBotSwitch";        // debug
+    m_value = nullptr;
+    m_block = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotSwitch::~CBotSwitch()
 {
-    delete  m_Value;        // frees the value
-    delete  m_Block;        // frees the instruction block
+    delete m_value;        // frees the value
+    delete m_block;        // frees the instruction block
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -56,7 +55,7 @@ CBotInstr* CBotSwitch::Compile(CBotToken* &p, CBotCStack* pStack)
 
     if ( IsOfType(p, ID_OPENPAR ) )
     {
-        if ( nullptr != (inst->m_Value = CBotExpression::Compile( p, pStk )) )
+        if ( nullptr != (inst->m_value = CBotExpression::Compile(p, pStk )) )
         {
             if ( pStk->GetType() < CBotTypLong )
             {
@@ -79,12 +78,12 @@ CBotInstr* CBotSwitch::Compile(CBotToken* &p, CBotCStack* pStack)
                                     return pStack->Return(nullptr, pStk2);
                                 }
                                 delete pStk2;
-                                if ( inst->m_Block == nullptr ) inst->m_Block = i;
-                                else inst->m_Block->AddNext(i);
+                                if (inst->m_block == nullptr ) inst->m_block = i;
+                                else inst->m_block->AddNext(i);
                                 continue;
                             }
 
-                            if ( inst->m_Block == nullptr )
+                            if (inst->m_block == nullptr )
                             {
                                 pStk->SetError(CBotErrNoCase, p->GetStart());
                                 delete inst;
@@ -97,7 +96,7 @@ CBotInstr* CBotSwitch::Compile(CBotToken* &p, CBotCStack* pStack)
                                 delete inst;
                                 return pStack->Return(nullptr, pStk);
                             }
-                            inst->m_Block->AddNext(i);
+                            inst->m_block->AddNext(i);
 
                             if ( p == nullptr )
                             {
@@ -108,7 +107,7 @@ CBotInstr* CBotSwitch::Compile(CBotToken* &p, CBotCStack* pStack)
                         }
                         DecLvl();
 
-                        if ( inst->m_Block == nullptr )
+                        if (inst->m_block == nullptr )
                         {
                             pStk->SetError(CBotErrNoCase, p->GetStart());
                             delete inst;
@@ -136,12 +135,12 @@ bool CBotSwitch :: Execute(CBotStack* &pj)
     CBotStack* pile1 = pj->AddStack(this);      // adds an item to the stack
 //  if ( pile1 == EOX ) return true;
 
-    CBotInstr*  p = m_Block;                    // first expression
+    CBotInstr*  p = m_block;                    // first expression
 
     int     state = pile1->GetState();
     if (state == 0)
     {
-        if ( !m_Value->Execute(pile1) ) return false;
+        if ( !m_value->Execute(pile1) ) return false;
         pile1->SetState(state = -1);
     }
 
@@ -166,7 +165,7 @@ bool CBotSwitch :: Execute(CBotStack* &pj)
         if ( !pile1->SetState(state) ) return false;
     }
 
-    p = m_Block;                                        // returns to the beginning
+    p = m_block;                                        // returns to the beginning
     while (state-->0) p = p->GetNext();                 // advance in the list
 
     while( p != nullptr )
@@ -186,12 +185,12 @@ void CBotSwitch :: RestoreState(CBotStack* &pj, bool bMain)
     CBotStack* pile1 = pj->RestoreStack(this);  // adds an item to the stack
     if ( pile1 == nullptr ) return;
 
-    CBotInstr*  p = m_Block;                    // first expression
+    CBotInstr*  p = m_block;                    // first expression
 
     int     state = pile1->GetState();
     if (state == 0)
     {
-        m_Value->RestoreState(pile1, bMain);
+        m_value->RestoreState(pile1, bMain);
         return;
     }
 
@@ -200,7 +199,7 @@ void CBotSwitch :: RestoreState(CBotStack* &pj, bool bMain)
         return;
     }
 
-//  p = m_Block;                                // returns to the beginning
+//  p = m_block;                                // returns to the beginning
     while ( p != nullptr && state-- > 0 )
     {
         p->RestoreState(pile1, false);
@@ -214,4 +213,12 @@ void CBotSwitch :: RestoreState(CBotStack* &pj, bool bMain)
     }
 }
 
+std::map<std::string, CBotInstr*> CBotSwitch::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_value"] = m_value;
+    links["m_block"] = m_block;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotSwitch.h b/src/CBot/CBotInstr/CBotSwitch.h
index f22aa50..13aa375 100644
--- a/src/CBot/CBotInstr/CBotSwitch.h
+++ b/src/CBot/CBotInstr/CBotSwitch.h
@@ -63,13 +63,15 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
-private:
+protected:
+    virtual const std::string GetDebugName() { return "CBotSwitch"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
 
+private:
     //! Value to seek
-    CBotInstr* m_Value;
+    CBotInstr* m_value;
     //! Instructions
-    CBotInstr* m_Block;
-
+    CBotInstr* m_block;
 };
 
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotThrow.cpp b/src/CBot/CBotInstr/CBotThrow.cpp
index d3a9632..da0c5e6 100644
--- a/src/CBot/CBotInstr/CBotThrow.cpp
+++ b/src/CBot/CBotInstr/CBotThrow.cpp
@@ -29,15 +29,13 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotThrow::CBotThrow()
 {
-    m_Value     = nullptr;     // nullptr so that delete is not possible further
-
-    name = "CBotThrow";     // debug
+    m_value = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotThrow::~CBotThrow()
 {
-    delete  m_Value;
+    delete m_value;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -52,7 +50,7 @@ CBotInstr* CBotThrow::Compile(CBotToken* &p, CBotCStack* pStack)
 
     if (!IsOfType(p, ID_THROW)) return nullptr;    // should never happen
 
-    inst->m_Value = CBotExpression::Compile( p, pStack );
+    inst->m_value = CBotExpression::Compile(p, pStack );
 
     if (pStack->GetType() < CBotTypLong && pStack->IsOk())
     {
@@ -72,7 +70,7 @@ bool CBotThrow::Execute(CBotStack* &pj)
 
     if ( pile->GetState() == 0 )
     {
-        if ( !m_Value->Execute(pile) ) return false;
+        if ( !m_value->Execute(pile) ) return false;
         pile->IncState();
     }
 
@@ -94,9 +92,16 @@ void CBotThrow::RestoreState(CBotStack* &pj, bool bMain)
 
     if ( pile->GetState() == 0 )
     {
-        m_Value->RestoreState(pile, bMain);
+        m_value->RestoreState(pile, bMain);
         return;
     }
 }
 
+std::map<std::string, CBotInstr*> CBotThrow::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_value"] = m_value;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotThrow.h b/src/CBot/CBotInstr/CBotThrow.h
index 257ffcf..dd6dd2b 100644
--- a/src/CBot/CBotInstr/CBotThrow.h
+++ b/src/CBot/CBotInstr/CBotThrow.h
@@ -63,9 +63,13 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotThrow"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! The value to send.
-    CBotInstr* m_Value;
+    CBotInstr* m_value;
 
 };
 
diff --git a/src/CBot/CBotInstr/CBotTry.cpp b/src/CBot/CBotInstr/CBotTry.cpp
index a950e1a..a98056d 100644
--- a/src/CBot/CBotInstr/CBotTry.cpp
+++ b/src/CBot/CBotInstr/CBotTry.cpp
@@ -30,18 +30,17 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotTry::CBotTry()
 {
-    m_ListCatch = nullptr;
-    m_FinalInst =
-    m_Block     = nullptr;     // nullptr so that delete is not possible further
-    name = "CBotTry";       // debug
+    m_catchList = nullptr;
+    m_finallyBlock = nullptr;
+    m_block = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotTry::~CBotTry()
 {
-    delete  m_ListCatch;    // frees the list
-    delete  m_Block;        // frees the instruction block
-    delete  m_FinalInst;
+    delete m_catchList;    // frees the list
+    delete m_block;        // frees the instruction block
+    delete m_finallyBlock;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -55,8 +54,8 @@ CBotInstr* CBotTry::Compile(CBotToken* &p, CBotCStack* pStack)
 
     CBotCStack* pStk = pStack->TokenStack(pp);  // un petit bout de pile svp
 
-    inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk );
-    CBotCatch** pn = &inst->m_ListCatch;
+    inst->m_block = CBotBlock::CompileBlkOrInst(p, pStk );
+    CBotCatch** pn = &inst->m_catchList;
 
     while (pStk->IsOk() && p->GetType() == ID_CATCH)
     {
@@ -67,7 +66,7 @@ CBotInstr* CBotTry::Compile(CBotToken* &p, CBotCStack* pStack)
 
     if (pStk->IsOk() && IsOfType( p, ID_FINALLY) )
     {
-        inst->m_FinalInst = CBotBlock::CompileBlkOrInst( p, pStk );
+        inst->m_finallyBlock = CBotBlock::CompileBlkOrInst(p, pStk );
     }
 
     if (pStk->IsOk())
@@ -95,9 +94,9 @@ bool CBotTry::Execute(CBotStack* &pj)
 
     if ( pile1->GetState() == 0 )
     {
-        if ( m_Block->Execute(pile1) )
+        if ( m_block->Execute(pile1) )
         {
-            if ( m_FinalInst == nullptr ) return pj->Return(pile1);
+            if (m_finallyBlock == nullptr ) return pj->Return(pile1);
             pile1->SetState(-2);                                // passes final
         }
 
@@ -116,7 +115,7 @@ bool CBotTry::Execute(CBotStack* &pj)
     // there was an interruption
     // see what it returns
 
-    CBotCatch*  pc = m_ListCatch;
+    CBotCatch*  pc = m_catchList;
     int state = static_cast<short>(pile1->GetState());                       // where were we?
     val = pile2->GetState();                                    // what error?
     pile0->SetState(1);                                         // marking the GetRunPos
@@ -137,7 +136,7 @@ bool CBotTry::Execute(CBotStack* &pj)
 //              pile0->SetState(1);
 
                 if ( !pc->Execute(pile2) ) return false;        // performs the operation
-                if ( m_FinalInst == nullptr )
+                if (m_finallyBlock == nullptr )
                     return pj->Return(pile2);                   // ends the try
 
                 pile1->SetState(-2);                            // passes final
@@ -147,14 +146,14 @@ bool CBotTry::Execute(CBotStack* &pj)
         }
         pc = pc->m_next;
     }
-    if ( m_FinalInst != nullptr &&
+    if (m_finallyBlock != nullptr &&
          pile1->GetState() > 0 && val != 0 ) pile1->SetState(-1);// if stop then made the final
 
     if (pile1->GetState() <= -1)
     {
 //      pile0->SetState(1);
 
-        if (!m_FinalInst->Execute(pile2) && pile2->IsOk()) return false;
+        if (!m_finallyBlock->Execute(pile2) && pile2->IsOk()) return false;
         if (!pile2->IsOk()) return pj->Return(pile2);           // keep this exception
         pile2->SetError(pile1->GetState()==-1 ? static_cast<CBotError>(val) : CBotNoErr);       // gives the initial error
         return pj->Return(pile2);
@@ -162,7 +161,7 @@ bool CBotTry::Execute(CBotStack* &pj)
 
     pile1->SetState(0);                                         // returns to the evaluation
     pile0->SetState(0);                                         // returns to the evaluation
-    if ( val != 0 && m_ListCatch == nullptr && m_FinalInst == nullptr )
+    if ( val != 0 && m_catchList == nullptr && m_finallyBlock == nullptr )
                             return pj->Return(pile2);           // ends the try without exception
 
     pile1->SetError(static_cast<CBotError>(val));                                       // gives the error
@@ -184,7 +183,7 @@ void CBotTry::RestoreState(CBotStack* &pj, bool bMain)
     CBotStack* pile2 = pile0->RestoreStack();
     if ( pile2 == nullptr ) return;
 
-    m_Block->RestoreState(pile1, bMain);
+    m_block->RestoreState(pile1, bMain);
     if ( pile0->GetState() == 0 )
     {
         return;
@@ -193,7 +192,7 @@ void CBotTry::RestoreState(CBotStack* &pj, bool bMain)
     // there was an interruption
     // see what it returns
 
-    CBotCatch*  pc = m_ListCatch;
+    CBotCatch*  pc = m_catchList;
     int state = pile1->GetState();                              // where were we ?
     val = pile2->GetState();                                    // what error ?
 
@@ -219,9 +218,18 @@ void CBotTry::RestoreState(CBotStack* &pj, bool bMain)
 
     if (pile1->GetState() <= -1)
     {
-        m_FinalInst->RestoreState(pile2, bMain);
+        m_finallyBlock->RestoreState(pile2, bMain);
         return;
     }
 }
 
+std::map<std::string, CBotInstr*> CBotTry::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_block"] = m_block;
+    links["m_catchList"] = m_catchList;
+    links["m_finallyBlock"] = m_finallyBlock;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotTry.h b/src/CBot/CBotInstr/CBotTry.h
index 39deebd..2bb5c03 100644
--- a/src/CBot/CBotInstr/CBotTry.h
+++ b/src/CBot/CBotInstr/CBotTry.h
@@ -64,14 +64,17 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotTry"; }
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! Instructions
-    CBotInstr* m_Block;
+    CBotInstr* m_block;
     //! Catches
-    CBotCatch* m_ListCatch;
+    CBotCatch* m_catchList;
     //! Final instruction
-    CBotInstr* m_FinalInst;
-
+    CBotInstr* m_finallyBlock;
 };
 
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotTwoOpExpr.cpp b/src/CBot/CBotInstr/CBotTwoOpExpr.cpp
index 0d16744..e428c96 100644
--- a/src/CBot/CBotInstr/CBotTwoOpExpr.cpp
+++ b/src/CBot/CBotInstr/CBotTwoOpExpr.cpp
@@ -38,9 +38,8 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotTwoOpExpr::CBotTwoOpExpr()
 {
-    m_leftop    =
-    m_rightop   = nullptr;         // nullptr to be able to delete without other
-    name = "CBotTwoOpExpr";     // debug
+    m_leftop    = nullptr;
+    m_rightop   = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -505,4 +504,17 @@ void CBotTwoOpExpr::RestoreState(CBotStack* &pStack, bool bMain)
     }
 }
 
+std::string CBotTwoOpExpr::GetDebugData()
+{
+    return m_token.GetString();
+}
+
+std::map<std::string, CBotInstr*> CBotTwoOpExpr::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_leftop"] = m_leftop;
+    links["m_rightop"] = m_rightop;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotTwoOpExpr.h b/src/CBot/CBotInstr/CBotTwoOpExpr.h
index f711a35..26b4791 100644
--- a/src/CBot/CBotInstr/CBotTwoOpExpr.h
+++ b/src/CBot/CBotInstr/CBotTwoOpExpr.h
@@ -67,6 +67,11 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotTwoOpExpr"; }
+    virtual std::string GetDebugData();
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
+
 private:
     //! Left element
     CBotInstr* m_leftop;
diff --git a/src/CBot/CBotInstr/CBotWhile.cpp b/src/CBot/CBotInstr/CBotWhile.cpp
index a28f3fe..8e186be 100644
--- a/src/CBot/CBotInstr/CBotWhile.cpp
+++ b/src/CBot/CBotInstr/CBotWhile.cpp
@@ -30,16 +30,15 @@ namespace CBot
 ////////////////////////////////////////////////////////////////////////////////
 CBotWhile::CBotWhile()
 {
-    m_Condition =
-    m_Block     = nullptr;     // nullptr so that delete is not possible further
-    name = "CBotWhile";     // debug
+    m_condition = nullptr;
+    m_block = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 CBotWhile::~CBotWhile()
 {
-    delete  m_Condition;    // frees the condition
-    delete  m_Block;        // releases the block instruction
+    delete m_condition;    // frees the condition
+    delete m_block;        // releases the block instruction
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -60,12 +59,12 @@ CBotInstr* CBotWhile::Compile(CBotToken* &p, CBotCStack* pStack)
     CBotCStack* pStk = pStack->TokenStack(pp);  // un petit bout de pile svp
                                                 // a bit of battery please (??)
 
-    if ( nullptr != (inst->m_Condition = CBotCondition::Compile( p, pStk )) )
+    if ( nullptr != (inst->m_condition = CBotCondition::Compile(p, pStk )) )
     {
         // the condition exists
 
         IncLvl(inst->m_label);
-        inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true );
+        inst->m_block = CBotBlock::CompileBlkOrInst(p, pStk, true );
         DecLvl();
 
         if ( pStk->IsOk() )
@@ -94,7 +93,7 @@ bool CBotWhile::Execute(CBotStack* &pj)
     {                                           // there are two possible states (depending on recovery)
     case 0:
         // evaluates the condition
-        if ( !m_Condition->Execute(pile) ) return false; // interrupted here?
+        if ( !m_condition->Execute(pile) ) return false; // interrupted here?
 
         // the result of the condition is on the stack
 
@@ -110,8 +109,8 @@ bool CBotWhile::Execute(CBotStack* &pj)
 
     case 1:
         // evaluates the associated statement block
-        if ( m_Block != nullptr &&
-            !m_Block->Execute(pile) )
+        if (m_block != nullptr &&
+            !m_block->Execute(pile) )
         {
             if (pile->IfContinue(0, m_label)) continue; // if continued, will return to test
             return pj->BreakReturn(pile, m_label);      // sends the results and releases the stack
@@ -140,14 +139,27 @@ void CBotWhile::RestoreState(CBotStack* &pj, bool bMain)
     {                                           // there are two possible states (depending on recovery)
     case 0:
         // evaluates the condition
-        m_Condition->RestoreState(pile, bMain);
+        m_condition->RestoreState(pile, bMain);
         return;
 
     case 1:
         // evaluates the associated statement block
-        if ( m_Block != nullptr ) m_Block->RestoreState(pile, bMain);
+        if (m_block != nullptr ) m_block->RestoreState(pile, bMain);
         return;
     }
 }
 
+std::string CBotWhile::GetDebugData()
+{
+    return !m_label.empty() ? "m_label = "+m_label : "";
+}
+
+std::map<std::string, CBotInstr*> CBotWhile::GetDebugLinks()
+{
+    auto links = CBotInstr::GetDebugLinks();
+    links["m_condition"] = m_condition;
+    links["m_block"] = m_block;
+    return links;
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotInstr/CBotWhile.h b/src/CBot/CBotInstr/CBotWhile.h
index af3ab00..f1e1355 100644
--- a/src/CBot/CBotInstr/CBotWhile.h
+++ b/src/CBot/CBotInstr/CBotWhile.h
@@ -64,16 +64,18 @@ public:
      */
     void RestoreState(CBotStack* &pj, bool bMain) override;
 
+protected:
+    virtual const std::string GetDebugName() { return "CBotWhile"; }
+    virtual std::string GetDebugData();
+    virtual std::map<std::string, CBotInstr*> GetDebugLinks();
 
 private:
-
     //! Condition
-    CBotInstr* m_Condition;
+    CBotInstr* m_condition;
     //! Instructions
-    CBotInstr* m_Block;
+    CBotInstr* m_block;
     //! A label if there is
     std::string m_label;
-
 };
 
 } // namespace CBot
diff --git a/src/CBot/CBotProgram.h b/src/CBot/CBotProgram.h
index cb16301..491ca5f 100644
--- a/src/CBot/CBotProgram.h
+++ b/src/CBot/CBotProgram.h
@@ -358,6 +358,7 @@ private:
     //! "this" variable
     CBotVar* m_thisVar = nullptr;
     friend class CBotFunction;
+    friend class CBotDebug;
 
     CBotError m_error = CBotNoErr;
     int m_errorStart = 0;
diff --git a/src/CBot/CBotTypResult.cpp b/src/CBot/CBotTypResult.cpp
index e20db63..d4cd4e8 100644
--- a/src/CBot/CBotTypResult.cpp
+++ b/src/CBot/CBotTypResult.cpp
@@ -173,4 +173,23 @@ CBotTypResult& CBotTypResult::operator=(const CBotTypResult& src)
     return *this;
 }
 
+std::string CBotTypResult::ToString()
+{
+    switch (m_type)
+    {
+        case CBotTypVoid: return "void";
+        case CBotTypInt: return "int";
+        case CBotTypFloat: return "float";
+        case CBotTypBoolean: return "bool";
+        case CBotTypString: return "string";
+        case CBotTypArrayPointer: return m_pNext->ToString()+"[]";
+        case CBotTypArrayBody: return m_pNext->ToString()+"[] (by value)";
+        case CBotTypPointer: return m_pClass->GetName();
+        case CBotTypNullPointer: return m_pClass->GetName()+" (null)";
+        case CBotTypClass: return m_pClass->GetName()+" (by value)";
+        case CBotTypIntrinsic: return m_pClass->GetName()+" (intr)";
+    }
+    return "?";
+}
+
 } // namespace CBot
diff --git a/src/CBot/CBotTypResult.h b/src/CBot/CBotTypResult.h
index 6a211f0..6e1d30f 100644
--- a/src/CBot/CBotTypResult.h
+++ b/src/CBot/CBotTypResult.h
@@ -152,6 +152,8 @@ public:
      */
     CBotTypResult& operator=(const CBotTypResult& src);
 
+    std::string ToString();
+
 private:
     int               m_type;   //!< type, see ::CBotType and ::CBotError
     CBotTypResult*    m_pNext;  //!< type of array element
diff --git a/src/CBot/CMakeLists.txt b/src/CBot/CMakeLists.txt
index 62a944f..a647572 100644
--- a/src/CBot/CMakeLists.txt
+++ b/src/CBot/CMakeLists.txt
@@ -1,74 +1,75 @@
 set(SOURCES
-        CBotUtils.cpp
-        CBotFileUtils.cpp
-        CBotClass.cpp
-        CBotProgram.cpp
-        CBotStack.cpp
-        CBotCStack.cpp
-        CBotToken.cpp
-        CBotExternalCall.cpp
-        CBotDefParam.cpp
-        CBotCallMethode.cpp
-        CBotTypResult.cpp
-        CBotInstr/CBotInstr.cpp
-        CBotInstr/CBotInstrUtils.cpp
-        CBotInstr/CBotWhile.cpp
-        CBotInstr/CBotDo.cpp
-        CBotInstr/CBotFor.cpp
-        CBotInstr/CBotListExpression.cpp
-        CBotInstr/CBotSwitch.cpp
-        CBotInstr/CBotCase.cpp
-        CBotInstr/CBotBreak.cpp
-        CBotInstr/CBotTry.cpp
-        CBotInstr/CBotCatch.cpp
-        CBotInstr/CBotThrow.cpp
-        CBotInstr/CBotExprAlpha.cpp
-        CBotInstr/CBotExprNum.cpp
-        CBotInstr/CBotNew.cpp
-        CBotInstr/CBotExprNan.cpp
-        CBotInstr/CBotExprNull.cpp
-        CBotInstr/CBotExprBool.cpp
-        CBotInstr/CBotLeftExprVar.cpp
-        CBotInstr/CBotPreIncExpr.cpp
-        CBotInstr/CBotPostIncExpr.cpp
-        CBotInstr/CBotExprVar.cpp
-        CBotInstr/CBotInstrMethode.cpp
-        CBotInstr/CBotInstrCall.cpp
-        CBotInstr/CBotListInstr.cpp
-        CBotInstr/CBotBlock.cpp
-        CBotInstr/CBotExprUnaire.cpp
-        CBotInstr/CBotParExpr.cpp
-        CBotInstr/CBotBoolExpr.cpp
-        CBotInstr/CBotLogicExpr.cpp
-        CBotInstr/CBotTwoOpExpr.cpp
-        CBotInstr/CBotExpression.cpp
-        CBotInstr/CBotIndexExpr.cpp
-        CBotInstr/CBotFieldExpr.cpp
-        CBotInstr/CBotLeftExpr.cpp
-        CBotInstr/CBotCondition.cpp
-        CBotInstr/CBotClassInst.cpp
-        CBotInstr/CBotIString.cpp
-        CBotInstr/CBotFloat.cpp
-        CBotInstr/CBotBoolean.cpp
-        CBotInstr/CBotEmpty.cpp
-        CBotInstr/CBotReturn.cpp
-        CBotInstr/CBotIf.cpp
-        CBotInstr/CBotListArray.cpp
-        CBotInstr/CBotInstArray.cpp
-        CBotInstr/CBotInt.cpp
-        CBotInstr/CBotFunction.cpp
-        CBotVar/CBotVarArray.cpp
-        CBotVar/CBotVarPointer.cpp
-        CBotVar/CBotVarClass.cpp
-        CBotVar/CBotVarBoolean.cpp
-        CBotVar/CBotVarString.cpp
-        CBotVar/CBotVarFloat.cpp
-        CBotVar/CBotVarInt.cpp
-        CBotVar/CBotVar.cpp
-        stdlib/FileFunctions.cpp
-        stdlib/StringFunctions.cpp
-        stdlib/MathFunctions.cpp
-        stdlib/Compilation.cpp
+    CBotUtils.cpp
+    CBotFileUtils.cpp
+    CBotClass.cpp
+    CBotDebug.cpp
+    CBotProgram.cpp
+    CBotStack.cpp
+    CBotCStack.cpp
+    CBotToken.cpp
+    CBotExternalCall.cpp
+    CBotDefParam.cpp
+    CBotCallMethode.cpp
+    CBotTypResult.cpp
+    CBotInstr/CBotInstr.cpp
+    CBotInstr/CBotInstrUtils.cpp
+    CBotInstr/CBotWhile.cpp
+    CBotInstr/CBotDo.cpp
+    CBotInstr/CBotFor.cpp
+    CBotInstr/CBotListExpression.cpp
+    CBotInstr/CBotSwitch.cpp
+    CBotInstr/CBotCase.cpp
+    CBotInstr/CBotBreak.cpp
+    CBotInstr/CBotTry.cpp
+    CBotInstr/CBotCatch.cpp
+    CBotInstr/CBotThrow.cpp
+    CBotInstr/CBotExprAlpha.cpp
+    CBotInstr/CBotExprNum.cpp
+    CBotInstr/CBotNew.cpp
+    CBotInstr/CBotExprNan.cpp
+    CBotInstr/CBotExprNull.cpp
+    CBotInstr/CBotExprBool.cpp
+    CBotInstr/CBotLeftExprVar.cpp
+    CBotInstr/CBotPreIncExpr.cpp
+    CBotInstr/CBotPostIncExpr.cpp
+    CBotInstr/CBotExprVar.cpp
+    CBotInstr/CBotInstrMethode.cpp
+    CBotInstr/CBotInstrCall.cpp
+    CBotInstr/CBotListInstr.cpp
+    CBotInstr/CBotBlock.cpp
+    CBotInstr/CBotExprUnaire.cpp
+    CBotInstr/CBotParExpr.cpp
+    CBotInstr/CBotBoolExpr.cpp
+    CBotInstr/CBotLogicExpr.cpp
+    CBotInstr/CBotTwoOpExpr.cpp
+    CBotInstr/CBotExpression.cpp
+    CBotInstr/CBotIndexExpr.cpp
+    CBotInstr/CBotFieldExpr.cpp
+    CBotInstr/CBotLeftExpr.cpp
+    CBotInstr/CBotCondition.cpp
+    CBotInstr/CBotClassInst.cpp
+    CBotInstr/CBotIString.cpp
+    CBotInstr/CBotFloat.cpp
+    CBotInstr/CBotBoolean.cpp
+    CBotInstr/CBotEmpty.cpp
+    CBotInstr/CBotReturn.cpp
+    CBotInstr/CBotIf.cpp
+    CBotInstr/CBotListArray.cpp
+    CBotInstr/CBotInstArray.cpp
+    CBotInstr/CBotInt.cpp
+    CBotInstr/CBotFunction.cpp
+    CBotVar/CBotVarArray.cpp
+    CBotVar/CBotVarPointer.cpp
+    CBotVar/CBotVarClass.cpp
+    CBotVar/CBotVarBoolean.cpp
+    CBotVar/CBotVarString.cpp
+    CBotVar/CBotVarFloat.cpp
+    CBotVar/CBotVarInt.cpp
+    CBotVar/CBotVar.cpp
+    stdlib/FileFunctions.cpp
+    stdlib/StringFunctions.cpp
+    stdlib/MathFunctions.cpp
+    stdlib/Compilation.cpp
 )
 
 # Includes
diff --git a/test/cbot/CMakeLists.txt b/test/cbot/CMakeLists.txt
index d5de1f4..ce1f8e2 100644
--- a/test/cbot/CMakeLists.txt
+++ b/test/cbot/CMakeLists.txt
@@ -1 +1,19 @@
-add_subdirectory(console)
\ No newline at end of file
+# Includes
+include_directories(
+    ${COLOBOT_LOCAL_INCLUDES}
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+# Libraries
+set(LIBS
+    CBot
+    colobotbase # Needed for error strings (TODO: why are they on Colobot side? :/)
+    ${COLOBOT_LIBS} # Needed for colobotbase
+)
+
+add_executable(CBot_console console.cpp)
+target_link_libraries(CBot_console ${LIBS})
+
+add_executable(CBot_compile_graph compile_graph.cpp)
+target_link_libraries(CBot_compile_graph CBot)
\ No newline at end of file
diff --git a/test/cbot/compile_graph.cpp b/test/cbot/compile_graph.cpp
new file mode 100644
index 0000000..c3d32cd
--- /dev/null
+++ b/test/cbot/compile_graph.cpp
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the Colobot: Gold Edition source code
+ * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
+ * http://epsitec.ch; http://colobot.info; http://github.com/colobot
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://gnu.org/licenses
+ */
+
+#include <iostream>
+#include <memory>
+
+#include "CBot/CBot.h"
+#include "CBot/CBotDebug.h"
+
+/**
+ * \file test/cbot/compile_graph.cpp
+ * \brief A tool for generating graphs of compiled CBot instructions
+ *
+ * To generate the graph, pass the output to GraphViz:
+ * \code{.sh}
+ * ./CBot_compile_graph < input_file.txt | dot -Tx11
+ * \endcode
+ *
+ * or for output to file:
+ *
+ * \code{.sh}
+ * ./CBot_compile_graph < input_file.txt | dot -Tpng -o output.png
+ * \endcode
+ */
+
+using namespace CBot;
+
+int main(int argc, char* argv[])
+{
+    // Read program code from stdin
+    std::string code = "";
+    std::string line;
+    while (std::getline(std::cin, line))
+    {
+        code += line;
+        code += "\n";
+    }
+
+    // Initialize the CBot engine
+    CBotProgram::Init();
+
+    // Compile the program
+    std::vector<std::string> externFunctions;
+    std::unique_ptr<CBotProgram> program{new CBotProgram(nullptr)};
+    if (!program->Compile(code.c_str(), externFunctions, nullptr))
+    {
+        CBotError error;
+        int cursor1, cursor2;
+        program->GetError(error, cursor1, cursor2);
+        std::cerr << "COMPILE ERROR: " << error << " @ " << cursor1 << " - " << cursor2 << std::endl;
+        return 1;
+    }
+
+    // Generate graphs for all compiled functions marked as "extern"
+    if (externFunctions.empty())
+    {
+        std::cerr << "NO EXTERN FUNCTIONS FOUND";
+        return 2;
+    }
+    for (const std::string& func : externFunctions)
+    {
+        program->Start(func);
+        std::cerr << "# Graph for " << func << std::endl;
+        CBotDebug::DumpCompiledProgram(program.get());
+        program->Stop();
+    }
+
+    // Free the engine
+    CBotProgram::Free();
+
+    return 0;
+}
diff --git a/test/cbot/console/main.cpp b/test/cbot/console.cpp
similarity index 76%
rename from test/cbot/console/main.cpp
rename to test/cbot/console.cpp
index 6e6e877..9c03fe1 100644
--- a/test/cbot/console/main.cpp
+++ b/test/cbot/console.cpp
@@ -1,3 +1,22 @@
+/*
+ * This file is part of the Colobot: Gold Edition source code
+ * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
+ * http://epsitec.ch; http://colobot.info; http://github.com/colobot
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://gnu.org/licenses
+ */
+
 #include <iostream>
 #include <memory>
 
diff --git a/test/cbot/console/CMakeLists.txt b/test/cbot/console/CMakeLists.txt
deleted file mode 100644
index e33a108..0000000
--- a/test/cbot/console/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-# Sources
-set(CBOT_CONSOLE_SOURCES
-    main.cpp
-)
-
-# Includes
-include_directories(
-        ${COLOBOT_LOCAL_INCLUDES}
-        ${CMAKE_CURRENT_SOURCE_DIR}
-        ${CMAKE_CURRENT_BINARY_DIR}
-)
-
-# Libraries
-set(LIBS
-    CBot
-    colobotbase # Needed for error strings (TODO: why are they on Colobot side? :/)
-    ${COLOBOT_LIBS} # Needed for colobotbase
-)
-# Targets
-
-add_executable(CBot_console ${CBOT_CONSOLE_SOURCES})
-target_link_libraries(CBot_console ${LIBS})
\ No newline at end of file

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