From 3b753de7c10df8d4cfa2c0f54364d2f6887abb14 Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Tue, 30 Jul 2019 19:28:31 +0200 Subject: [PATCH] Begin displacement of processors to their own files The language/node_processor sub-directory was created It remains to displace a few classes embedded into some expression builders --- src/language/ASTNode.hpp | 4 +- src/language/ASTNodeExpressionBuilder.cpp | 325 +----------------- src/language/CMakeLists.txt | 4 +- .../node_processor/ASTNodeListProcessor.hpp | 30 ++ .../node_processor/BreakProcessor.hpp | 26 ++ src/language/node_processor/CMakeLists.txt | 5 + .../node_processor/ContinueProcessor.hpp | 26 ++ .../node_processor/DoWhileProcessor.hpp | 50 +++ .../ExecUntilBreakOrContinue.hpp | 0 src/language/node_processor/FakeProcessor.hpp | 27 ++ src/language/node_processor/ForProcessor.hpp | 53 +++ .../{ => node_processor}/INodeProcessor.hpp | 2 +- src/language/node_processor/IfProcessor.hpp | 48 +++ src/language/node_processor/NameProcessor.hpp | 37 ++ .../node_processor/OStreamProcessor.hpp | 46 +++ .../node_processor/WhileProcessor.hpp | 50 +++ 16 files changed, 414 insertions(+), 319 deletions(-) create mode 100644 src/language/node_processor/ASTNodeListProcessor.hpp create mode 100644 src/language/node_processor/BreakProcessor.hpp create mode 100644 src/language/node_processor/CMakeLists.txt create mode 100644 src/language/node_processor/ContinueProcessor.hpp create mode 100644 src/language/node_processor/DoWhileProcessor.hpp rename src/language/{ => node_processor}/ExecUntilBreakOrContinue.hpp (100%) create mode 100644 src/language/node_processor/FakeProcessor.hpp create mode 100644 src/language/node_processor/ForProcessor.hpp rename src/language/{ => node_processor}/INodeProcessor.hpp (87%) create mode 100644 src/language/node_processor/IfProcessor.hpp create mode 100644 src/language/node_processor/NameProcessor.hpp create mode 100644 src/language/node_processor/OStreamProcessor.hpp create mode 100644 src/language/node_processor/WhileProcessor.hpp diff --git a/src/language/ASTNode.hpp b/src/language/ASTNode.hpp index e8ef09b3a..31b12b1e5 100644 --- a/src/language/ASTNode.hpp +++ b/src/language/ASTNode.hpp @@ -7,8 +7,8 @@ #include <ASTNodeDataType.hpp> #include <ASTNodeDataVariant.hpp> -#include <ExecUntilBreakOrContinue.hpp> -#include <INodeProcessor.hpp> +#include <node_processor/ExecUntilBreakOrContinue.hpp> +#include <node_processor/INodeProcessor.hpp> #include <pegtl/contrib/parse_tree.hpp> diff --git a/src/language/ASTNodeExpressionBuilder.cpp b/src/language/ASTNodeExpressionBuilder.cpp index 8eb9b8995..ceeb6eaac 100644 --- a/src/language/ASTNodeExpressionBuilder.cpp +++ b/src/language/ASTNodeExpressionBuilder.cpp @@ -5,321 +5,18 @@ #include <ASTNodeIncDecExpressionBuilder.hpp> #include <ASTNodeUnaryOperatorExpressionBuilder.hpp> -#include <PEGGrammar.hpp> -#include <SymbolTable.hpp> - -#include <Demangle.hpp> - -class ASTNodeListProcessor final : public INodeProcessor -{ - ASTNode& m_node; - - public: - std::string - describe() const - { - return demangle<decltype(*this)>(); - } - - void - execute(ExecUntilBreakOrContinue& exec_policy) - { - for (auto& child : m_node.children) { - child->execute(exec_policy); - } - } - - ASTNodeListProcessor(ASTNode& node) : m_node{node} {} -}; - -class FakeProcessor final : public INodeProcessor -{ - public: - std::string - describe() const - { - return demangle<decltype(*this)>(); - } - - PUGS_INLINE - void - execute(ExecUntilBreakOrContinue&) - { - ; - } - - FakeProcessor() = default; -}; - -class IfProcessor final : public INodeProcessor -{ - ASTNode& m_node; - - public: - std::string - describe() const - { - return demangle<decltype(*this)>(); - } - - void - execute(ExecUntilBreakOrContinue& exec_policy) - { - m_node.children[0]->execute(exec_policy); - const bool is_true = static_cast<bool>(std::visit( - [](const auto& value) -> bool { - using T = std::decay_t<decltype(value)>; - if constexpr (std::is_arithmetic_v<T>) { - return value; - } else { - return false; - } - }, - m_node.children[0]->m_value)); - if (is_true) { - Assert(m_node.children[1] != nullptr); - m_node.children[1]->execute(exec_policy); - } else { - if (m_node.children.size() == 3) { - // else statement - Assert(m_node.children[2] != nullptr); - m_node.children[2]->execute(exec_policy); - } - } - } - - IfProcessor(ASTNode& node) : m_node{node} {} -}; - -class DoWhileProcessor final : public INodeProcessor -{ - ASTNode& m_node; - - public: - std::string - describe() const - { - return demangle<decltype(*this)>(); - } - - void - execute(ExecUntilBreakOrContinue& exec_policy) - { - bool continuation_test = true; - ExecUntilBreakOrContinue exec_until_jump; - do { - m_node.children[0]->execute(exec_until_jump); - if (not exec_until_jump.exec()) { - if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::break_jump) { - break; - } else if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::continue_jump) { - exec_until_jump = ExecUntilBreakOrContinue{}; // getting ready for next loop traversal - } - } - m_node.children[1]->execute(exec_policy); - continuation_test = static_cast<bool>(std::visit( - [](const auto& value) -> bool { - using T = std::decay_t<decltype(value)>; - if constexpr (std::is_arithmetic_v<T>) { - return value; - } else { - return false; - } - }, - m_node.children[1]->m_value)); - } while (continuation_test); - } - - DoWhileProcessor(ASTNode& node) : m_node{node} {} -}; - -class WhileProcessor final : public INodeProcessor -{ - ASTNode& m_node; - - public: - std::string - describe() const - { - return demangle<decltype(*this)>(); - } - - void - execute(ExecUntilBreakOrContinue& exec_policy) - { - ExecUntilBreakOrContinue exec_until_jump; - while ([&]() { - m_node.children[0]->execute(exec_policy); - return static_cast<bool>(std::visit( - [](const auto& value) -> bool { - using T = std::decay_t<decltype(value)>; - if constexpr (std::is_arithmetic_v<T>) { - return value; - } else { - return false; - } - }, - m_node.children[0]->m_value)); - }()) { - m_node.children[1]->execute(exec_until_jump); - if (not exec_until_jump.exec()) { - if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::break_jump) { - break; - } else if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::continue_jump) { - exec_until_jump = ExecUntilBreakOrContinue{}; // getting ready for next loop traversal - } - } - } - } - - WhileProcessor(ASTNode& node) : m_node{node} {} -}; +#include <node_processor/ASTNodeListProcessor.hpp> +#include <node_processor/BreakProcessor.hpp> +#include <node_processor/ContinueProcessor.hpp> +#include <node_processor/DoWhileProcessor.hpp> +#include <node_processor/FakeProcessor.hpp> +#include <node_processor/ForProcessor.hpp> +#include <node_processor/IfProcessor.hpp> +#include <node_processor/NameProcessor.hpp> +#include <node_processor/OStreamProcessor.hpp> +#include <node_processor/WhileProcessor.hpp> -class ForProcessor final : public INodeProcessor -{ - ASTNode& m_node; - - public: - std::string - describe() const - { - return demangle<decltype(*this)>(); - } - - void - execute(ExecUntilBreakOrContinue& exec_policy) - { - ExecUntilBreakOrContinue exec_until_jump; - m_node.children[0]->execute(exec_policy); - while ([&]() { - m_node.children[1]->execute(exec_policy); - return static_cast<bool>(std::visit( - [](const auto& value) -> bool { - using T = std::decay_t<decltype(value)>; - if constexpr (std::is_arithmetic_v<T>) { - return value; - } else { - return false; - } - }, - m_node.children[1]->m_value)); - }()) { - m_node.children[3]->execute(exec_until_jump); - if (not exec_until_jump.exec()) { - if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::break_jump) { - break; - } else if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::continue_jump) { - exec_until_jump = ExecUntilBreakOrContinue{}; // getting ready for next loop traversal - } - } - - m_node.children[2]->execute(exec_policy); - } - } - - ForProcessor(ASTNode& node) : m_node{node} {} -}; - -class NameProcessor final : public INodeProcessor -{ - ASTNode& m_node; - ASTNodeDataVariant* p_value{nullptr}; - - public: - std::string - describe() const - { - return demangle<decltype(*this)>(); - } - - void - execute(ExecUntilBreakOrContinue&) - { - m_node.m_value = *p_value; - } - - NameProcessor(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 BreakProcessor final : public INodeProcessor -{ - public: - std::string - describe() const - { - return demangle<decltype(*this)>(); - } - - void - execute(ExecUntilBreakOrContinue& exec_policy) - { - exec_policy = ExecUntilBreakOrContinue(ExecUntilBreakOrContinue::JumpType::break_jump); - } - - BreakProcessor() = default; -}; - -class ContinueProcessor final : public INodeProcessor -{ - public: - std::string - describe() const - { - return demangle<decltype(*this)>(); - } - - void - execute(ExecUntilBreakOrContinue& exec_policy) - { - exec_policy = ExecUntilBreakOrContinue(ExecUntilBreakOrContinue::JumpType::continue_jump); - } - - ContinueProcessor() = default; -}; - -class OStreamProcessor final : public INodeProcessor -{ - ASTNode& m_node; - std::ostream& m_os; - - public: - std::string - describe() const - { - return demangle<decltype(*this)>(); - } - - void - execute(ExecUntilBreakOrContinue& exec_policy) - { - for (size_t i = 0; i < m_node.children.size(); ++i) { - m_node.children[i]->execute(exec_policy); - std::visit( - [&](auto&& value) { - using ValueT = std::decay_t<decltype(value)>; - if constexpr (not std::is_same_v<std::monostate, ValueT>) { - if constexpr (std::is_same_v<bool, ValueT>) { - m_os << std::boolalpha << value; - } else { - m_os << value; - } - } - }, - m_node.children[i]->m_value); - } - } - - OStreamProcessor(ASTNode& node, std::ostream& os) : m_node{node}, m_os(os) - { - ; - } -}; +#include <PEGGrammar.hpp> void ASTNodeExpressionBuilder::_buildExpression(ASTNode& n) diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt index 7b440e23e..9910dd470 100644 --- a/src/language/CMakeLists.txt +++ b/src/language/CMakeLists.txt @@ -3,6 +3,8 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) # ------------------- Source files -------------------- +add_subdirectory(node_processor) + add_library( PugsLanguage ASTBuilder.cpp @@ -24,8 +26,6 @@ add_library( ASTSymbolInitializationChecker.cpp PugsParser.cpp) -#include_directories(${PUGS_SOURCE_DIR}/utils) - # Additional dependencies add_dependencies(PugsLanguage PugsUtils) diff --git a/src/language/node_processor/ASTNodeListProcessor.hpp b/src/language/node_processor/ASTNodeListProcessor.hpp new file mode 100644 index 000000000..0eb6590b5 --- /dev/null +++ b/src/language/node_processor/ASTNodeListProcessor.hpp @@ -0,0 +1,30 @@ +#ifndef AST_NODE_LIST_PROCESSOR_HPP +#define AST_NODE_LIST_PROCESSOR_HPP + +#include <node_processor/INodeProcessor.hpp> + +#include <Demangle.hpp> + +class ASTNodeListProcessor final : public INodeProcessor +{ + ASTNode& m_node; + + public: + std::string + describe() const + { + return demangle<decltype(*this)>(); + } + + void + execute(ExecUntilBreakOrContinue& exec_policy) + { + for (auto& child : m_node.children) { + child->execute(exec_policy); + } + } + + ASTNodeListProcessor(ASTNode& node) : m_node{node} {} +}; + +#endif // AST_NODE_LIST_PROCESSOR_HPP diff --git a/src/language/node_processor/BreakProcessor.hpp b/src/language/node_processor/BreakProcessor.hpp new file mode 100644 index 000000000..7046f2342 --- /dev/null +++ b/src/language/node_processor/BreakProcessor.hpp @@ -0,0 +1,26 @@ +#ifndef BREAK_PROCESSOR_HPP +#define BREAK_PROCESSOR_HPP + +#include <node_processor/INodeProcessor.hpp> + +#include <Demangle.hpp> + +class BreakProcessor final : public INodeProcessor +{ + public: + std::string + describe() const + { + return demangle<decltype(*this)>(); + } + + void + execute(ExecUntilBreakOrContinue& exec_policy) + { + exec_policy = ExecUntilBreakOrContinue(ExecUntilBreakOrContinue::JumpType::break_jump); + } + + BreakProcessor() = default; +}; + +#endif // BREAK_PROCESSOR_HPP diff --git a/src/language/node_processor/CMakeLists.txt b/src/language/node_processor/CMakeLists.txt new file mode 100644 index 000000000..adc3b3876 --- /dev/null +++ b/src/language/node_processor/CMakeLists.txt @@ -0,0 +1,5 @@ +# ------------------- Source files -------------------- + +#add_library( +# PugsLanguageNodeProcessor +#) diff --git a/src/language/node_processor/ContinueProcessor.hpp b/src/language/node_processor/ContinueProcessor.hpp new file mode 100644 index 000000000..c3185da9d --- /dev/null +++ b/src/language/node_processor/ContinueProcessor.hpp @@ -0,0 +1,26 @@ +#ifndef CONTINUE_PROCESSOR_HPP +#define CONTINUE_PROCESSOR_HPP + +#include <node_processor/INodeProcessor.hpp> + +#include <Demangle.hpp> + +class ContinueProcessor final : public INodeProcessor +{ + public: + std::string + describe() const + { + return demangle<decltype(*this)>(); + } + + void + execute(ExecUntilBreakOrContinue& exec_policy) + { + exec_policy = ExecUntilBreakOrContinue(ExecUntilBreakOrContinue::JumpType::continue_jump); + } + + ContinueProcessor() = default; +}; + +#endif // CONTINUE_PROCESSOR_HPP diff --git a/src/language/node_processor/DoWhileProcessor.hpp b/src/language/node_processor/DoWhileProcessor.hpp new file mode 100644 index 000000000..52961c306 --- /dev/null +++ b/src/language/node_processor/DoWhileProcessor.hpp @@ -0,0 +1,50 @@ +#ifndef DO_WHILE_PROCESSOR_HPP +#define DO_WHILE_PROCESSOR_HPP + +#include <node_processor/INodeProcessor.hpp> + +#include <Demangle.hpp> + +class DoWhileProcessor final : public INodeProcessor +{ + ASTNode& m_node; + + public: + std::string + describe() const + { + return demangle<decltype(*this)>(); + } + + void + execute(ExecUntilBreakOrContinue& exec_policy) + { + bool continuation_test = true; + ExecUntilBreakOrContinue exec_until_jump; + do { + m_node.children[0]->execute(exec_until_jump); + if (not exec_until_jump.exec()) { + if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::break_jump) { + break; + } else if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::continue_jump) { + exec_until_jump = ExecUntilBreakOrContinue{}; // getting ready for next loop traversal + } + } + m_node.children[1]->execute(exec_policy); + continuation_test = static_cast<bool>(std::visit( + [](const auto& value) -> bool { + using T = std::decay_t<decltype(value)>; + if constexpr (std::is_arithmetic_v<T>) { + return value; + } else { + return false; + } + }, + m_node.children[1]->m_value)); + } while (continuation_test); + } + + DoWhileProcessor(ASTNode& node) : m_node{node} {} +}; + +#endif // DO_WHILE_PROCESSOR_HPP diff --git a/src/language/ExecUntilBreakOrContinue.hpp b/src/language/node_processor/ExecUntilBreakOrContinue.hpp similarity index 100% rename from src/language/ExecUntilBreakOrContinue.hpp rename to src/language/node_processor/ExecUntilBreakOrContinue.hpp diff --git a/src/language/node_processor/FakeProcessor.hpp b/src/language/node_processor/FakeProcessor.hpp new file mode 100644 index 000000000..4eb170cbd --- /dev/null +++ b/src/language/node_processor/FakeProcessor.hpp @@ -0,0 +1,27 @@ +#ifndef FAKE_PROCESSOR_HPP +#define FAKE_PROCESSOR_HPP + +#include <node_processor/INodeProcessor.hpp> + +#include <Demangle.hpp> + +class FakeProcessor final : public INodeProcessor +{ + public: + std::string + describe() const + { + return demangle<decltype(*this)>(); + } + + PUGS_INLINE + void + execute(ExecUntilBreakOrContinue&) + { + ; + } + + FakeProcessor() = default; +}; + +#endif // FAKE_PROCESSOR_HPP diff --git a/src/language/node_processor/ForProcessor.hpp b/src/language/node_processor/ForProcessor.hpp new file mode 100644 index 000000000..a342a45d6 --- /dev/null +++ b/src/language/node_processor/ForProcessor.hpp @@ -0,0 +1,53 @@ +#ifndef FOR_PROCESSOR_HPP +#define FOR_PROCESSOR_HPP + +#include <node_processor/INodeProcessor.hpp> + +#include <Demangle.hpp> + +class ForProcessor final : public INodeProcessor +{ + ASTNode& m_node; + + public: + std::string + describe() const + { + return demangle<decltype(*this)>(); + } + + void + execute(ExecUntilBreakOrContinue& exec_policy) + { + ExecUntilBreakOrContinue exec_until_jump; + m_node.children[0]->execute(exec_policy); + while ([&]() { + m_node.children[1]->execute(exec_policy); + return static_cast<bool>(std::visit( + [](const auto& value) -> bool { + using T = std::decay_t<decltype(value)>; + if constexpr (std::is_arithmetic_v<T>) { + return value; + } else { + return false; + } + }, + m_node.children[1]->m_value)); + }()) { + m_node.children[3]->execute(exec_until_jump); + if (not exec_until_jump.exec()) { + if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::break_jump) { + break; + } else if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::continue_jump) { + exec_until_jump = ExecUntilBreakOrContinue{}; // getting ready for next loop traversal + } + } + + m_node.children[2]->execute(exec_policy); + } + } + + ForProcessor(ASTNode& node) : m_node{node} {} +}; + +#endif // FOR_PROCESSOR_HPP diff --git a/src/language/INodeProcessor.hpp b/src/language/node_processor/INodeProcessor.hpp similarity index 87% rename from src/language/INodeProcessor.hpp rename to src/language/node_processor/INodeProcessor.hpp index c664d57d9..361565105 100644 --- a/src/language/INodeProcessor.hpp +++ b/src/language/node_processor/INodeProcessor.hpp @@ -1,7 +1,7 @@ #ifndef I_NODE_PROCESSOR_HPP #define I_NODE_PROCESSOR_HPP -#include <ExecUntilBreakOrContinue.hpp> +#include <node_processor/ExecUntilBreakOrContinue.hpp> #include <string> diff --git a/src/language/node_processor/IfProcessor.hpp b/src/language/node_processor/IfProcessor.hpp new file mode 100644 index 000000000..60dabe8da --- /dev/null +++ b/src/language/node_processor/IfProcessor.hpp @@ -0,0 +1,48 @@ +#ifndef IF_PROCESSOR_HPP +#define IF_PROCESSOR_HPP + +#include <node_processor/INodeProcessor.hpp> + +#include <Demangle.hpp> + +class IfProcessor final : public INodeProcessor +{ + ASTNode& m_node; + + public: + std::string + describe() const + { + return demangle<decltype(*this)>(); + } + + void + execute(ExecUntilBreakOrContinue& exec_policy) + { + m_node.children[0]->execute(exec_policy); + const bool is_true = static_cast<bool>(std::visit( + [](const auto& value) -> bool { + using T = std::decay_t<decltype(value)>; + if constexpr (std::is_arithmetic_v<T>) { + return value; + } else { + return false; + } + }, + m_node.children[0]->m_value)); + if (is_true) { + Assert(m_node.children[1] != nullptr); + m_node.children[1]->execute(exec_policy); + } else { + if (m_node.children.size() == 3) { + // else statement + Assert(m_node.children[2] != nullptr); + m_node.children[2]->execute(exec_policy); + } + } + } + + IfProcessor(ASTNode& node) : m_node{node} {} +}; + +#endif // IF_PROCESSOR_HPP diff --git a/src/language/node_processor/NameProcessor.hpp b/src/language/node_processor/NameProcessor.hpp new file mode 100644 index 000000000..9da2b5b49 --- /dev/null +++ b/src/language/node_processor/NameProcessor.hpp @@ -0,0 +1,37 @@ +#ifndef NODE_PROCESSOR_HPP +#define NODE_PROCESSOR_HPP + +#include <node_processor/INodeProcessor.hpp> + +#include <Demangle.hpp> + +#include <SymbolTable.hpp> + +class NameProcessor final : public INodeProcessor +{ + ASTNode& m_node; + ASTNodeDataVariant* p_value{nullptr}; + + public: + std::string + describe() const + { + return demangle<decltype(*this)>(); + } + + void + execute(ExecUntilBreakOrContinue&) + { + m_node.m_value = *p_value; + } + + NameProcessor(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()); + } +}; + +#endif // NODE_PROCESSOR_HPP diff --git a/src/language/node_processor/OStreamProcessor.hpp b/src/language/node_processor/OStreamProcessor.hpp new file mode 100644 index 000000000..752b97650 --- /dev/null +++ b/src/language/node_processor/OStreamProcessor.hpp @@ -0,0 +1,46 @@ +#ifndef OSTREAM_PROCESSOR_HPP +#define OSTREAM_PROCESSOR_HPP + +#include <node_processor/INodeProcessor.hpp> + +#include <Demangle.hpp> + +class OStreamProcessor final : public INodeProcessor +{ + ASTNode& m_node; + std::ostream& m_os; + + public: + std::string + describe() const + { + return demangle<decltype(*this)>(); + } + + void + execute(ExecUntilBreakOrContinue& exec_policy) + { + for (size_t i = 0; i < m_node.children.size(); ++i) { + m_node.children[i]->execute(exec_policy); + std::visit( + [&](auto&& value) { + using ValueT = std::decay_t<decltype(value)>; + if constexpr (not std::is_same_v<std::monostate, ValueT>) { + if constexpr (std::is_same_v<bool, ValueT>) { + m_os << std::boolalpha << value; + } else { + m_os << value; + } + } + }, + m_node.children[i]->m_value); + } + } + + OStreamProcessor(ASTNode& node, std::ostream& os) : m_node{node}, m_os(os) + { + ; + } +}; + +#endif // OSTREAM_PROCESSOR_HPP diff --git a/src/language/node_processor/WhileProcessor.hpp b/src/language/node_processor/WhileProcessor.hpp new file mode 100644 index 000000000..ffa877e9e --- /dev/null +++ b/src/language/node_processor/WhileProcessor.hpp @@ -0,0 +1,50 @@ +#ifndef WHILE_PROCESSOR_HPP +#define WHILE_PROCESSOR_HPP + +#include <node_processor/INodeProcessor.hpp> + +#include <Demangle.hpp> + +class WhileProcessor final : public INodeProcessor +{ + ASTNode& m_node; + + public: + std::string + describe() const + { + return demangle<decltype(*this)>(); + } + + void + execute(ExecUntilBreakOrContinue& exec_policy) + { + ExecUntilBreakOrContinue exec_until_jump; + while ([&]() { + m_node.children[0]->execute(exec_policy); + return static_cast<bool>(std::visit( + [](const auto& value) -> bool { + using T = std::decay_t<decltype(value)>; + if constexpr (std::is_arithmetic_v<T>) { + return value; + } else { + return false; + } + }, + m_node.children[0]->m_value)); + }()) { + m_node.children[1]->execute(exec_until_jump); + if (not exec_until_jump.exec()) { + if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::break_jump) { + break; + } else if (exec_until_jump.jumpType() == ExecUntilBreakOrContinue::JumpType::continue_jump) { + exec_until_jump = ExecUntilBreakOrContinue{}; // getting ready for next loop traversal + } + } + } + } + + WhileProcessor(ASTNode& node) : m_node{node} {} +}; + +#endif // WHILE_PROCESSOR_HPP -- GitLab