Skip to content
Snippets Groups Projects
Commit 3b753de7 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

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
parent 213fb495
No related branches found
No related tags found
1 merge request!37Feature/language
Showing
with 414 additions and 319 deletions
......@@ -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>
......
......@@ -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} {}
};
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;
};
#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 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)
......
......@@ -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)
#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
#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
# ------------------- Source files --------------------
#add_library(
# PugsLanguageNodeProcessor
#)
#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
#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
#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
#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
#ifndef I_NODE_PROCESSOR_HPP
#define I_NODE_PROCESSOR_HPP
#include <ExecUntilBreakOrContinue.hpp>
#include <node_processor/ExecUntilBreakOrContinue.hpp>
#include <string>
......
#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
#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
#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
#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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment