diff --git a/src/language/ASTNode.hpp b/src/language/ASTNode.hpp index 54e47efc33233566b3803b4a0729a4c08722025c..53d20e687ca5da7ffa77db39afd2581e9a404ba9 100644 --- a/src/language/ASTNode.hpp +++ b/src/language/ASTNode.hpp @@ -56,11 +56,13 @@ class INodeProcessor public: virtual void execute(ExecUntilBreakOrContinue& exec_policy) = 0; - INodeProcessor(const INodeProcessor& node) = delete; + virtual std::string describe() const = 0; - INodeProcessor() {} + INodeProcessor(const INodeProcessor&) = delete; - virtual ~INodeProcessor() {} + INodeProcessor() = default; + + virtual ~INodeProcessor() = default; }; class SymbolTable; diff --git a/src/language/ASTNodeAffectationExpressionBuilder.cpp b/src/language/ASTNodeAffectationExpressionBuilder.cpp index 89a86a2954bf09a85a9fc1496985769401c079b8..5eaa3f785656e2c21061e546cf3ac2fa4a823b0b 100644 --- a/src/language/ASTNodeAffectationExpressionBuilder.cpp +++ b/src/language/ASTNodeAffectationExpressionBuilder.cpp @@ -2,6 +2,8 @@ #include <PEGGrammar.hpp> #include <SymbolTable.hpp> +#include <Demangle.hpp> + template <typename Op> struct AffOp; @@ -77,16 +79,10 @@ class AffectationProcessor final : public INodeProcessor }()}; public: - AffectationProcessor(ASTNode& node) : m_node{node} + std::string + describe() const { - if constexpr (_is_defined) { - const std::string& symbol = m_node.children[0]->string(); - auto [i_symbol, found] = m_node.m_symbol_table->find(symbol, m_node.children[0]->begin()); - Assert(found); - p_value = &i_symbol->second.value(); - } else { - throw parse_error("invalid operands to binary expression", std::vector{m_node.begin()}); - } + return demangle<decltype(*this)>(); } void @@ -106,6 +102,18 @@ class AffectationProcessor final : public INodeProcessor } } } + + AffectationProcessor(ASTNode& node) : m_node{node} + { + if constexpr (_is_defined) { + const std::string& symbol = m_node.children[0]->string(); + auto [i_symbol, found] = m_node.m_symbol_table->find(symbol, m_node.children[0]->begin()); + Assert(found); + p_value = &i_symbol->second.value(); + } else { + throw parse_error("invalid operands to binary expression", std::vector{m_node.begin()}); + } + } }; template <typename OperatorT, typename DataT> @@ -116,12 +124,10 @@ class AffectationToStringProcessor final : public INodeProcessor ASTNodeDataVariant* p_value{nullptr}; public: - AffectationToStringProcessor(ASTNode& node) : m_node{node} + std::string + describe() const { - const std::string& symbol = m_node.children[0]->string(); - auto [i_symbol, found] = m_node.m_symbol_table->find(symbol, m_node.children[0]->begin()); - Assert(found); - p_value = &i_symbol->second.value(); + return demangle<decltype(*this)>(); } void @@ -143,6 +149,14 @@ class AffectationToStringProcessor final : public INodeProcessor } } } + + AffectationToStringProcessor(ASTNode& node) : m_node{node} + { + const std::string& symbol = m_node.children[0]->string(); + auto [i_symbol, found] = m_node.m_symbol_table->find(symbol, m_node.children[0]->begin()); + Assert(found); + p_value = &i_symbol->second.value(); + } }; ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode& n) diff --git a/src/language/ASTNodeBinaryOperatorExpressionBuilder.cpp b/src/language/ASTNodeBinaryOperatorExpressionBuilder.cpp index 8309bf1b49d1c8da76640b49712488c51ab40d45..496668c57a7738cbcd351d3834ba0c7800c51d3c 100644 --- a/src/language/ASTNodeBinaryOperatorExpressionBuilder.cpp +++ b/src/language/ASTNodeBinaryOperatorExpressionBuilder.cpp @@ -2,6 +2,8 @@ #include <PEGGrammar.hpp> #include <SymbolTable.hpp> +#include <Demangle.hpp> + #include <type_traits> template <typename Op> @@ -156,7 +158,7 @@ class BinaryExpressionProcessor final : public INodeProcessor ASTNode& m_node; PUGS_INLINE auto - eval(const ASTNodeDataVariant& a, const ASTNodeDataVariant& b, ASTNodeDataVariant& value) + _eval(const ASTNodeDataVariant& a, const ASTNodeDataVariant& b, ASTNodeDataVariant& value) { // Add 'signed' when necessary to avoid signed/unsigned comparison warnings if constexpr ((not(std::is_same_v<A_DataT, bool> or std::is_same_v<B_DataT, bool>)) and @@ -194,11 +196,10 @@ class BinaryExpressionProcessor final : public INodeProcessor }()}; public: - BinaryExpressionProcessor(ASTNode& node) : m_node{node} + std::string + describe() const { - if constexpr (not _is_defined) { - throw parse_error("invalid operands to binary expression", std::vector{m_node.begin()}); - } + return demangle<decltype(*this)>(); } void @@ -208,7 +209,14 @@ class BinaryExpressionProcessor final : public INodeProcessor m_node.children[0]->execute(exec_policy); m_node.children[1]->execute(exec_policy); - this->eval(m_node.children[0]->m_value, m_node.children[1]->m_value, m_node.m_value); + this->_eval(m_node.children[0]->m_value, m_node.children[1]->m_value, m_node.m_value); + } + } + + BinaryExpressionProcessor(ASTNode& node) : m_node{node} + { + if constexpr (not _is_defined) { + throw parse_error("invalid operands to binary expression", std::vector{m_node.begin()}); } } }; @@ -219,7 +227,7 @@ class ConcatExpressionProcessor final : public INodeProcessor ASTNode& m_node; PUGS_INLINE auto - eval(const std::string& a, const ASTNodeDataVariant& b, ASTNodeDataVariant& value) + _eval(const std::string& a, const ASTNodeDataVariant& b, ASTNodeDataVariant& value) { if constexpr (std::is_same_v<B_DataT, std::string>) { value = a + std::get<B_DataT>(b); @@ -229,7 +237,11 @@ class ConcatExpressionProcessor final : public INodeProcessor } public: - ConcatExpressionProcessor(ASTNode& node) : m_node{node} {} + std::string + describe() const + { + return demangle<decltype(*this)>(); + } void execute(ExecUntilBreakOrContinue& exec_policy) @@ -237,8 +249,10 @@ class ConcatExpressionProcessor final : public INodeProcessor m_node.children[0]->execute(exec_policy); m_node.children[1]->execute(exec_policy); - this->eval(std::get<std::string>(m_node.children[0]->m_value), m_node.children[1]->m_value, m_node.m_value); + this->_eval(std::get<std::string>(m_node.children[0]->m_value), m_node.children[1]->m_value, m_node.m_value); } + + ConcatExpressionProcessor(ASTNode& node) : m_node{node} {} }; ASTNodeBinaryOperatorExpressionBuilder::ASTNodeBinaryOperatorExpressionBuilder(ASTNode& n) diff --git a/src/language/ASTNodeExpressionBuilder.cpp b/src/language/ASTNodeExpressionBuilder.cpp index 93068490c490abdb84f8e8dfe7b7e7ff13a712b9..5c07d1d5ea6e3e4d23d19ff531f4390384ba6753 100644 --- a/src/language/ASTNodeExpressionBuilder.cpp +++ b/src/language/ASTNodeExpressionBuilder.cpp @@ -8,12 +8,18 @@ #include <PEGGrammar.hpp> #include <SymbolTable.hpp> +#include <Demangle.hpp> + class ASTNodeList final : public INodeProcessor { ASTNode& m_node; public: - ASTNodeList(ASTNode& node) : m_node{node} {} + std::string + describe() const + { + return demangle<decltype(*this)>(); + } void execute(ExecUntilBreakOrContinue& exec_policy) @@ -22,12 +28,18 @@ class ASTNodeList final : public INodeProcessor child->execute(exec_policy); } } + + ASTNodeList(ASTNode& node) : m_node{node} {} }; class NoProcess final : public INodeProcessor { public: - NoProcess() {} + std::string + describe() const + { + return demangle<decltype(*this)>(); + } PUGS_INLINE void @@ -35,6 +47,8 @@ class NoProcess final : public INodeProcessor { ; } + + NoProcess() = default; }; class IfStatement final : public INodeProcessor @@ -42,7 +56,11 @@ class IfStatement final : public INodeProcessor ASTNode& m_node; public: - IfStatement(ASTNode& node) : m_node{node} {} + std::string + describe() const + { + return demangle<decltype(*this)>(); + } void execute(ExecUntilBreakOrContinue& exec_policy) @@ -69,6 +87,8 @@ class IfStatement final : public INodeProcessor } } } + + IfStatement(ASTNode& node) : m_node{node} {} }; class DoWhileStatement final : public INodeProcessor @@ -76,7 +96,11 @@ class DoWhileStatement final : public INodeProcessor ASTNode& m_node; public: - DoWhileStatement(ASTNode& node) : m_node{node} {} + std::string + describe() const + { + return demangle<decltype(*this)>(); + } void execute(ExecUntilBreakOrContinue& exec_policy) @@ -105,6 +129,8 @@ class DoWhileStatement final : public INodeProcessor m_node.children[1]->m_value)); } while (continuation_test); } + + DoWhileStatement(ASTNode& node) : m_node{node} {} }; class WhileStatement final : public INodeProcessor @@ -112,7 +138,11 @@ class WhileStatement final : public INodeProcessor ASTNode& m_node; public: - WhileStatement(ASTNode& node) : m_node{node} {} + std::string + describe() const + { + return demangle<decltype(*this)>(); + } void execute(ExecUntilBreakOrContinue& exec_policy) @@ -141,6 +171,8 @@ class WhileStatement final : public INodeProcessor } } } + + WhileStatement(ASTNode& node) : m_node{node} {} }; class ForStatement final : public INodeProcessor @@ -148,7 +180,11 @@ class ForStatement final : public INodeProcessor ASTNode& m_node; public: - ForStatement(ASTNode& node) : m_node{node} {} + std::string + describe() const + { + return demangle<decltype(*this)>(); + } void execute(ExecUntilBreakOrContinue& exec_policy) @@ -180,6 +216,8 @@ class ForStatement final : public INodeProcessor m_node.children[2]->execute(exec_policy); } } + + ForStatement(ASTNode& node) : m_node{node} {} }; class NameExpression final : public INodeProcessor @@ -188,12 +226,10 @@ class NameExpression final : public INodeProcessor ASTNodeDataVariant* p_value{nullptr}; public: - NameExpression(ASTNode& node) : m_node{node} + std::string + describe() const { - const std::string& symbol = m_node.string(); - auto [i_symbol, found] = m_node.m_symbol_table->find(symbol, m_node.begin()); - Assert(found); - p_value = &(i_symbol->second.value()); + return demangle<decltype(*this)>(); } void @@ -201,30 +237,50 @@ class NameExpression final : public INodeProcessor { m_node.m_value = *p_value; } + + NameExpression(ASTNode& node) : m_node{node} + { + const std::string& symbol = m_node.string(); + auto [i_symbol, found] = m_node.m_symbol_table->find(symbol, m_node.begin()); + Assert(found); + p_value = &(i_symbol->second.value()); + } }; class BreakExpression final : public INodeProcessor { public: - BreakExpression() {} + std::string + describe() const + { + return demangle<decltype(*this)>(); + } void execute(ExecUntilBreakOrContinue& exec_policy) { exec_policy = ExecUntilBreakOrContinue(ExecUntilBreakOrContinue::JumpType::break_jump); } + + BreakExpression() = default; }; class ContinueExpression final : public INodeProcessor { public: - ContinueExpression() {} + std::string + describe() const + { + return demangle<decltype(*this)>(); + } void execute(ExecUntilBreakOrContinue& exec_policy) { exec_policy = ExecUntilBreakOrContinue(ExecUntilBreakOrContinue::JumpType::continue_jump); } + + ContinueExpression() = default; }; class OStreamObject final : public INodeProcessor @@ -233,9 +289,10 @@ class OStreamObject final : public INodeProcessor std::ostream& m_os; public: - OStreamObject(ASTNode& node, std::ostream& os) : m_node{node}, m_os(os) + std::string + describe() const { - ; + return demangle<decltype(*this)>(); } void @@ -257,6 +314,11 @@ class OStreamObject final : public INodeProcessor m_node.children[i]->m_value); } } + + OStreamObject(ASTNode& node, std::ostream& os) : m_node{node}, m_os(os) + { + ; + } }; void diff --git a/src/language/ASTNodeIncDecExpressionBuilder.cpp b/src/language/ASTNodeIncDecExpressionBuilder.cpp index cae715aefe4e0f7020136888efd4aa306d653637..485c5d6532f08b624f60563ffae966860836d129 100644 --- a/src/language/ASTNodeIncDecExpressionBuilder.cpp +++ b/src/language/ASTNodeIncDecExpressionBuilder.cpp @@ -2,6 +2,8 @@ #include <PEGGrammar.hpp> #include <SymbolTable.hpp> +#include <Demangle.hpp> + template <typename Op> struct IncDecOp; @@ -66,6 +68,20 @@ class IncDecExpressionProcessor final : public INodeProcessor }()}; public: + std::string + describe() const + { + return demangle<decltype(*this)>(); + } + + void + execute(ExecUntilBreakOrContinue&) + { + if constexpr (_is_defined) { + m_node.m_value = IncDecOp<IncDecOpT>().eval(std::get<DataT>(*p_value)); + } + } + IncDecExpressionProcessor(ASTNode& node) : m_node{node} { if constexpr (_is_defined) { @@ -79,13 +95,6 @@ class IncDecExpressionProcessor final : public INodeProcessor throw parse_error("invalid operand to unary operator", std::vector{m_node.begin()}); } } - void - execute(ExecUntilBreakOrContinue&) - { - if constexpr (_is_defined) { - m_node.m_value = IncDecOp<IncDecOpT>().eval(std::get<DataT>(*p_value)); - } - } }; ASTNodeIncDecExpressionBuilder::ASTNodeIncDecExpressionBuilder(ASTNode& n) diff --git a/src/language/ASTNodeUnaryOperatorExpressionBuilder.cpp b/src/language/ASTNodeUnaryOperatorExpressionBuilder.cpp index 9112ad5535611b1b406ddee7483fde3afc891f46..8d70f9f65173548335dd944deeebe837eb379a77 100644 --- a/src/language/ASTNodeUnaryOperatorExpressionBuilder.cpp +++ b/src/language/ASTNodeUnaryOperatorExpressionBuilder.cpp @@ -2,6 +2,8 @@ #include <PEGGrammar.hpp> #include <SymbolTable.hpp> +#include <Demangle.hpp> + template <typename Op> struct UnaryOp; @@ -32,22 +34,27 @@ class UnaryExpressionProcessor final : public INodeProcessor { ASTNode& m_node; - public: PUGS_INLINE ValueT - eval(const ASTNodeDataVariant& a) + _eval(const ASTNodeDataVariant& a) { return UnaryOp<UnaryOpT>().eval(std::get<DataT>(a)); } public: - UnaryExpressionProcessor(ASTNode& node) : m_node{node} {} + std::string + describe() const + { + return demangle<decltype(*this)>(); + } void execute(ExecUntilBreakOrContinue& exec_policy) { m_node.children[0]->execute(exec_policy); - m_node.m_value = eval(m_node.children[0]->m_value); + m_node.m_value = this->_eval(m_node.children[0]->m_value); } + + UnaryExpressionProcessor(ASTNode& node) : m_node{node} {} }; ASTNodeUnaryOperatorExpressionBuilder::ASTNodeUnaryOperatorExpressionBuilder(ASTNode& n) diff --git a/src/language/ASTPrinter.cpp b/src/language/ASTPrinter.cpp index 3f5b7344aaeb979becfa81875db39257bb85636b..84e03e38fab52533e4bfdd26ff228c8c0ce7d22f 100644 --- a/src/language/ASTPrinter.cpp +++ b/src/language/ASTPrinter.cpp @@ -39,8 +39,19 @@ ASTPrinter::_print(std::ostream& os, const ASTNode& node) const } }, node.m_value); + os << rang::fg::reset; } - os << rang::fg::reset << ")\n"; + + if (m_info & static_cast<InfoBaseType>(Info::exec_type)) { + if (node.m_node_processor) { + os << ':'; + os << rang::fgB::magenta; + os << node.m_node_processor->describe(); + os << rang::fg::reset; + } + } + + os << ")\n"; if (not node.children.empty()) { _print(os, node.children); diff --git a/src/language/ASTPrinter.hpp b/src/language/ASTPrinter.hpp index 464a67435c88a028254f8b52c59bb6f4005b4e2f..d8eb0802af8b4fdd61fd594583dbfa4f61800703 100644 --- a/src/language/ASTPrinter.hpp +++ b/src/language/ASTPrinter.hpp @@ -19,6 +19,7 @@ class ASTPrinter none = 0, data_type = 1 << 0, data_value = 1 << 1, + exec_type = 1 << 2, all = std::numeric_limits<InfoBaseType>::max() }; diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt index 3333d9b769e8d2efad96f5335cbdd983a77221d6..7b440e23ea1e62f0a9545e64a08f9bf3dab49c64 100644 --- a/src/language/CMakeLists.txt +++ b/src/language/CMakeLists.txt @@ -27,4 +27,5 @@ add_library( #include_directories(${PUGS_SOURCE_DIR}/utils) # Additional dependencies -#add_dependencies(PugsMesh) +add_dependencies(PugsLanguage + PugsUtils) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 29d77d5d018bfdfce8b1acfa325290985c29c938..56957855999ef09f029c9e7311ee1d4842f0ccc2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -32,8 +32,8 @@ add_executable (mpi_unit_tests ) target_link_libraries (unit_tests - PugsUtils PugsLanguage + PugsUtils kokkos Catch2 ) diff --git a/tests/test_ASTNodeExpressionBuilder.cpp b/tests/test_ASTNodeExpressionBuilder.cpp index 2ce02e86e5ea591c41f8b175068f13a758db8710..b7a6c82a1c8fd3c797458eb70c7e6c01fdfa218f 100644 --- a/tests/test_ASTNodeExpressionBuilder.cpp +++ b/tests/test_ASTNodeExpressionBuilder.cpp @@ -14,26 +14,29 @@ #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}; \ - ASTNodeDeclarationCleaner{*ast}; \ - \ - ASTNodeExpressionBuilder{*ast}; \ - std::stringstream ast_output; \ - ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::none}}; \ - \ - REQUIRE(ast_output.str() == expected_output); \ +#include <Demangle.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>) or \ + (std::is_same_v<std::decay_t<decltype(expected_output)>, std::string>)); \ + \ + string_input input{data, "test.pgs"}; \ + auto ast = ASTBuilder::build(input); \ + \ + ASTSymbolTableBuilder{*ast}; \ + ASTNodeDataTypeBuilder{*ast}; \ + ASTNodeValueBuilder{*ast}; \ + \ + ASTNodeDeclarationToAffectationConverter{*ast}; \ + ASTNodeDeclarationCleaner{*ast}; \ + \ + ASTNodeExpressionBuilder{*ast}; \ + std::stringstream ast_output; \ + ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::exec_type}}; \ + \ + REQUIRE(ast_output.str() == expected_output); \ } TEST_CASE("ASTNodeExpressionBuilder", "[language]") @@ -44,9 +47,77 @@ TEST_CASE("ASTNodeExpressionBuilder", "[language]") )"; std::string_view result = R"( -(root) +(root:ASTNodeList) )"; CHECK_AST(data, result); } + + SECTION("string affectation") + { + SECTION("from bool") + { + std::string_view data = R"( +string s = true; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::eq_op:AffectationToStringProcessor<language::eq_op, bool>) + +-(language::name:s:NameExpression) + `-(language::true_kw:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("from int") + { + std::string_view data = R"( +string s = 0; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::eq_op:AffectationToStringProcessor<language::eq_op, long>) + +-(language::name:s:NameExpression) + `-(language::integer:0:NoProcess) +)"; + CHECK_AST(data, result); + } + + SECTION("from unsigned") + { + std::string_view data = R"( +N n = 0; +string s = n; +)"; + + std::string result = R"( +(root:ASTNodeList) + +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>) + | +-(language::name:n:NameExpression) + | `-(language::integer:0:NoProcess) + `-(language::eq_op:AffectationToStringProcessor<language::eq_op, unsigned long>) + +-(language::name:s:NameExpression) + `-(language::name:n:NameExpression) +)"; + CHECK_AST(data, result); + } + + SECTION("from real") + { + std::string_view data = R"( +string s = 0.; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::eq_op:AffectationToStringProcessor<language::eq_op, double>) + +-(language::name:s:NameExpression) + `-(language::real:0.:NoProcess) +)"; + CHECK_AST(data, result); + } + } }