From 4634976626b6102cb5fc7b57af8c58c26f5eaeeb Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Fri, 27 Sep 2019 15:04:47 +0200 Subject: [PATCH] Remove empty blocks and function declarations --- src/language/ASTNodeDeclarationCleaner.cpp | 2 +- src/language/ASTNodeEmptyBlockCleaner.cpp | 37 ++++++++++++++++++++++ src/language/ASTNodeEmptyBlockCleaner.hpp | 15 +++++++++ src/language/CMakeLists.txt | 1 + src/language/PugsParser.cpp | 3 ++ 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/language/ASTNodeEmptyBlockCleaner.cpp create mode 100644 src/language/ASTNodeEmptyBlockCleaner.hpp diff --git a/src/language/ASTNodeDeclarationCleaner.cpp b/src/language/ASTNodeDeclarationCleaner.cpp index 05a6822fd..7e2f139f9 100644 --- a/src/language/ASTNodeDeclarationCleaner.cpp +++ b/src/language/ASTNodeDeclarationCleaner.cpp @@ -10,7 +10,7 @@ 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>()) { + if (n.children[i_child]->is<language::declaration>() or n.children[i_child]->is<language::let_declaration>()) { declaration_ids.push(i_child); } } diff --git a/src/language/ASTNodeEmptyBlockCleaner.cpp b/src/language/ASTNodeEmptyBlockCleaner.cpp new file mode 100644 index 000000000..eeb71c087 --- /dev/null +++ b/src/language/ASTNodeEmptyBlockCleaner.cpp @@ -0,0 +1,37 @@ +#include <ASTNodeEmptyBlockCleaner.hpp> + +#include <PEGGrammar.hpp> +#include <PugsAssert.hpp> + +#include <stack> + +void +ASTNodeEmptyBlockCleaner::_removeEmptyBlockNode(ASTNode& n) +{ + for (auto& child : n.children) { + this->_removeEmptyBlockNode(*child); + } + + std::stack<size_t> empty_block_ids; + for (size_t i_child = 0; i_child < n.children.size(); ++i_child) { + if (n.children[i_child]->is<language::block>()) { + if (n.children[i_child]->children.size() == 0) + empty_block_ids.push(i_child); + } + } + + while (empty_block_ids.size() > 0) { + size_t i_removed = empty_block_ids.top(); + empty_block_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(); + } +} + +ASTNodeEmptyBlockCleaner::ASTNodeEmptyBlockCleaner(ASTNode& n) +{ + Assert(n.is_root()); + this->_removeEmptyBlockNode(n); +} diff --git a/src/language/ASTNodeEmptyBlockCleaner.hpp b/src/language/ASTNodeEmptyBlockCleaner.hpp new file mode 100644 index 000000000..bfa492ec0 --- /dev/null +++ b/src/language/ASTNodeEmptyBlockCleaner.hpp @@ -0,0 +1,15 @@ +#ifndef AST_NODE_EMPTY_BLOCK_CLEANER_HPP +#define AST_NODE_EMPTY_BLOCK_CLEANER_HPP + +#include <ASTNode.hpp> + +class ASTNodeEmptyBlockCleaner +{ + private: + void _removeEmptyBlockNode(ASTNode& node); + + public: + ASTNodeEmptyBlockCleaner(ASTNode& root_node); +}; + +#endif // AST_NODE_EMPTY_BLOCK_CLEANER_HPP diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt index 9910dd470..ab42c18cc 100644 --- a/src/language/CMakeLists.txt +++ b/src/language/CMakeLists.txt @@ -16,6 +16,7 @@ add_library( ASTNodeDataTypeChecker.cpp ASTNodeDeclarationToAffectationConverter.cpp ASTNodeDeclarationCleaner.cpp + ASTNodeEmptyBlockCleaner.cpp ASTNodeExpressionBuilder.cpp ASTNodeIncDecExpressionBuilder.cpp ASTNodeJumpPlacementChecker.cpp diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp index 1b40aa888..d59d53210 100644 --- a/src/language/PugsParser.cpp +++ b/src/language/PugsParser.cpp @@ -29,6 +29,8 @@ #include <ASTSymbolInitializationChecker.hpp> #include <ASTSymbolTableBuilder.hpp> +#include <ASTNodeEmptyBlockCleaner.hpp> + #include <ASTNodeDeclarationCleaner.hpp> #include <ASTNodeDeclarationToAffectationConverter.hpp> @@ -75,6 +77,7 @@ parser(const std::string& filename) // optimizations ASTNodeDeclarationToAffectationConverter{*root_node}; ASTNodeDeclarationCleaner{*root_node}; + ASTNodeEmptyBlockCleaner{*root_node}; ASTNodeExpressionBuilder{*root_node}; -- GitLab