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

Change binary operator processors

Following what was done for unary operators, types are now resolved when AST is built
parent c31f5040
No related branches found
No related tags found
1 merge request!37Feature/language
......@@ -943,59 +943,19 @@ struct BinOp<language::divide_op>
}
};
template <typename BinaryOpT>
class BinaryExpression final : public INodeProcessor
template <typename BinaryOpT, typename ValueT, typename A_DataT, typename B_DataT>
class BinaryExpressionProcessor final : public INodeProcessor
{
Node& m_node;
template <typename op, typename A, typename B>
auto
eval(const BinOp<op>& bin_op, const A& a, const B& b)
{
return bin_op.eval(a, b);
}
template <typename CastType, typename op>
CastType
PUGS_INLINE ValueT
eval(const DataVariant& a, const DataVariant& b)
{
return std::visit(
[](const auto& a, const auto& b) -> double {
using A = std::decay_t<decltype(a)>;
using B = std::decay_t<decltype(b)>;
if constexpr ((std::is_same_v<A, std::monostate>) or (std::is_same_v<B, std::monostate>)) {
return 0;
} else {
return BinOp<op>().eval(a, b);
}
},
a, b);
}
template <typename op>
void
eval_node_op(Node& n, const DataVariant& a, const DataVariant& b)
{
switch (n.m_data_type) {
case DataType::double_t: {
n.m_value = eval<double, op>(a, b);
break;
}
case DataType::int_t: {
n.m_value = eval<int64_t, op>(a, b);
break;
}
case DataType::bool_t: {
n.m_value = eval<bool, op>(a, b);
break;
}
default: {
throw parse_error("unknown operation type", std::vector{n.begin()});
}
}
return BinOp<BinaryOpT>().eval(std::get<A_DataT>(a), std::get<B_DataT>(b));
}
public:
BinaryExpression(Node& node) : m_node{node} {}
BinaryExpressionProcessor(Node& node) : m_node{node} {}
void
execute(ExecUntilBreakOrContinue& exec_policy)
......@@ -1003,7 +963,7 @@ class BinaryExpression final : public INodeProcessor
m_node.children[0]->execute(exec_policy);
m_node.children[1]->execute(exec_policy);
eval_node_op<BinaryOpT>(m_node, m_node.children[0]->m_value, m_node.children[1]->m_value);
m_node.m_value = eval(m_node.children[0]->m_value, m_node.children[1]->m_value);
}
};
......@@ -1203,24 +1163,24 @@ void
build_node_type(Node& n)
{
auto set_unary_operator_processor = [](Node& n, const auto& operator_v) {
auto set_unary_operator_processor_for_data = [&](const DataType& data_type, const auto& value) {
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, bool, ValueT>>(n);
n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, bool>>(n);
break;
}
case DataType::int_t: {
n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, int64_t, ValueT>>(n);
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, double, ValueT>>(n);
n.m_node_processor = std::make_unique<UnaryExpressionProcessor<OperatorT, ValueT, double>>(n);
break;
}
default: {
throw parse_error("undefined operand type for unary minus", std::vector{n.begin()});
throw parse_error("undefined operand type for unary operator", std::vector{n.children[0]->begin()});
}
}
};
......@@ -1229,19 +1189,19 @@ build_node_type(Node& n)
const DataType data_type = n.children[0]->m_data_type;
switch (value_type) {
case DataType::bool_t: {
set_unary_operator_processor_for_data(data_type, bool{});
set_unary_operator_processor_for_data(bool{}, data_type);
break;
}
case DataType::int_t: {
set_unary_operator_processor_for_data(data_type, int64_t{});
set_unary_operator_processor_for_data(int64_t{}, data_type);
break;
}
case DataType::double_t: {
set_unary_operator_processor_for_data(data_type, double{});
set_unary_operator_processor_for_data(double{}, data_type);
break;
}
default: {
throw parse_error("undefined operand type for unary minus", std::vector{n.children[0]->begin()});
throw parse_error("undefined value type for unary operator", std::vector{n.begin()});
}
}
};
......@@ -1249,6 +1209,75 @@ build_node_type(Node& n)
set_unary_operator_processor_for_value(n.m_data_type);
};
auto set_binary_operator_processor = [](Node& n, const auto& operator_v) {
auto set_binary_operator_processor_for_data_b = [&](const auto value, const auto data_a,
const DataType& data_type_b) {
using OperatorT = std::decay_t<decltype(operator_v)>;
using ValueT = std::decay_t<decltype(value)>;
using DataTA = std::decay_t<decltype(data_a)>;
switch (data_type_b) {
case DataType::bool_t: {
n.m_node_processor = std::make_unique<BinaryExpressionProcessor<OperatorT, ValueT, DataTA, bool>>(n);
break;
}
case DataType::int_t: {
n.m_node_processor = std::make_unique<BinaryExpressionProcessor<OperatorT, ValueT, DataTA, int64_t>>(n);
break;
}
case DataType::double_t: {
n.m_node_processor = std::make_unique<BinaryExpressionProcessor<OperatorT, ValueT, DataTA, double>>(n);
break;
}
default: {
throw parse_error("undefined operand type for binary operator", std::vector{n.children[1]->begin()});
}
}
};
auto set_binary_operator_processor_for_data_a = [&](const auto value, const DataType& data_type_a) {
switch (data_type_a) {
case DataType::bool_t: {
set_binary_operator_processor_for_data_b(value, bool{}, data_type_a);
break;
}
case DataType::int_t: {
set_binary_operator_processor_for_data_b(value, int64_t{}, data_type_a);
break;
}
case DataType::double_t: {
set_binary_operator_processor_for_data_b(value, double{}, data_type_a);
break;
}
default: {
throw parse_error("undefined operand type for binary operator", std::vector{n.children[0]->begin()});
}
}
};
auto set_binary_operator_processor_for_value = [&](const DataType& value_type) {
const DataType data_type_a = n.children[0]->m_data_type;
switch (value_type) {
case DataType::bool_t: {
set_binary_operator_processor_for_data_a(bool{}, data_type_a);
break;
}
case DataType::int_t: {
set_binary_operator_processor_for_data_a(int64_t{}, data_type_a);
break;
}
case DataType::double_t: {
set_binary_operator_processor_for_data_a(double{}, data_type_a);
break;
}
default: {
throw parse_error("undefined value type for binary operator", std::vector{n.begin()});
}
}
};
set_binary_operator_processor_for_value(n.m_data_type);
};
if (n.is_root()) {
n.m_node_processor = std::make_unique<NodeList>(n);
} else if (n.is<language::bloc>()) {
......@@ -1287,29 +1316,29 @@ build_node_type(Node& n)
} else if (n.is<language::unary_not>()) {
set_unary_operator_processor(n, language::unary_not{});
} else if (n.is<language::multiply_op>()) {
n.m_node_processor = std::make_unique<BinaryExpression<language::multiply_op>>(n);
set_binary_operator_processor(n, language::multiply_op{});
} else if (n.is<language::divide_op>()) {
n.m_node_processor = std::make_unique<BinaryExpression<language::divide_op>>(n);
set_binary_operator_processor(n, language::divide_op{});
} else if (n.is<language::plus_op>()) {
n.m_node_processor = std::make_unique<BinaryExpression<language::plus_op>>(n);
set_binary_operator_processor(n, language::plus_op{});
} else if (n.is<language::minus_op>()) {
n.m_node_processor = std::make_unique<BinaryExpression<language::minus_op>>(n);
set_binary_operator_processor(n, language::minus_op{});
} else if (n.is<language::or_op>()) {
n.m_node_processor = std::make_unique<BinaryExpression<language::or_op>>(n);
set_binary_operator_processor(n, language::or_op{});
} else if (n.is<language::and_op>()) {
n.m_node_processor = std::make_unique<BinaryExpression<language::and_op>>(n);
set_binary_operator_processor(n, language::and_op{});
} else if (n.is<language::greater_op>()) {
n.m_node_processor = std::make_unique<BinaryExpression<language::greater_op>>(n);
set_binary_operator_processor(n, language::greater_op{});
} else if (n.is<language::greater_or_eq_op>()) {
n.m_node_processor = std::make_unique<BinaryExpression<language::greater_or_eq_op>>(n);
set_binary_operator_processor(n, language::greater_or_eq_op{});
} else if (n.is<language::lesser_op>()) {
n.m_node_processor = std::make_unique<BinaryExpression<language::lesser_op>>(n);
set_binary_operator_processor(n, language::lesser_op{});
} else if (n.is<language::lesser_or_eq_op>()) {
n.m_node_processor = std::make_unique<BinaryExpression<language::lesser_or_eq_op>>(n);
set_binary_operator_processor(n, language::lesser_or_eq_op{});
} else if (n.is<language::eq_op>()) {
n.m_node_processor = std::make_unique<BinaryExpression<language::eq_op>>(n);
set_binary_operator_processor(n, language::eq_op{});
} else if (n.is<language::not_eq_op>()) {
n.m_node_processor = std::make_unique<BinaryExpression<language::not_eq_op>>(n);
set_binary_operator_processor(n, language::not_eq_op{});
} else if (n.is<language::B_set>()) {
} else if (n.is<language::Z_set>()) {
} else if (n.is<language::R_set>()) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment