Select Git revision
Connectivity.hpp
ASTNodeListAffectationExpressionBuilder.cpp 5.36 KiB
#include <ASTNodeListAffectationExpressionBuilder.hpp>
#include <PEGGrammar.hpp>
#include <node_processor/AffectationProcessor.hpp>
#include <ASTNodeDataTypeFlattener.hpp>
template <typename OperatorT>
void
ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor(
const ASTNodeSubDataType& rhs_node_sub_data_type,
ASTNode& value_node,
std::unique_ptr<ListAffectationProcessor<OperatorT>>& list_affectation_processor)
{
auto add_affectation_processor_for_data = [&](const auto& value, const ASTNodeSubDataType& node_sub_data_type) {
using ValueT = std::decay_t<decltype(value)>;
switch (node_sub_data_type.m_data_type) {
case ASTNodeDataType::bool_t: {
list_affectation_processor->template add<ValueT, bool>(value_node);
break;
}
case ASTNodeDataType::unsigned_int_t: {
list_affectation_processor->template add<ValueT, uint64_t>(value_node);
break;
}
case ASTNodeDataType::int_t: {
list_affectation_processor->template add<ValueT, int64_t>(value_node);
break;
}
case ASTNodeDataType::double_t: {
list_affectation_processor->template add<ValueT, double>(value_node);
break;
}
default: {
throw parse_error("invalid operand type for affectation", std::vector{node_sub_data_type.m_parent_node.begin()});
}
}
};
auto add_affectation_processor_for_string_data = [&](const ASTNodeSubDataType& node_sub_data_type) {
if constexpr (std::is_same_v<OperatorT, language::eq_op> or std::is_same_v<OperatorT, language::pluseq_op>) {
switch (node_sub_data_type.m_data_type) {
case ASTNodeDataType::bool_t: {
list_affectation_processor->template add<std::string, bool>(value_node);
break;
}
case ASTNodeDataType::unsigned_int_t: {
list_affectation_processor->template add<std::string, uint64_t>(value_node);
break;
}
case ASTNodeDataType::int_t: {
list_affectation_processor->template add<std::string, int64_t>(value_node);
break;
}
case ASTNodeDataType::double_t: {
list_affectation_processor->template add<std::string, double>(value_node);
break;
}
case ASTNodeDataType::string_t: {
list_affectation_processor->template add<std::string, std::string>(value_node);
break;
}
default: {
throw parse_error("invalid operand type for string affectation",
std::vector{node_sub_data_type.m_parent_node.begin()});
}
}
} else {
throw parse_error("unexpected error: undefined operator type for string affectation",
std::vector{m_node.begin()});
}
};
auto add_affectation_processor_for_value = [&](const ASTNodeDataType& value_type,
const ASTNodeSubDataType& node_sub_data_type) {
switch (value_type) {
case ASTNodeDataType::bool_t: {
add_affectation_processor_for_data(bool{}, node_sub_data_type);
break;
}
case ASTNodeDataType::unsigned_int_t: {
add_affectation_processor_for_data(uint64_t{}, node_sub_data_type);
break;
}
case ASTNodeDataType::int_t: {
add_affectation_processor_for_data(int64_t{}, node_sub_data_type);
break;
}
case ASTNodeDataType::double_t: {
add_affectation_processor_for_data(double{}, node_sub_data_type);
break;
}
case ASTNodeDataType::string_t: {
add_affectation_processor_for_string_data(node_sub_data_type);
break;
}
default: {
throw parse_error("undefined value type for tuple affectation", std::vector{value_node.begin()});
}
}
};
add_affectation_processor_for_value(value_node.m_data_type, rhs_node_sub_data_type);
}
template <typename OperatorT>
void
ASTNodeListAffectationExpressionBuilder::_buildListAffectationProcessor()
{
Assert(m_node.children[1]->is_type<language::expression_list>() or
m_node.children[1]->is_type<language::function_evaluation>());
ASTNodeDataTypeFlattener::FlattenedDataTypeList flattened_rhs_data_type_list;
ASTNodeDataTypeFlattener{*m_node.children[1], flattened_rhs_data_type_list};
ASTNode& name_list_node = *m_node.children[0];
if (name_list_node.children.size() != flattened_rhs_data_type_list.size()) {
throw parse_error("incompatible list sizes in affectation", std::vector{m_node.begin()});
}
using ListAffectationProcessorT = ListAffectationProcessor<OperatorT>;
std::unique_ptr list_affectation_processor = std::make_unique<ListAffectationProcessorT>(m_node);
for (size_t i = 0; i < name_list_node.children.size(); ++i) {
ASTNode& name_node = *name_list_node.children[i];
this->_buildAffectationProcessor(flattened_rhs_data_type_list[i], name_node, list_affectation_processor);
}
m_node.m_node_processor = std::move(list_affectation_processor);
}
ASTNodeListAffectationExpressionBuilder::ASTNodeListAffectationExpressionBuilder(ASTNode& node) : m_node(node)
{
if (node.children[1]->is_type<language::expression_list>() or
node.children[1]->is_type<language::function_evaluation>()) {
if (node.is_type<language::eq_op>()) {
this->_buildListAffectationProcessor<language::eq_op>();
} else {
throw parse_error("undefined affectation operator for tuples", std::vector{node.begin()});
}
} else {
throw parse_error("invalid right hand side in tuple affectation", std::vector{node.children[1]->begin()});
}
}