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
No related branches found
No related tags found
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