From 9fac66053a998edecdd7615a44a310c5fe640209 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Fri, 26 Jul 2019 19:22:14 +0200
Subject: [PATCH] Add ASTNodeDeclarationCleaner

This removes declaration instructions. These instructions have been used to
build symbol tables are then useless in the AST.

Other instructions could probably be removed but it is future work and probably
not crucial optimization.
---
 src/language/ASTNodeDeclarationCleaner.cpp | 36 ++++++++++++++++++++++
 src/language/ASTNodeDeclarationCleaner.hpp | 15 +++++++++
 src/language/CMakeLists.txt                |  1 +
 src/language/PugsParser.cpp                |  2 ++
 4 files changed, 54 insertions(+)
 create mode 100644 src/language/ASTNodeDeclarationCleaner.cpp
 create mode 100644 src/language/ASTNodeDeclarationCleaner.hpp

diff --git a/src/language/ASTNodeDeclarationCleaner.cpp b/src/language/ASTNodeDeclarationCleaner.cpp
new file mode 100644
index 000000000..05a6822fd
--- /dev/null
+++ b/src/language/ASTNodeDeclarationCleaner.cpp
@@ -0,0 +1,36 @@
+#include <ASTNodeDeclarationCleaner.hpp>
+
+#include <PEGGrammar.hpp>
+#include <PugsAssert.hpp>
+
+#include <stack>
+
+void
+ASTNodeDeclarationCleaner::_removeDeclarationNode(ASTNode& n)
+{
+  std::stack<size_t> declaration_ids;
+  for (size_t i_child = 0; i_child < n.children.size(); ++i_child) {
+    if (n.children[i_child]->is<language::declaration>()) {
+      declaration_ids.push(i_child);
+    }
+  }
+
+  while (declaration_ids.size() > 0) {
+    size_t i_removed = declaration_ids.top();
+    declaration_ids.pop();
+    for (size_t i = i_removed; i + 1 < n.children.size(); ++i) {
+      n.children[i] = std::move(n.children[i + 1]);
+    }
+    n.children.pop_back();
+  }
+
+  for (auto& child : n.children) {
+    this->_removeDeclarationNode(*child);
+  }
+}
+
+ASTNodeDeclarationCleaner::ASTNodeDeclarationCleaner(ASTNode& n)
+{
+  Assert(n.is_root());
+  this->_removeDeclarationNode(n);
+}
diff --git a/src/language/ASTNodeDeclarationCleaner.hpp b/src/language/ASTNodeDeclarationCleaner.hpp
new file mode 100644
index 000000000..422f1e910
--- /dev/null
+++ b/src/language/ASTNodeDeclarationCleaner.hpp
@@ -0,0 +1,15 @@
+#ifndef AST_NODE_DECLARATION_CLEANER_HPP
+#define AST_NODE_DECLARATION_CLEANER_HPP
+
+#include <ASTNode.hpp>
+
+class ASTNodeDeclarationCleaner
+{
+ private:
+  void _removeDeclarationNode(ASTNode& node);
+
+ public:
+  ASTNodeDeclarationCleaner(ASTNode& root_node);
+};
+
+#endif   // AST_NODE_DECLARATION_CLEANER_HPP
diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt
index 496f44e92..3333d9b76 100644
--- a/src/language/CMakeLists.txt
+++ b/src/language/CMakeLists.txt
@@ -13,6 +13,7 @@ add_library(
   ASTNodeDataTypeBuilder.cpp
   ASTNodeDataTypeChecker.cpp
   ASTNodeDeclarationToAffectationConverter.cpp
+  ASTNodeDeclarationCleaner.cpp
   ASTNodeExpressionBuilder.cpp
   ASTNodeIncDecExpressionBuilder.cpp
   ASTNodeJumpPlacementChecker.cpp
diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp
index 0972e9117..f37b16f8a 100644
--- a/src/language/PugsParser.cpp
+++ b/src/language/PugsParser.cpp
@@ -29,6 +29,7 @@
 #include <ASTSymbolInitializationChecker.hpp>
 #include <ASTSymbolTableBuilder.hpp>
 
+#include <ASTNodeDeclarationCleaner.hpp>
 #include <ASTNodeDeclarationToAffectationConverter.hpp>
 
 #include <ASTDotPrinter.hpp>
@@ -72,6 +73,7 @@ parser(const std::string& filename)
 
     // optimizations
     ASTNodeDeclarationToAffectationConverter{*root_node};
+    ASTNodeDeclarationCleaner{*root_node};
 
     language::build_node_type(*root_node);
 
-- 
GitLab