From fe5963c7fc79cfe4c4f4de5a171ea27d67095505 Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Wed, 5 Feb 2020 19:26:19 +0100 Subject: [PATCH] Finish list affectation containing R^d by 0 Now it is possible to write `` R^3 x=(1,2,3); R^2 y=(1,3); R z = 2; (x, z, y) = (0, 3, 0); `` This will lead to the final values: `x==(0,0,0)`, `y==(0,0)` and `z==3` Remember that the only valid **N** value in such instruction is `0`. --- ...STNodeListAffectationExpressionBuilder.cpp | 43 ++++++++++++++++++- .../node_processor/AffectationProcessor.hpp | 42 ++++++++++-------- 2 files changed, 64 insertions(+), 21 deletions(-) diff --git a/src/language/ASTNodeListAffectationExpressionBuilder.cpp b/src/language/ASTNodeListAffectationExpressionBuilder.cpp index a39f53c6a..3f88ad804 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 dec7f5b54..c9e91663f 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}; } } } -- GitLab