#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()}); } }