From 940318816b325205dbc7493a79ba211fb117f67b Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Mon, 22 Jun 2020 16:07:26 +0200
Subject: [PATCH] Clear symbol tables when leaving blocks

This allows to free memory that is no more needed
---
 src/language/PugsParser.cpp                    |  4 +++-
 .../node_processor/ASTNodeListProcessor.hpp    |  3 +++
 .../node_processor/DoWhileProcessor.hpp        |  2 ++
 src/language/node_processor/ForProcessor.hpp   |  2 ++
 src/language/node_processor/IfProcessor.hpp    |  7 +++++++
 src/language/node_processor/WhileProcessor.hpp |  1 +
 src/language/utils/SymbolTable.hpp             |  8 ++++++++
 src/mesh/SynchronizerManager.cpp               | 18 ++++++++++--------
 src/mesh/SynchronizerManager.hpp               |  6 +++---
 9 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp
index b13c77149..235eab368 100644
--- a/src/language/PugsParser.cpp
+++ b/src/language/PugsParser.cpp
@@ -81,6 +81,8 @@ parser(const std::string& filename)
     ExecutionPolicy exec_all;
     root_node->execute(exec_all);
     std::cout << *(root_node->m_symbol_table) << '\n';
+
+    root_node->m_symbol_table->clearValues();
   };
 
   if (not SignalManager::pauseOnError()) {
@@ -103,5 +105,5 @@ parser(const std::string& filename)
     read_input input(filename);
     parse_and_execute(input);
   }
-  std::cout << "Parsed: " << filename << '\n';
+  std::cout << "Executed successfuly: " << filename << '\n';
 }
diff --git a/src/language/node_processor/ASTNodeListProcessor.hpp b/src/language/node_processor/ASTNodeListProcessor.hpp
index be0e786ac..df29d82de 100644
--- a/src/language/node_processor/ASTNodeListProcessor.hpp
+++ b/src/language/node_processor/ASTNodeListProcessor.hpp
@@ -17,6 +17,9 @@ class ASTNodeListProcessor final : public INodeProcessor
       child->execute(exec_policy);
     }
 
+    if (not(m_node.is_root() or m_node.is_type<language::for_statement_block>()))
+      m_node.m_symbol_table->clearValues();
+
     return {};
   }
 
diff --git a/src/language/node_processor/DoWhileProcessor.hpp b/src/language/node_processor/DoWhileProcessor.hpp
index a8240cf34..5b03b769f 100644
--- a/src/language/node_processor/DoWhileProcessor.hpp
+++ b/src/language/node_processor/DoWhileProcessor.hpp
@@ -37,6 +37,8 @@ class DoWhileProcessor final : public INodeProcessor
         },
         m_node.children[1]->execute(exec_policy)));
     } while (continuation_test);
+
+    m_node.children[0]->m_symbol_table->clearValues();
     return {};
   }
 
diff --git a/src/language/node_processor/ForProcessor.hpp b/src/language/node_processor/ForProcessor.hpp
index 83c2f8cee..8680aaf7d 100644
--- a/src/language/node_processor/ForProcessor.hpp
+++ b/src/language/node_processor/ForProcessor.hpp
@@ -38,6 +38,8 @@ class ForProcessor final : public INodeProcessor
 
       m_node.children[2]->execute(exec_policy);
     }
+
+    m_node.m_symbol_table->clearValues();
     return {};
   }
 
diff --git a/src/language/node_processor/IfProcessor.hpp b/src/language/node_processor/IfProcessor.hpp
index c1af1b99c..1a76e3068 100644
--- a/src/language/node_processor/IfProcessor.hpp
+++ b/src/language/node_processor/IfProcessor.hpp
@@ -26,14 +26,21 @@ class IfProcessor final : public INodeProcessor
     if (is_true) {
       Assert(m_node.children[1] != nullptr);
       m_node.children[1]->execute(exec_policy);
+      if (m_node.children[1]->m_symbol_table != m_node.m_symbol_table)
+        m_node.children[1]->m_symbol_table->clearValues();
+
     } else {
       if (m_node.children.size() == 3) {
         // else statement
         Assert(m_node.children[2] != nullptr);
         m_node.children[2]->execute(exec_policy);
+        if (m_node.children[2]->m_symbol_table != m_node.m_symbol_table)
+          m_node.children[2]->m_symbol_table->clearValues();
       }
     }
 
