From 8e5a94314f75949ff67a89cab77a610cb584633c Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Tue, 11 Feb 2020 17:40:24 +0100 Subject: [PATCH] Add missing tests for ASTNodeExpressionBuilder By the way fix a bunch of bugs related to R -> R^1 conversions. There are probably other bugs especially in the case of function whose args/return contain R^1. --- .../ASTNodeAffectationExpressionBuilder.cpp | 14 ++-- src/language/ASTNodeExpressionBuilder.cpp | 7 +- ...STNodeListAffectationExpressionBuilder.cpp | 35 +++++++--- tests/test_ASTNodeExpressionBuilder.cpp | 68 +++++++++++++++++++ 4 files changed, 107 insertions(+), 17 deletions(-) diff --git a/src/language/ASTNodeAffectationExpressionBuilder.cpp b/src/language/ASTNodeAffectationExpressionBuilder.cpp index 592c9295c..8c018fe3b 100644 --- a/src/language/ASTNodeAffectationExpressionBuilder.cpp +++ b/src/language/ASTNodeAffectationExpressionBuilder.cpp @@ -67,14 +67,20 @@ ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode } } case ASTNodeDataType::int_t: { - if (n.children[1]->is_type<language::integer>()) { + if constexpr (std::is_same_v<ValueT, TinyVector<1>>) { + if (n.children[1]->is_type<language::integer>()) { + if (std::stoi(n.children[1]->string()) == 0) { + n.m_node_processor = std::make_unique<AffectationFromZeroProcessor<ValueT>>(n); + break; + } + } + n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, int64_t>>(n); + break; + } else if (n.children[1]->is_type<language::integer>()) { if (std::stoi(n.children[1]->string()) == 0) { n.m_node_processor = std::make_unique<AffectationFromZeroProcessor<ValueT>>(n); break; } - } else if constexpr (std::is_same_v<ValueT, TinyVector<1>>) { - n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, int64_t>>(n); - break; } // LCOV_EXCL_START throw parse_error("unexpected error: invalid integral value", std::vector{n.children[1]->begin()}); diff --git a/src/language/ASTNodeExpressionBuilder.cpp b/src/language/ASTNodeExpressionBuilder.cpp index 55d2db53a..ff21fb58b 100644 --- a/src/language/ASTNodeExpressionBuilder.cpp +++ b/src/language/ASTNodeExpressionBuilder.cpp @@ -42,10 +42,7 @@ ASTNodeExpressionBuilder::_buildExpression(ASTNode& n) } else if (n.is_type<language::tuple_expression>()) { switch (n.children.size()) { - case 1: { - n.m_node_processor = std::make_unique<TupleToVectorProcessor<ASTNodeExpressionListProcessor, 1>>(n); - break; - } + // tuples are made of at least two elements case 2: { n.m_node_processor = std::make_unique<TupleToVectorProcessor<ASTNodeExpressionListProcessor, 2>>(n); break; @@ -54,9 +51,11 @@ ASTNodeExpressionBuilder::_buildExpression(ASTNode& n) n.m_node_processor = std::make_unique<TupleToVectorProcessor<ASTNodeExpressionListProcessor, 3>>(n); break; } + // LCOV_EXCL_START default: { throw parse_error("unexpected error: invalid tuple size", n.begin()); } + // LCOV_EXCL_STOP } } else if (n.is_type<language::function_definition>()) { n.m_node_processor = std::make_unique<FakeProcessor>(); diff --git a/src/language/ASTNodeListAffectationExpressionBuilder.cpp b/src/language/ASTNodeListAffectationExpressionBuilder.cpp index 2c14148ec..2829e8715 100644 --- a/src/language/ASTNodeListAffectationExpressionBuilder.cpp +++ b/src/language/ASTNodeListAffectationExpressionBuilder.cpp @@ -44,21 +44,33 @@ ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor( auto add_affectation_processor_for_vector_data = [&](const auto& value, const ASTNodeSubDataType& node_sub_data_type) { 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); + if constexpr (std::is_same_v<ValueT, TinyVector<1>>) { + if ((node_sub_data_type.m_data_type == ASTNodeDataType::vector_t) and + (node_sub_data_type.m_data_type.dimension() == value.dimension())) { + list_affectation_processor->template add<ValueT, ValueT>(value_node); } else { - throw parse_error("invalid operand value", std::vector{node_sub_data_type.m_parent_node.begin()}); + add_affectation_processor_for_data(value, node_sub_data_type); + } + } else if constexpr (std::is_same_v<ValueT, TinyVector<2>> or std::is_same_v<ValueT, TinyVector<3>>) { + if ((node_sub_data_type.m_data_type == ASTNodeDataType::vector_t) and + (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()}); } } else { - throw parse_error("invalid dimension", std::vector{node_sub_data_type.m_parent_node.begin()}); + throw parse_error("unexpected error: invalid value type"); } }; 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>) { + if constexpr (std::is_same_v<OperatorT, language::eq_op>) { switch (node_sub_data_type.m_data_type) { case ASTNodeDataType::bool_t: { list_affectation_processor->template add<std::string, bool>(value_node); @@ -145,7 +157,12 @@ ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor( } }; - ASTNodeNaturalConversionChecker{rhs_node_sub_data_type, value_node.m_data_type}; + if ((value_node.m_data_type != rhs_node_sub_data_type.m_data_type) and + (value_node.m_data_type == ASTNodeDataType::vector_t) and (value_node.m_data_type.dimension() == 1)) { + ASTNodeNaturalConversionChecker{rhs_node_sub_data_type, ASTNodeDataType::double_t}; + } else { + ASTNodeNaturalConversionChecker{rhs_node_sub_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/tests/test_ASTNodeExpressionBuilder.cpp b/tests/test_ASTNodeExpressionBuilder.cpp index bee00ca0a..e2e14d267 100644 --- a/tests/test_ASTNodeExpressionBuilder.cpp +++ b/tests/test_ASTNodeExpressionBuilder.cpp @@ -264,6 +264,51 @@ z -= 2; CHECK_AST(data, result); } + + SECTION("tuple -> R^3") + { + std::string_view data = R"( +R*R^3 (t,x) = (0,(1,2,3)); +)"; + + std::string result = R"( +(root:ASTNodeListProcessor) + `-(language::eq_op:ListAffectationProcessor<language::eq_op>) + +-(language::name_list:FakeProcessor) + | +-(language::name:t:NameProcessor) + | `-(language::name:x:NameProcessor) + `-(language::expression_list:ASTNodeExpressionListProcessor) + +-(language::integer:0:ValueProcessor) + `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor, 3ul>) + +-(language::integer:1:ValueProcessor) + +-(language::integer:2:ValueProcessor) + `-(language::integer:3:ValueProcessor) +)"; + + CHECK_AST(data, result); + } + + SECTION("tuple -> R^2") + { + std::string_view data = R"( +R*R^2 (t,x) = (0,(1,2)); +)"; + + std::string result = R"( +(root:ASTNodeListProcessor) + `-(language::eq_op:ListAffectationProcessor<language::eq_op>) + +-(language::name_list:FakeProcessor) + | +-(language::name:t:NameProcessor) + | `-(language::name:x:NameProcessor) + `-(language::expression_list:ASTNodeExpressionListProcessor) + +-(language::integer:0:ValueProcessor) + `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor, 2ul>) + +-(language::integer:1:ValueProcessor) + `-(language::integer:2:ValueProcessor) +)"; + + CHECK_AST(data, result); + } } SECTION("unary operators") @@ -409,6 +454,29 @@ a--; CHECK_AST(data, result); } + + SECTION("array subscript") + { + std::string_view data = R"( +R^3 x = (1, 2, 3); +x[2]; +)"; + + std::string result = R"( +(root:ASTNodeListProcessor) + +-(language::eq_op:AffectationFromListProcessor<language::eq_op, TinyVector<3ul, double> >) + | +-(language::name:x:NameProcessor) + | `-(language::expression_list:ASTNodeExpressionListProcessor) + | +-(language::integer:1:ValueProcessor) + | +-(language::integer:2:ValueProcessor) + | `-(language::integer:3:ValueProcessor) + `-(language::subscript_expression:ArraySubscriptProcessor<TinyVector<3ul, double> >) + +-(language::name:x:NameProcessor) + `-(language::integer:2:ValueProcessor) +)"; + + CHECK_AST(data, result); + } } SECTION("binary operators") -- GitLab