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

Apply same strategy to unary operators

parent 677ff496
Branches
Tags
1 merge request!37Feature/language
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <ASTNodeAffectationExpressionBuilder.hpp> #include <ASTNodeAffectationExpressionBuilder.hpp>
#include <ASTNodeBinaryOperatorExpressionBuilder.hpp> #include <ASTNodeBinaryOperatorExpressionBuilder.hpp>
#include <ASTNodeIncDecExpressionBuilder.hpp> #include <ASTNodeIncDecExpressionBuilder.hpp>
#include <ASTNodeUnaryOperatorExpressionBuilder.hpp>
#include <PEGGrammar.hpp> #include <PEGGrammar.hpp>
#include <SymbolTable.hpp> #include <SymbolTable.hpp>
...@@ -38,54 +39,6 @@ class NoProcess final : public INodeProcessor ...@@ -38,54 +39,6 @@ class NoProcess final : public INodeProcessor
} }
}; };
template <typename Op>
struct UnaryOp;
template <>
struct UnaryOp<language::unary_minus>
{
template <typename A>
PUGS_INLINE A
eval(const A& a)
{
return -a;
}
};
template <>
struct UnaryOp<language::unary_not>
{
template <typename A>
PUGS_INLINE bool
eval(const A& a)
{
return not a;
}
};
template <typename UnaryOpT, typename ValueT, typename DataT>
class UnaryExpressionProcessor final : public INodeProcessor
{
Node& m_node;
public:
PUGS_INLINE ValueT
eval(const DataVariant& a)
{
return UnaryOp<UnaryOpT>().eval(std::get<DataT>(a));
}
public:
UnaryExpressionProcessor(Node& node) : m_node{node} {}
void
execute(ExecUntilBreakOrContinue& exec_policy)
{
m_node.children[0]->execute(exec_policy);
m_node.m_value = eval(m_node.children[0]->m_value);
}
};
class IfStatement final : public INodeProcessor class IfStatement final : public INodeProcessor
{ {
Node& m_node; Node& m_node;
...@@ -313,61 +266,6 @@ namespace internal ...@@ -313,61 +266,6 @@ namespace internal
void void
build_node_type(Node& n) build_node_type(Node& n)
{ {
auto set_unary_operator_processor = [](Node& n, const auto& operator_v) {
auto set_unary_operator_processor_for_data = [&](const auto& value, const DataType& data_type) {
using OperatorT = std::decay_t<decltype(operator_v)>;
using ValueT = std::decay_t<decltype(value)>;
switch (data_type) {
case DataType::bool_t: {
n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, bool>>(n);
break;
}
case DataType::unsigned_int_t: {
n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, uint64_t>>(n);
break;
}
case DataType::int_t: {
n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, int64_t>>(n);
break;
}
case DataType::double_t: {
n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, double>>(n);
break;
}
default: {
throw parse_error("undefined operand type for unary operator", std::vector{n.children[0]->begin()});
}
}
};
auto set_unary_operator_processor_for_value = [&](const DataType& value_type) {
const DataType data_type = n.children[0]->m_data_type;
switch (value_type) {
case DataType::bool_t: {
set_unary_operator_processor_for_data(bool{}, data_type);
break;
}
case DataType::unsigned_int_t: {
set_unary_operator_processor_for_data(uint64_t{}, data_type);
break;
}
case DataType::int_t: {
set_unary_operator_processor_for_data(int64_t{}, data_type);
break;
}
case DataType::double_t: {
set_unary_operator_processor_for_data(double{}, data_type);
break;
}
default: {
throw parse_error("undefined value type for unary operator", std::vector{n.begin()});
}
}
};
set_unary_operator_processor_for_value(n.m_data_type);
};
if (n.is_root() or n.is<language::bloc>()) { if (n.is_root() or n.is<language::bloc>()) {
n.m_node_processor = std::make_unique<NodeList>(n); n.m_node_processor = std::make_unique<NodeList>(n);
} else if (n.is<language::declaration>()) { } else if (n.is<language::declaration>()) {
...@@ -386,10 +284,8 @@ build_node_type(Node& n) ...@@ -386,10 +284,8 @@ build_node_type(Node& n)
} else if (n.is<language::name>()) { } else if (n.is<language::name>()) {
n.m_node_processor = std::make_unique<NameExpression>(n); n.m_node_processor = std::make_unique<NameExpression>(n);
} else if (n.is<language::unary_minus>()) { } else if (n.is<language::unary_minus>() or n.is<language::unary_not>()) {
set_unary_operator_processor(n, language::unary_minus{}); ASTNodeUnaryOperatorExpressionBuilder{n};
} else if (n.is<language::unary_not>()) {
set_unary_operator_processor(n, language::unary_not{});
} else if (n.is<language::unary_minusminus>() or n.is<language::unary_plusplus>() or } else if (n.is<language::unary_minusminus>() or n.is<language::unary_plusplus>() or
n.is<language::post_minusminus>() or n.is<language::post_plusplus>()) { n.is<language::post_minusminus>() or n.is<language::post_plusplus>()) {
......
#include <ASTNodeUnaryOperatorExpressionBuilder.hpp>
#include <PEGGrammar.hpp>
#include <SymbolTable.hpp>
namespace language
{
template <typename Op>
struct UnaryOp;
template <>
struct UnaryOp<language::unary_minus>
{
template <typename A>
PUGS_INLINE A
eval(const A& a)
{
return -a;
}
};
template <>
struct UnaryOp<language::unary_not>
{
template <typename A>
PUGS_INLINE bool
eval(const A& a)
{
return not a;
}
};
template <typename UnaryOpT, typename ValueT, typename DataT>
class UnaryExpressionProcessor final : public INodeProcessor
{
Node& m_node;
public:
PUGS_INLINE ValueT
eval(const DataVariant& a)
{
return UnaryOp<UnaryOpT>().eval(std::get<DataT>(a));
}
public:
UnaryExpressionProcessor(Node& node) : m_node{node} {}
void
execute(ExecUntilBreakOrContinue& exec_policy)
{
m_node.children[0]->execute(exec_policy);
m_node.m_value = eval(m_node.children[0]->m_value);
}
};
ASTNodeUnaryOperatorExpressionBuilder::ASTNodeUnaryOperatorExpressionBuilder(Node& n)
{
auto set_unary_operator_processor = [](Node& n, const auto& operator_v) {
auto set_unary_operator_processor_for_data = [&](const auto& value, const DataType& data_type) {
using OperatorT = std::decay_t<decltype(operator_v)>;
using ValueT = std::decay_t<decltype(value)>;
switch (data_type) {
case DataType::bool_t: {
n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, bool>>(n);
break;
}
case DataType::unsigned_int_t: {
n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, uint64_t>>(n);
break;
}
case DataType::int_t: {
n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, int64_t>>(n);
break;
}
case DataType::double_t: {
n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, double>>(n);
break;
}
default: {
throw parse_error("undefined operand type for unary operator", std::vector{n.children[0]->begin()});
}
}
};
auto set_unary_operator_processor_for_value = [&](const DataType& value_type) {
const DataType data_type = n.children[0]->m_data_type;
switch (value_type) {
case DataType::bool_t: {
set_unary_operator_processor_for_data(bool{}, data_type);
break;
}
case DataType::unsigned_int_t: {
set_unary_operator_processor_for_data(uint64_t{}, data_type);
break;
}
case DataType::int_t: {
set_unary_operator_processor_for_data(int64_t{}, data_type);
break;
}
case DataType::double_t: {
set_unary_operator_processor_for_data(double{}, data_type);
break;
}
default: {
throw parse_error("undefined value type for unary operator", std::vector{n.begin()});
}
}
};
set_unary_operator_processor_for_value(n.m_data_type);
};
if (n.is<language::unary_minus>()) {
set_unary_operator_processor(n, language::unary_minus{});
} else if (n.is<language::unary_not>()) {
set_unary_operator_processor(n, language::unary_not{});
} else {
throw parse_error("unexpected error: undefined unary operator", std::vector{n.begin()});
}
}
} // namespace language
#ifndef AST_NODE_UNARY_OPERATOR_EXPRESSION_BUILDER_HPP
#define AST_NODE_UNARY_OPERATOR_EXPRESSION_BUILDER_HPP
#include <ASTNode.hpp>
namespace language
{
struct ASTNodeUnaryOperatorExpressionBuilder
{
ASTNodeUnaryOperatorExpressionBuilder(Node& node);
};
} // namespace language
#endif // AST_NODE_UNARY_OPERATOR_EXPRESSION_BUILDER_HPP
...@@ -11,6 +11,7 @@ add_library( ...@@ -11,6 +11,7 @@ add_library(
ASTNodeBinaryOperatorExpressionBuilder.cpp ASTNodeBinaryOperatorExpressionBuilder.cpp
ASTNodeExpressionBuilder.cpp ASTNodeExpressionBuilder.cpp
ASTNodeIncDecExpressionBuilder.cpp ASTNodeIncDecExpressionBuilder.cpp
ASTNodeUnaryOperatorExpressionBuilder.cpp
PugsParser.cpp) PugsParser.cpp)
#include_directories(${PUGS_SOURCE_DIR}/utils) #include_directories(${PUGS_SOURCE_DIR}/utils)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment