From d95517a6dc778c740aa847171af5beeb898c4a81 Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Thu, 25 Jul 2019 18:57:44 +0200 Subject: [PATCH] Add ASTNodeDataTypeChecker and its associated tests --- src/language/ASTNodeDataTypeChecker.cpp | 20 +++++++++++ src/language/ASTNodeDataTypeChecker.hpp | 15 ++++++++ src/language/CMakeLists.txt | 1 + src/language/PugsParser.cpp | 26 ++------------ tests/CMakeLists.txt | 1 + tests/test_ASTNodeDataTypeChecker.cpp | 48 +++++++++++++++++++++++++ 6 files changed, 87 insertions(+), 24 deletions(-) create mode 100644 src/language/ASTNodeDataTypeChecker.cpp create mode 100644 src/language/ASTNodeDataTypeChecker.hpp create mode 100644 tests/test_ASTNodeDataTypeChecker.cpp diff --git a/src/language/ASTNodeDataTypeChecker.cpp b/src/language/ASTNodeDataTypeChecker.cpp new file mode 100644 index 000000000..d598e3a87 --- /dev/null +++ b/src/language/ASTNodeDataTypeChecker.cpp @@ -0,0 +1,20 @@ +#include <ASTNodeDataTypeChecker.hpp> + +void +ASTNodeDataTypeChecker::_checkNodeDataTypes(const ASTNode& n) +{ + if (n.m_data_type == ASTNodeDataType::undefined_t) { + throw parse_error("unexpected error: undefined datatype for AST node for " + n.name(), n.begin()); + } + + for (const auto& child : n.children) { + this->_checkNodeDataTypes(*child); + } +} + +ASTNodeDataTypeChecker::ASTNodeDataTypeChecker(const ASTNode& node) +{ + Assert(node.is_root()); + this->_checkNodeDataTypes(node); + std::cout << " - checked node data types\n"; +} diff --git a/src/language/ASTNodeDataTypeChecker.hpp b/src/language/ASTNodeDataTypeChecker.hpp new file mode 100644 index 000000000..6bf555a0b --- /dev/null +++ b/src/language/ASTNodeDataTypeChecker.hpp @@ -0,0 +1,15 @@ +#ifndef AST_NODE_DATA_TYPE_CHECKER_HPP +#define AST_NODE_DATA_TYPE_CHECKER_HPP + +#include <ASTNode.hpp> + +class ASTNodeDataTypeChecker +{ + private: + void _checkNodeDataTypes(const ASTNode& node); + + public: + ASTNodeDataTypeChecker(const ASTNode& root_node); +}; + +#endif // AST_NODE_DATA_TYPE_CHECKER_HPP diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt index 8216aeac9..5b14863b4 100644 --- a/src/language/CMakeLists.txt +++ b/src/language/CMakeLists.txt @@ -9,6 +9,7 @@ add_library( ASTDotPrinter.cpp ASTNodeDataType.cpp ASTNodeDataTypeBuilder.cpp + ASTNodeDataTypeChecker.cpp ASTNodeAffectationExpressionBuilder.cpp ASTNodeBinaryOperatorExpressionBuilder.cpp ASTNodeExpressionBuilder.cpp diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp index b57dfc03a..f0a3ebb05 100644 --- a/src/language/PugsParser.cpp +++ b/src/language/PugsParser.cpp @@ -20,6 +20,7 @@ #include <SymbolTable.hpp> #include <ASTNodeDataTypeBuilder.hpp> +#include <ASTNodeDataTypeChecker.hpp> #include <EscapedString.hpp> @@ -33,29 +34,6 @@ namespace language { -namespace internal -{ -void -check_node_data_types(const ASTNode& n) -{ - if (n.m_data_type == ASTNodeDataType::undefined_t) { - throw parse_error("unexpected error: undefined datatype for AST node for " + n.name(), n.begin()); - } - - for (auto& child : n.children) { - check_node_data_types(*child); - } -} -} // namespace internal - -void -check_node_data_types(const ASTNode& n) -{ - Assert(n.is_root()); - internal::check_node_data_types(n); - std::cout << " - checked node data types\n"; -} - namespace internal { void @@ -199,8 +177,8 @@ parser(const std::string& filename) } ASTNodeDataTypeBuilder{*root_node}; + ASTNodeDataTypeChecker{*root_node}; - language::check_node_data_types(*root_node); language::build_node_values(*root_node); language::check_break_or_continue_placement(*root_node); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b8c714d18..21c8a1b23 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,6 +9,7 @@ add_executable (unit_tests test_ASTBuilder.cpp test_ASTNodeDataType.cpp test_ASTNodeDataTypeBuilder.cpp + test_ASTNodeDataTypeChecker.cpp test_ASTPrinter.cpp test_ASTSymbolTableBuilder.cpp test_ASTSymbolInitializationChecker.cpp diff --git a/tests/test_ASTNodeDataTypeChecker.cpp b/tests/test_ASTNodeDataTypeChecker.cpp new file mode 100644 index 000000000..bb4c7474d --- /dev/null +++ b/tests/test_ASTNodeDataTypeChecker.cpp @@ -0,0 +1,48 @@ +#include <catch2/catch.hpp> + +#include <ASTBuilder.hpp> + +#include <ASTNodeDataTypeBuilder.hpp> +#include <ASTNodeDataTypeChecker.hpp> +#include <ASTSymbolTableBuilder.hpp> + +TEST_CASE("ASTNodeDataTypeChecker", "[language]") +{ + SECTION("everything ok: nothrow") + { + std::string_view data = R"( +for(Z i=0; i<10; ++i) { + cout << "i=" << i; + cout<< "\n"; +} +)"; + + string_input input{data, "test.pgs"}; + auto ast = ASTBuilder::build(input); + + ASTSymbolTableBuilder{*ast}; + ASTNodeDataTypeBuilder{*ast}; + + REQUIRE_NOTHROW(ASTNodeDataTypeChecker{*ast}); + } + + SECTION("everything uninitialized node type") + { + std::string_view data = R"( +for(Z i=0; i<10; ++i) { + cout << "i=" << i; + cout<< "\n"; +} +)"; + + string_input input{data, "test.pgs"}; + auto ast = ASTBuilder::build(input); + + ASTSymbolTableBuilder{*ast}; + ASTNodeDataTypeBuilder{*ast}; + + ast->children[0]->m_data_type = ASTNodeDataType::undefined_t; + + REQUIRE_THROWS_AS(ASTNodeDataTypeChecker{*ast}, parse_error); + } +} -- GitLab