From 2605cd626bb91cd87dd09e23aa886e6f9e827d89 Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Fri, 26 Jul 2019 18:12:51 +0200 Subject: [PATCH] Add ASTNodeDeclarationToAffectationConverter and its unit tests --- ...TNodeDeclarationToAffectationConverter.cpp | 27 +++++ ...TNodeDeclarationToAffectationConverter.hpp | 15 +++ src/language/CMakeLists.txt | 1 + src/language/PugsParser.cpp | 35 +----- tests/CMakeLists.txt | 1 + ...TNodeDeclarationToAffectationConverter.cpp | 111 ++++++++++++++++++ 6 files changed, 158 insertions(+), 32 deletions(-) create mode 100644 src/language/ASTNodeDeclarationToAffectationConverter.cpp create mode 100644 src/language/ASTNodeDeclarationToAffectationConverter.hpp create mode 100644 tests/test_ASTNodeDeclarationToAffectationConverter.cpp diff --git a/src/language/ASTNodeDeclarationToAffectationConverter.cpp b/src/language/ASTNodeDeclarationToAffectationConverter.cpp new file mode 100644 index 000000000..bc641a01c --- /dev/null +++ b/src/language/ASTNodeDeclarationToAffectationConverter.cpp @@ -0,0 +1,27 @@ +#include <ASTNodeDeclarationToAffectationConverter.hpp> + +#include <PEGGrammar.hpp> +#include <PugsAssert.hpp> + +void +ASTNodeDeclarationToAffectationConverter::_convertNodeDeclaration(ASTNode& n) +{ + if (n.is<language::declaration>()) { + if (n.children.size() == 3) { + n.children[0] = std::move(n.children[1]); + n.children[1] = std::move(n.children[2]); + n.children.resize(2); + n.id = typeid(language::eq_op); + } + } else { + for (auto& child : n.children) { + this->_convertNodeDeclaration(*child); + } + } +} + +ASTNodeDeclarationToAffectationConverter::ASTNodeDeclarationToAffectationConverter(ASTNode& n) +{ + Assert(n.is_root()); + this->_convertNodeDeclaration(n); +} diff --git a/src/language/ASTNodeDeclarationToAffectationConverter.hpp b/src/language/ASTNodeDeclarationToAffectationConverter.hpp new file mode 100644 index 000000000..8a5dd0cf0 --- /dev/null +++ b/src/language/ASTNodeDeclarationToAffectationConverter.hpp @@ -0,0 +1,15 @@ +#ifndef AST_NODE_DECLARATION_TO_AFFECTATION_CONVERTER_HPP +#define AST_NODE_DECLARATION_TO_AFFECTATION_CONVERTER_HPP + +#include <ASTNode.hpp> + +class ASTNodeDeclarationToAffectationConverter +{ + private: + void _convertNodeDeclaration(ASTNode& node); + + public: + ASTNodeDeclarationToAffectationConverter(ASTNode& root_node); +}; + +#endif // AST_NODE_DECLARATION_TO_AFFECTATION_CONVERTER_HPP diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt index ae4c49563..496f44e92 100644 --- a/src/language/CMakeLists.txt +++ b/src/language/CMakeLists.txt @@ -12,6 +12,7 @@ add_library( ASTNodeDataType.cpp ASTNodeDataTypeBuilder.cpp ASTNodeDataTypeChecker.cpp + ASTNodeDeclarationToAffectationConverter.cpp ASTNodeExpressionBuilder.cpp ASTNodeIncDecExpressionBuilder.cpp ASTNodeJumpPlacementChecker.cpp diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp index 518250a29..0972e9117 100644 --- a/src/language/PugsParser.cpp +++ b/src/language/PugsParser.cpp @@ -29,42 +29,13 @@ #include <ASTSymbolInitializationChecker.hpp> #include <ASTSymbolTableBuilder.hpp> +#include <ASTNodeDeclarationToAffectationConverter.hpp> + #include <ASTDotPrinter.hpp> #include <ASTPrinter.hpp> #include <ASTNodeValueBuilder.hpp> -namespace language -{ -namespace internal -{ -void -simplify_declarations(ASTNode& n) -{ - if (n.is<language::declaration>()) { - if (n.children.size() == 3) { - n.children[0] = std::move(n.children[1]); - n.children[1] = std::move(n.children[2]); - n.children.resize(2); - n.id = typeid(language::eq_op); - } - } else { - for (auto& child : n.children) { - simplify_declarations(*child); - } - } -} -} // namespace internal - -void -simplify_declarations(ASTNode& n) -{ - Assert(n.is_root()); - internal::simplify_declarations(n); -} - -} // namespace language - void parser(const std::string& filename) { @@ -100,7 +71,7 @@ parser(const std::string& filename) ASTNodeJumpPlacementChecker{*root_node}; // optimizations - language::simplify_declarations(*root_node); + ASTNodeDeclarationToAffectationConverter{*root_node}; language::build_node_type(*root_node); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 246771d48..235e13153 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable (unit_tests test_ASTNodeDataType.cpp test_ASTNodeDataTypeBuilder.cpp test_ASTNodeDataTypeChecker.cpp + test_ASTNodeDeclarationToAffectationConverter.cpp test_ASTNodeJumpPlacementChecker.cpp test_ASTNodeValueBuilder.cpp test_ASTPrinter.cpp diff --git a/tests/test_ASTNodeDeclarationToAffectationConverter.cpp b/tests/test_ASTNodeDeclarationToAffectationConverter.cpp new file mode 100644 index 000000000..b7f00390c --- /dev/null +++ b/tests/test_ASTNodeDeclarationToAffectationConverter.cpp @@ -0,0 +1,111 @@ +#include <catch2/catch.hpp> + +#include <ASTNodeValueBuilder.hpp> + +#include <ASTBuilder.hpp> +#include <ASTNodeDataTypeBuilder.hpp> + +#include <ASTNodeDeclarationToAffectationConverter.hpp> + +#include <ASTSymbolTableBuilder.hpp> + +#include <ASTPrinter.hpp> + +#define CHECK_AST(data, expected_output) \ + { \ + static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>); \ + static_assert(std::is_same_v<std::decay_t<decltype(expected_output)>, std::string_view>); \ + \ + string_input input{data, "test.pgs"}; \ + auto ast = ASTBuilder::build(input); \ + \ + ASTSymbolTableBuilder{*ast}; \ + ASTNodeDataTypeBuilder{*ast}; \ + ASTNodeValueBuilder{*ast}; \ + \ + ASTNodeDeclarationToAffectationConverter{*ast}; \ + \ + std::stringstream ast_output; \ + ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::none}}; \ + \ + REQUIRE(ast_output.str() == expected_output); \ + } + +TEST_CASE("ASTNodeDeclarationToAffectationConverter", "[language]") +{ + SECTION("nothing to convert") + { + std::string_view data = R"( +R z; +)"; + + std::string_view result = R"( +(root) + `-(language::declaration) + +-(language::R_set) + `-(language::name:z) +)"; + + CHECK_AST(data, result); + } + + SECTION("simple constructor") + { + std::string_view data = R"( +R z = 0; +)"; + + std::string_view result = R"( +(root) + `-(language::eq_op) + +-(language::name:z) + `-(language::integer:0) +)"; + + CHECK_AST(data, result); + } + + SECTION("complex constructors") + { + std::string_view data = R"( +N k = 0; +for(N i=0; i<2; ++i) { + N j = 2*i+k; + k = 2*j-1; +} +)"; + + std::string_view result = R"( +(root) + +-(language::eq_op) + | +-(language::name:k) + | `-(language::integer:0) + `-(language::for_statement) + +-(language::eq_op) + | +-(language::name:i) + | `-(language::integer:0) + +-(language::lesser_op) + | +-(language::name:i) + | `-(language::integer:2) + +-(language::unary_plusplus) + | `-(language::name:i) + `-(language::for_statement_bloc) + +-(language::eq_op) + | +-(language::name:j) + | `-(language::plus_op) + | +-(language::multiply_op) + | | +-(language::integer:2) + | | `-(language::name:i) + | `-(language::name:k) + `-(language::eq_op) + +-(language::name:k) + `-(language::minus_op) + +-(language::multiply_op) + | +-(language::integer:2) + | `-(language::name:j) + `-(language::integer:1) +)"; + + CHECK_AST(data, result); + } +} -- GitLab