diff --git a/src/language/ASTNodeListAffectationExpressionBuilder.cpp b/src/language/ASTNodeListAffectationExpressionBuilder.cpp index a39f53c6a2f7f8adfbdd4a0177d49ee428f57155..3f88ad804702c7094ef90baa307bbc2dad726d75 100644 --- a/src/language/ASTNodeListAffectationExpressionBuilder.cpp +++ b/src/language/ASTNodeListAffectationExpressionBuilder.cpp @@ -46,6 +46,12 @@ ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor( using ValueT = std::decay_t<decltype(value)>; if (node_sub_data_type.m_data_type.dimension() == value.dimension()) { list_affectation_processor->template add<ValueT, ValueT>(value_node); + } else if (node_sub_data_type.m_parent_node.is_type<language::integer>()) { + if (std::stoi(node_sub_data_type.m_parent_node.string()) == 0) { + list_affectation_processor->template add<ValueT, ZeroType>(value_node); + } else { + throw parse_error("invalid operand value", std::vector{node_sub_data_type.m_parent_node.begin()}); + } } else { throw parse_error("invalid dimension", std::vector{node_sub_data_type.m_parent_node.begin()}); } @@ -89,8 +95,6 @@ ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor( auto add_affectation_processor_for_value = [&](const ASTNodeDataType& value_type, const ASTNodeSubDataType& node_sub_data_type) { - ASTNodeNaturalConversionChecker{node_sub_data_type.m_parent_node, node_sub_data_type.m_data_type, value_type}; - switch (value_type) { case ASTNodeDataType::bool_t: { add_affectation_processor_for_data(bool{}, node_sub_data_type); @@ -141,6 +145,41 @@ ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor( } }; + if (value_node.m_data_type == ASTNodeDataType::vector_t) { + // Only real data are considered + const ASTNode& data_node = rhs_node_sub_data_type.m_parent_node; + switch (data_node.m_data_type) { + case ASTNodeDataType::list_t: { + if (data_node.children.size() != value_node.m_data_type.dimension()) { + throw parse_error("incompatible dimensions in affectation", std::vector{value_node.begin()}); + } + for (const auto& child : data_node.children) { + ASTNodeNaturalConversionChecker{rhs_node_sub_data_type.m_parent_node, child->m_data_type, + ASTNodeDataType::double_t}; + } + + break; + } + case ASTNodeDataType::vector_t: { + if (data_node.m_data_type.dimension() != value_node.m_data_type.dimension()) { + throw parse_error("incompatible dimensions in affectation", std::vector{value_node.begin()}); + } + break; + } + case ASTNodeDataType::int_t: { + // Nothing to check by now since the special value 0 is allowed + break; + } + default: { + ASTNodeNaturalConversionChecker{rhs_node_sub_data_type.m_parent_node, rhs_node_sub_data_type.m_data_type, + value_node.m_data_type}; + } + } + } else { + ASTNodeNaturalConversionChecker{rhs_node_sub_data_type.m_parent_node, rhs_node_sub_data_type.m_data_type, + value_node.m_data_type}; + } + add_affectation_processor_for_value(value_node.m_data_type, rhs_node_sub_data_type); } diff --git a/src/language/node_processor/AffectationProcessor.hpp b/src/language/node_processor/AffectationProcessor.hpp index dec7f5b5490f9ea354552192d9ab1d29ede3bef9..c9e91663f77dbf9af99815202a21118877562e7a 100644 --- a/src/language/node_processor/AffectationProcessor.hpp +++ b/src/language/node_processor/AffectationProcessor.hpp @@ -88,31 +88,35 @@ class AffectationExecutor final : public IAffectationExecutor affect(ExecutionPolicy&, DataVariant&& rhs) { if constexpr (_is_defined) { - if constexpr (std::is_same_v<ValueT, std::string>) { - if constexpr (std::is_same_v<OperatorT, language::eq_op>) { - if constexpr (std::is_same_v<std::string, DataT>) { - m_lhs = std::get<DataT>(rhs); + if constexpr (not std::is_same_v<DataT, ZeroType>) { + if constexpr (std::is_same_v<ValueT, std::string>) { + if constexpr (std::is_same_v<OperatorT, language::eq_op>) { + if constexpr (std::is_same_v<std::string, DataT>) { + m_lhs = std::get<DataT>(rhs); + } else { + m_lhs = std::to_string(std::get<DataT>(rhs)); + } } else { - m_lhs = std::to_string(std::get<DataT>(rhs)); + static_assert(std::is_same_v<OperatorT, language::pluseq_op>, "unexpected operator type"); + if constexpr (std::is_same_v<std::string, DataT>) { + m_lhs += std::get<std::string>(rhs); + } else { + m_lhs += std::to_string(std::get<DataT>(rhs)); + } } } else { - static_assert(std::is_same_v<OperatorT, language::pluseq_op>, "unexpected operator type"); - if constexpr (std::is_same_v<std::string, DataT>) { - m_lhs += std::get<std::string>(rhs); - } else { - m_lhs += std::to_string(std::get<DataT>(rhs)); - } - } - } else { - if constexpr (std::is_same_v<OperatorT, language::eq_op>) { - if constexpr (std::is_same_v<ValueT, DataT>) { - m_lhs = std::get<DataT>(rhs); + if constexpr (std::is_same_v<OperatorT, language::eq_op>) { + if constexpr (std::is_same_v<ValueT, DataT>) { + m_lhs = std::get<DataT>(rhs); + } else { + m_lhs = static_cast<ValueT>(std::get<DataT>(rhs)); + } } else { - m_lhs = static_cast<ValueT>(std::get<DataT>(rhs)); + AffOp<OperatorT>().eval(m_lhs, std::get<DataT>(rhs)); } - } else { - AffOp<OperatorT>().eval(m_lhs, std::get<DataT>(rhs)); } + } else if (std::is_same_v<OperatorT, language::eq_op>) { + m_lhs = ValueT{zero}; } } }