+    if (m_node.children[0]->m_symbol_table != m_node.m_symbol_table)
+      m_node.children[0]->m_symbol_table->clearValues();
     return {};
   }
 
diff --git a/src/language/node_processor/WhileProcessor.hpp b/src/language/node_processor/WhileProcessor.hpp
index b0f27a8a5..20b0ac985 100644
--- a/src/language/node_processor/WhileProcessor.hpp
+++ b/src/language/node_processor/WhileProcessor.hpp
@@ -36,6 +36,7 @@ class WhileProcessor final : public INodeProcessor
       }
     }
 
+    m_node.children[1]->m_symbol_table->clearValues();
     return {};
   }
 
diff --git a/src/language/utils/SymbolTable.hpp b/src/language/utils/SymbolTable.hpp
index 246749dab..3eba77ec9 100644
--- a/src/language/utils/SymbolTable.hpp
+++ b/src/language/utils/SymbolTable.hpp
@@ -263,6 +263,14 @@ class SymbolTable
     return os;
   }
 
+  void
+  clearValues()
+  {
+    for (auto& symbol : m_symbol_list) {
+      symbol.attributes().value() = DataVariant{};
+    }
+  }
+
   auto
   find(const std::string& symbol, const TAO_PEGTL_NAMESPACE::position& use_position)
   {
diff --git a/src/mesh/SynchronizerManager.cpp b/src/mesh/SynchronizerManager.cpp
index 8e2346c79..b1301bd88 100644
--- a/src/mesh/SynchronizerManager.cpp
+++ b/src/mesh/SynchronizerManager.cpp
@@ -5,14 +5,6 @@
 
 SynchronizerManager* SynchronizerManager::m_instance{nullptr};
 
-SynchronizerManager::~SynchronizerManager()
-{
-  if (m_connectivity_synchronizer_map.size() > 0) {
-    std::cerr << __FILE__ << ':' << __LINE__ << ": warning: some connectivities are still registered\n";
-    ;
-  }
-}
-
 void
 SynchronizerManager::create()
 {
@@ -24,6 +16,16 @@ void
 SynchronizerManager::destroy()
 {
   Assert(m_instance != nullptr, "SynchronizerManager was not created!");
+
+  if (m_instance->m_connectivity_synchronizer_map.size() > 0) {
+    std::stringstream error;
+    error << ": some connectivities are still registered\n";
+    for (const auto& i_connectivity_synchronizer : m_instance->m_connectivity_synchronizer_map) {
+      error << " - connectivity " << rang::fgB::magenta << i_connectivity_synchronizer.first << rang::style::reset
+            << '\n';
+    }
+    throw UnexpectedError(error.str());
+  }
   delete m_instance;
   m_instance = nullptr;
 }
diff --git a/src/mesh/SynchronizerManager.hpp b/src/mesh/SynchronizerManager.hpp
index e0e4519c1..79cb3db0a 100644
--- a/src/mesh/SynchronizerManager.hpp
+++ b/src/mesh/SynchronizerManager.hpp
@@ -18,10 +18,10 @@ class SynchronizerManager
   static SynchronizerManager* m_instance;
 
   SynchronizerManager(const SynchronizerManager&) = delete;
-  SynchronizerManager(SynchronizerManager&)       = delete;
+  SynchronizerManager(SynchronizerManager&&)      = delete;
 
-  SynchronizerManager() = default;
-  ~SynchronizerManager();
+  SynchronizerManager()  = default;
+  ~SynchronizerManager() = default;
 
  public:
   static void create();
-- 
GitLab