diff --git a/src/language/PEGGrammar.hpp b/src/language/PEGGrammar.hpp index 5f8b21d3aca42e79fc00354488a98e247f2bf8bc..d173f50745e781d2be5cade0372a0b15524f4850 100644 --- a/src/language/PEGGrammar.hpp +++ b/src/language/PEGGrammar.hpp @@ -237,9 +237,8 @@ struct expression_list : seq< open_parent, sor< seq< tuple_expression, struct affect_op : sor< eq_op, multiplyeq_op, divideeq_op, pluseq_op, minuseq_op > {}; -struct name_subscript_expression : seq< NAME, plus< subscript_expression > >{}; - -struct lvalue_expression : sor< name_subscript_expression, NAME >{}; +struct subscript_expression_of_lvalue : subscript_expression {}; +struct lvalue_expression : if_must<NAME, not_at<subscript_expression_of_lvalue> >{}; struct lvalue_list : seq< open_parent, list_must< lvalue_expression, COMMA >, close_parent >{}; @@ -389,6 +388,12 @@ inline const std::string errors<language::slashstar>::error_message = "block com template <> inline const std::string errors<language::open_brace>::error_message = "open brace was never closed, missing '}'"; +template <> +inline const std::string errors<language::close_parent>::error_message = "parse error, expecting ')'"; + +template <> +inline const std::string errors<language::not_at<subscript_expression_of_lvalue> >::error_message = "parse error, using subscript expression as lvalue is not allowed"; + template <> inline const std::string errors<language::simple_type_specifier>::error_message = "expecting simple type specifier"; diff --git a/src/language/ast/ASTBuilder.cpp b/src/language/ast/ASTBuilder.cpp index 109ce527cffee1cc4aaa4221079894f8f0357338..db7f77b29695bf82fc650ade4176592eefe5b651 100644 --- a/src/language/ast/ASTBuilder.cpp +++ b/src/language/ast/ASTBuilder.cpp @@ -57,8 +57,7 @@ struct ASTBuilder::simplify_unary : TAO_PEGTL_NAMESPACE::parse_tree::apply<ASTBu transform(std::unique_ptr<ASTNode>& n, States&&... st) { if (n->children.size() == 1) { - if (n->is_type<language::unary_expression>() or n->is_type<language::type_expression>() or - n->is_type<language::name_subscript_expression>()) { + if (n->is_type<language::unary_expression>() or n->is_type<language::type_expression>()) { n = std::move(n->children.back()); transform(n, st...); } else if (n->is_type<language::unary_minus>()) { @@ -105,7 +104,7 @@ struct ASTBuilder::simplify_unary : TAO_PEGTL_NAMESPACE::parse_tree::apply<ASTBu } } - if (n->is_type<language::unary_expression>() or n->is_type<language::name_subscript_expression>()) { + if (n->is_type<language::unary_expression>()) { if (n->children.size() > 1) { if (n->children[1]->is_type<language::subscript_expression>()) { std::swap(n->children[0], n->children[1]); @@ -262,8 +261,7 @@ using selector = TAO_PEGTL_NAMESPACE::parse_tree::selector< language::subscript_expression, language::tuple_type_specifier, language::type_expression, - language::unary_expression, - language::name_subscript_expression>, + language::unary_expression>, TAO_PEGTL_NAMESPACE::parse_tree::remove_content::on<language::plus_op, language::minus_op, language::shift_left_op, diff --git a/src/language/ast/ASTSymbolInitializationChecker.cpp b/src/language/ast/ASTSymbolInitializationChecker.cpp index 8fe9ac4f774a949600b1dadbb0018568722c37a7..9ce181ca7fe005534f4e2d45a1c575e45fbb86af 100644 --- a/src/language/ast/ASTSymbolInitializationChecker.cpp +++ b/src/language/ast/ASTSymbolInitializationChecker.cpp @@ -86,22 +86,15 @@ ASTSymbolInitializationChecker::_checkSymbolInitialization(ASTNode& node) if (node.children[0]->is_type<language::name>()) { set_is_initialized(*node.children[0]); - } else if (node.children[0]->is_type<language::subscript_expression>()) { - ASTNode& subscript_node = *node.children[0]; - ASTNode& name_node = *subscript_node.children[0]; - - Assert(name_node.is_type<language::name>()); - set_is_initialized(name_node); } else if (node.children[0]->is_type<language::name_list>() or node.children[0]->is_type<language::lvalue_list>()) { ASTNode& list_node = *node.children[0]; for (auto& child_node : list_node.children) { if (child_node->is_type<language::name>()) { set_is_initialized(*child_node); } else { - Assert(child_node->is_type<language::subscript_expression>()); - ASTNode& name_node = *child_node->children[0]; - Assert(name_node.is_type<language::name>()); - set_is_initialized(name_node); + // LCOV_EXCL_START + throw UnexpectedError("elements of the list should be language::name"); + // LCOV_EXCL_STOP } } } diff --git a/src/language/node_processor/AffectationProcessor.hpp b/src/language/node_processor/AffectationProcessor.hpp index 002c0e4ed7aa427a20734689089de590cfd96bc0..6b764b8d8a0d013b1170f754cb6d551e68ab0fff 100644 --- a/src/language/node_processor/AffectationProcessor.hpp +++ b/src/language/node_processor/AffectationProcessor.hpp @@ -202,165 +202,6 @@ class AffectationExecutor final : public IAffectationExecutor } }; -template <typename OperatorT, typename ArrayT, typename ValueT, typename DataT> -class MatrixComponentAffectationExecutor final : public IAffectationExecutor -{ - private: - ArrayT& m_lhs_array; - ASTNode& m_index0_expression; - ASTNode& m_index1_expression; - - static inline const bool m_is_defined{[] { - if constexpr (not std::is_same_v<typename ArrayT::data_type, ValueT>) { - return false; - } else if constexpr (std::is_same_v<std::decay_t<ValueT>, bool>) { - if constexpr (not std::is_same_v<OperatorT, language::eq_op>) { - return false; - } - } - return true; - }()}; - - public: - MatrixComponentAffectationExecutor(ASTNode& lhs_node, - ArrayT& lhs_array, - ASTNode& index0_expression, - ASTNode& index1_expression) - : m_lhs_array{lhs_array}, m_index0_expression{index0_expression}, m_index1_expression{index1_expression} - { - // LCOV_EXCL_START - if constexpr (not m_is_defined) { - throw ParseError("unexpected error: invalid operands to affectation expression", std::vector{lhs_node.begin()}); - } - // LCOV_EXCL_STOP - } - - PUGS_INLINE void - affect(ExecutionPolicy& exec_policy, DataVariant&& rhs) - { - if constexpr (m_is_defined) { - auto get_index_value = [&](DataVariant&& value_variant) -> int64_t { - int64_t index_value = 0; - std::visit( - [&](auto&& value) { - using IndexValueT = std::decay_t<decltype(value)>; - if constexpr (std::is_integral_v<IndexValueT>) { - index_value = value; - } else { - // LCOV_EXCL_START - throw UnexpectedError("invalid index type"); - // LCOV_EXCL_STOP - } - }, - value_variant); - return index_value; - }; - - const int64_t index0_value = get_index_value(m_index0_expression.execute(exec_policy)); - const int64_t index1_value = get_index_value(m_index1_expression.execute(exec_policy)); - - 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_array(index0_value, index1_value) = std::get<DataT>(rhs); - } else { - m_lhs_array(index0_value, index1_value) = std::to_string(std::get<DataT>(rhs)); - } - } else { - if constexpr (std::is_same_v<std::string, DataT>) { - m_lhs_array(index0_value, index1_value) += std::get<std::string>(rhs); - } else { - m_lhs_array(index0_value, index1_value) += std::to_string(std::get<DataT>(rhs)); - } - } - } else { - if constexpr (std::is_same_v<OperatorT, language::eq_op>) { - static_assert(std::is_convertible_v<DataT, ValueT>, "unexpected types"); - m_lhs_array(index0_value, index1_value) = static_cast<ValueT>(std::get<DataT>(rhs)); - } else { - AffOp<OperatorT>().eval(m_lhs_array(index0_value, index1_value), std::get<DataT>(rhs)); - } - } - } - } -}; - -template <typename OperatorT, typename ArrayT, typename ValueT, typename DataT> -class VectorComponentAffectationExecutor final : public IAffectationExecutor -{ - private: - ArrayT& m_lhs_array; - ASTNode& m_index_expression; - - static inline const bool m_is_defined{[] { - if constexpr (not std::is_same_v<typename ArrayT::data_type, ValueT>) { - return false; - } else if constexpr (std::is_same_v<std::decay_t<ValueT>, bool>) { - if constexpr (not std::is_same_v<OperatorT, language::eq_op>) { - return false; - } - } - return true; - }()}; - - public: - VectorComponentAffectationExecutor(ASTNode& node, ArrayT& lhs_array, ASTNode& index_expression) - : m_lhs_array{lhs_array}, m_index_expression{index_expression} - { - // LCOV_EXCL_START - if constexpr (not m_is_defined) { - throw ParseError("unexpected error: invalid operands to affectation expression", std::vector{node.begin()}); - } - // LCOV_EXCL_STOP - } - - PUGS_INLINE void - affect(ExecutionPolicy& exec_policy, DataVariant&& rhs) - { - if constexpr (m_is_defined) { - const int64_t index_value = [&](DataVariant&& value_variant) -> int64_t { - int64_t index_value = 0; - std::visit( - [&](auto&& value) { - using IndexValueT = std::decay_t<decltype(value)>; - if constexpr (std::is_integral_v<IndexValueT>) { - index_value = value; - } else { - // LCOV_EXCL_START - throw ParseError("unexpected error: invalid index type", std::vector{m_index_expression.begin()}); - // LCOV_EXCL_STOP - } - }, - value_variant); - return index_value; - }(m_index_expression.execute(exec_policy)); - - 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_array[index_value] = std::get<DataT>(rhs); - } else { - m_lhs_array[index_value] = std::to_string(std::get<DataT>(rhs)); - } - } else { - if constexpr (std::is_same_v<std::string, DataT>) { - m_lhs_array[index_value] += std::get<std::string>(rhs); - } else { - m_lhs_array[index_value] += std::to_string(std::get<DataT>(rhs)); - } - } - } else { - if constexpr (std::is_same_v<OperatorT, language::eq_op>) { - static_assert(std::is_convertible_v<DataT, ValueT>, "incompatible data and value types"); - m_lhs_array[index_value] = static_cast<ValueT>(std::get<DataT>(rhs)); - } else { - AffOp<OperatorT>().eval(m_lhs_array[index_value], std::get<DataT>(rhs)); - } - } - } - } -}; - template <typename OperatorT, typename ValueT, typename DataT> class AffectationProcessor final : public INodeProcessor { @@ -384,104 +225,6 @@ class AffectationProcessor final : public INodeProcessor using AffectationExecutorT = AffectationExecutor<OperatorT, ValueT, DataT>; return std::make_unique<AffectationExecutorT>(lhs_node, std::get<ValueT>(value)); - } else if (lhs_node.is_type<language::subscript_expression>()) { - auto& array_expression = *lhs_node.children[0]; - Assert(array_expression.is_type<language::name>()); - - const std::string& symbol = array_expression.string(); - - auto [i_symbol, found] = lhs_node.m_symbol_table->find(symbol, lhs_node.begin()); - Assert(found); - DataVariant& value = i_symbol->attributes().value(); - - if (array_expression.m_data_type == ASTNodeDataType::vector_t) { - Assert(lhs_node.children.size() == 2); - - auto& index_expression = *lhs_node.children[1]; - - switch (array_expression.m_data_type.dimension()) { - case 1: { - using ArrayTypeT = TinyVector<1>; - if (not std::holds_alternative<ArrayTypeT>(value)) { - value = ArrayTypeT{}; - } - using AffectationExecutorT = VectorComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - - return std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index_expression); - } - case 2: { - using ArrayTypeT = TinyVector<2>; - if (not std::holds_alternative<ArrayTypeT>(value)) { - value = ArrayTypeT{}; - } - using AffectationExecutorT = VectorComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - - return std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index_expression); - } - case 3: { - using ArrayTypeT = TinyVector<3>; - if (not std::holds_alternative<ArrayTypeT>(value)) { - value = ArrayTypeT{}; - } - using AffectationExecutorT = VectorComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - - return std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index_expression); - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: invalid vector dimension", std::vector{lhs_node.begin()}); - } - // LCOV_EXCL_STOP - } - } else if (array_expression.m_data_type == ASTNodeDataType::matrix_t) { - Assert(lhs_node.children.size() == 3); - Assert(array_expression.m_data_type.numberOfRows() == array_expression.m_data_type.numberOfColumns()); - - auto& index0_expression = *lhs_node.children[1]; - auto& index1_expression = *lhs_node.children[2]; - - switch (array_expression.m_data_type.numberOfRows()) { - case 1: { - using ArrayTypeT = TinyMatrix<1>; - if (not std::holds_alternative<ArrayTypeT>(value)) { - value = ArrayTypeT{}; - } - using AffectationExecutorT = MatrixComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - - return std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index0_expression, - index1_expression); - } - case 2: { - using ArrayTypeT = TinyMatrix<2>; - if (not std::holds_alternative<ArrayTypeT>(value)) { - value = ArrayTypeT{}; - } - using AffectationExecutorT = MatrixComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - - return std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index0_expression, - index1_expression); - } - case 3: { - using ArrayTypeT = TinyMatrix<3>; - if (not std::holds_alternative<ArrayTypeT>(value)) { - value = ArrayTypeT{}; - } - using AffectationExecutorT = MatrixComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - - return std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index0_expression, - index1_expression); - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: invalid vector dimension", std::vector{lhs_node.begin()}); - } - // LCOV_EXCL_STOP - } - } else { - // LCOV_EXCL_START - throw UnexpectedError("invalid subscript expression"); - // LCOV_EXCL_STOP - } } else { // LCOV_EXCL_START throw ParseError("unexpected error: invalid lhs", std::vector{lhs_node.begin()}); @@ -866,111 +609,6 @@ class ListAffectationProcessor final : public INodeProcessor } m_affectation_executor_list.emplace_back(std::make_unique<AffectationExecutorT>(m_node, std::get<ValueT>(value))); - } else if (lhs_node.is_type<language::subscript_expression>()) { - auto& array_subscript_expression = lhs_node; - - auto& array_expression = *array_subscript_expression.children[0]; - Assert(array_expression.is_type<language::name>()); - - const std::string& symbol = array_expression.string(); - - auto [i_symbol, found] = m_node.m_symbol_table->find(symbol, array_subscript_expression.begin()); - Assert(found); - DataVariant& value = i_symbol->attributes().value(); - - if (array_expression.m_data_type == ASTNodeDataType::vector_t) { - Assert(array_subscript_expression.children.size() == 2); - - auto& index_expression = *array_subscript_expression.children[1]; - - switch (array_expression.m_data_type.dimension()) { - case 1: { - using ArrayTypeT = TinyVector<1>; - if (not std::holds_alternative<ArrayTypeT>(value)) { - value = ArrayTypeT{}; - } - using AffectationExecutorT = VectorComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - m_affectation_executor_list.emplace_back( - std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index_expression)); - break; - } - case 2: { - using ArrayTypeT = TinyVector<2>; - if (not std::holds_alternative<ArrayTypeT>(value)) { - value = ArrayTypeT{}; - } - using AffectationExecutorT = VectorComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - m_affectation_executor_list.emplace_back( - std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index_expression)); - break; - } - case 3: { - using ArrayTypeT = TinyVector<3>; - if (not std::holds_alternative<ArrayTypeT>(value)) { - value = ArrayTypeT{}; - } - using AffectationExecutorT = VectorComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - m_affectation_executor_list.emplace_back( - std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index_expression)); - break; - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: invalid vector dimension", - std::vector{array_subscript_expression.begin()}); - } - // LCOV_EXCL_STOP - } - } else if (array_expression.m_data_type == ASTNodeDataType::matrix_t) { - Assert(array_subscript_expression.children.size() == 3); - - auto& index0_expression = *array_subscript_expression.children[1]; - auto& index1_expression = *array_subscript_expression.children[2]; - - Assert(array_expression.m_data_type.numberOfRows() == array_expression.m_data_type.numberOfColumns()); - - switch (array_expression.m_data_type.numberOfRows()) { - case 1: { - using ArrayTypeT = TinyMatrix<1>; - if (not std::holds_alternative<ArrayTypeT>(value)) { - value = ArrayTypeT{}; - } - using AffectationExecutorT = MatrixComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - m_affectation_executor_list.emplace_back( - std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index0_expression, - index1_expression)); - break; - } - case 2: { - using ArrayTypeT = TinyMatrix<2>; - if (not std::holds_alternative<ArrayTypeT>(value)) { - value = ArrayTypeT{}; - } - using AffectationExecutorT = MatrixComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - m_affectation_executor_list.emplace_back( - std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index0_expression, - index1_expression)); - break; - } - case 3: { - using ArrayTypeT = TinyMatrix<3>; - if (not std::holds_alternative<ArrayTypeT>(value)) { - value = ArrayTypeT{}; - } - using AffectationExecutorT = MatrixComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>; - m_affectation_executor_list.emplace_back( - std::make_unique<AffectationExecutorT>(lhs_node, std::get<ArrayTypeT>(value), index0_expression, - index1_expression)); - break; - } - // LCOV_EXCL_START - default: { - throw ParseError("unexpected error: invalid vector dimension", - std::vector{array_subscript_expression.begin()}); - } - // LCOV_EXCL_STOP - } - } } else { // LCOV_EXCL_START throw ParseError("unexpected error: invalid left hand side", std::vector{lhs_node.begin()}); diff --git a/tests/test_ASTBuilder.cpp b/tests/test_ASTBuilder.cpp index fdcf13315b9eb606f71f06d2cb1c2da399566a43..262a0cd30b60cee5da070fe6fa8d62d8981e7b1d 100644 --- a/tests/test_ASTBuilder.cpp +++ b/tests/test_ASTBuilder.cpp @@ -309,33 +309,6 @@ not not not false; } } - SECTION("subscript handling") - { - std::string_view data = R"( -u[a]; -u[f(c)]; -u[u[b]]; -)"; - - std::string_view result = R"( -(root) - +-(language::subscript_expression) - | +-(language::name:u) - | `-(language::name:a) - +-(language::subscript_expression) - | +-(language::name:u) - | `-(language::function_evaluation) - | +-(language::name:f) - | `-(language::name:c) - `-(language::subscript_expression) - +-(language::name:u) - `-(language::subscript_expression) - +-(language::name:u) - `-(language::name:b) -)"; - CHECK_AST(data, result); - } - SECTION("post incr/decr rearrangements") { std::string_view data = R"( diff --git a/tests/test_ASTNodeDataTypeBuilder.cpp b/tests/test_ASTNodeDataTypeBuilder.cpp index 2e3835024a270781d0dccb37edd914abfdd63a51..5dcd6f57cb77dc3e91b8e2e084f98b9143a75f1c 100644 --- a/tests/test_ASTNodeDataTypeBuilder.cpp +++ b/tests/test_ASTNodeDataTypeBuilder.cpp @@ -313,7 +313,7 @@ let (x,b,n,s) : R*B*N*string; SECTION("invalid array subscript") { std::string_view data = R"( -let x : R; x[2]; +let x:R, x = 1; let y:R, y = x[2]; )"; TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"}; @@ -326,7 +326,7 @@ let x : R; x[2]; SECTION("invalid R^d subscript index list") { std::string_view data = R"( -let x : R^2; x[2,2]; +let x:R^2, x = 0; let y:R, y = x[2,2]; )"; TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"}; @@ -339,7 +339,7 @@ let x : R^2; x[2,2]; SECTION("invalid R^dxd subscript index list 1") { std::string_view data = R"( -let x : R^2x2; x[2]; +let x:R^2x2, x = 0; let y:R, y = x[2]; )"; TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"}; @@ -352,7 +352,7 @@ let x : R^2x2; x[2]; SECTION("invalid R^dxd subscript index list 2") { std::string_view data = R"( -let x : R^2x2; x[2,3,1]; +let x:R^2x2, x = 0; let y:R, y = x[2,3,1]; )"; TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"}; diff --git a/tests/test_ASTNodeExpressionBuilder.cpp b/tests/test_ASTNodeExpressionBuilder.cpp index 25a3d3a93f21294bbd04ae238ccbfcca5f4738fb..56af1db48dce6019d5cb3fedf93c3e32cfc12e25 100644 --- a/tests/test_ASTNodeExpressionBuilder.cpp +++ b/tests/test_ASTNodeExpressionBuilder.cpp @@ -467,7 +467,7 @@ a--; { std::string_view data = R"( let x: R^3, x = (1, 2, 3); -x[2]; +let y: R, y = x[2]; )"; std::string result = R"( @@ -478,9 +478,11 @@ x[2]; | +-(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) + `-(language::eq_op:AffectationProcessor<language::eq_op, double, double>) + +-(language::name:y:NameProcessor) + `-(language::subscript_expression:ArraySubscriptProcessor<TinyVector<3ul, double> >) + +-(language::name:x:NameProcessor) + `-(language::integer:2:ValueProcessor) )"; CHECK_AST(data, result); diff --git a/tests/test_ASTSymbolInitializationChecker.cpp b/tests/test_ASTSymbolInitializationChecker.cpp index d0475ee8cf53875436ac8c8f8e12c1a8a1c60d2f..b9bcef85937ee0563bb1d7f51e55ceaa00eaa93a 100644 --- a/tests/test_ASTSymbolInitializationChecker.cpp +++ b/tests/test_ASTSymbolInitializationChecker.cpp @@ -43,27 +43,6 @@ let p:N; REQUIRE(not symbol_p->attributes().isInitialized()); } - SECTION("Array subscript initialization") - { - std::string_view data = R"( -let x:R^3; -x[0] = 1; -)"; - - string_input input{data, "test.pgs"}; - auto ast = ASTBuilder::build(input); - - ASTSymbolTableBuilder{*ast}; - ASTSymbolInitializationChecker{*ast}; - - position position{internal::iterator{"fixture"}, "fixture"}; - position.byte = data.size(); // ensure that variables are declared at this point - - auto [symbol_m, found_m] = ast->m_symbol_table->find("x", position); - REQUIRE(found_m); - REQUIRE(symbol_m->attributes().isInitialized()); - } - SECTION("Declaration plus affectation") { std::string_view data = R"( @@ -238,27 +217,6 @@ let (x,y):R^3*R; } } - SECTION("Affectation") - { - std::string_view data = R"( -let x:R^3; -(x[2], x[1], x[0]) = (1, 2, 3); -)"; - - string_input input{data, "test.pgs"}; - auto ast = ASTBuilder::build(input); - - ASTSymbolTableBuilder{*ast}; - ASTSymbolInitializationChecker{*ast}; - - position position{internal::iterator{"fixture"}, "fixture"}; - position.byte = data.size(); // ensure that variables are declared at this point - - auto [symbol_x, found_x] = ast->m_symbol_table->find("x", position); - REQUIRE(found_x); - REQUIRE(symbol_x->attributes().isInitialized()); - } - SECTION("errors") { SECTION("used uninitialized") diff --git a/tests/test_AffectationProcessor.cpp b/tests/test_AffectationProcessor.cpp index b6f73afdb4ec60f6b754eea3eafcbe2bf0ce0759..42c0514f963d5c452558bf6a8676c8d69395658d 100644 --- a/tests/test_AffectationProcessor.cpp +++ b/tests/test_AffectationProcessor.cpp @@ -62,6 +62,12 @@ REQUIRE_THROWS_WITH(ASTNodeExpressionBuilder{*ast}, error_message); \ } +#define CHECK_BUILD_THROWS_WITH(data, error_message) \ + { \ + TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"}; \ + REQUIRE_THROWS_WITH(ASTBuilder::build(input), error_message); \ + } + // clazy:excludeall=non-pod-global-static TEST_CASE("AffectationProcessor", "[language]") @@ -102,11 +108,6 @@ TEST_CASE("AffectationProcessor", "[language]") CHECK_AFFECTATION_RESULT("let x : R^1, x = true;", "x", (TinyVector<1>{true})); CHECK_AFFECTATION_RESULT("let x : R^1, x = false;", "x", (TinyVector<1>{false})); CHECK_AFFECTATION_RESULT("let x : R^1, x = -2.3;", "x", (TinyVector<1>{-2.3})); - CHECK_AFFECTATION_RESULT("let x : R^1; x[0] = -1;", "x", (TinyVector<1>{-1})); - CHECK_AFFECTATION_RESULT("let x : R^1; x[0] = true;", "x", (TinyVector<1>{true})); - CHECK_AFFECTATION_RESULT("let x : R^1; x[0] = false;", "x", (TinyVector<1>{false})); - CHECK_AFFECTATION_RESULT("let x : R^1; x[0] = -2.3;", "x", (TinyVector<1>{-2.3})); - CHECK_AFFECTATION_RESULT("let x : R^1, x = 0;", "x", (TinyVector<1>{zero})); } @@ -115,10 +116,6 @@ TEST_CASE("AffectationProcessor", "[language]") CHECK_AFFECTATION_RESULT("let x : R^2, x = (-1, true);", "x", (TinyVector<2>{-1, true})); CHECK_AFFECTATION_RESULT("let x : R^2, x = (true, false);", "x", (TinyVector<2>{true, false})); CHECK_AFFECTATION_RESULT("let x : R^2, x = (-0.3, 12);", "x", (TinyVector<2>{-0.3, 12})); - CHECK_AFFECTATION_RESULT("let x : R^2; x[0] = -1; x[1] = true;", "x", (TinyVector<2>{-1, true})); - CHECK_AFFECTATION_RESULT("let x : R^2; x[0] = true; x[1] = false;", "x", (TinyVector<2>{true, false})); - CHECK_AFFECTATION_RESULT("let x : R^2; x[0] = -0.3; x[1] = 12;", "x", (TinyVector<2>{-0.3, 12})); - CHECK_AFFECTATION_RESULT("let x : R^2, x = 0;", "x", (TinyVector<2>{zero})); } @@ -126,10 +123,6 @@ TEST_CASE("AffectationProcessor", "[language]") { CHECK_AFFECTATION_RESULT("let x : R^3, x = (-1, true, false);", "x", (TinyVector<3>{-1, true, false})); CHECK_AFFECTATION_RESULT("let x : R^3, x = (-0.3, 12, 6.2);", "x", (TinyVector<3>{-0.3, 12, 6.2})); - CHECK_AFFECTATION_RESULT("let x : R^3; x[0] = -1; x[1] = true; x[2] = false;", "x", - (TinyVector<3>{-1, true, false})); - CHECK_AFFECTATION_RESULT("let x : R^3; x[0] = -0.3; x[1] = 12; x[2] = 6.2;", "x", (TinyVector<3>{-0.3, 12, 6.2})); - CHECK_AFFECTATION_RESULT("let x : R^3; x = 0;", "x", (TinyVector<3>{zero})); } @@ -139,11 +132,6 @@ TEST_CASE("AffectationProcessor", "[language]") CHECK_AFFECTATION_RESULT("let x : R^1x1, x = true;", "x", (TinyMatrix<1>{true})); CHECK_AFFECTATION_RESULT("let x : R^1x1, x = false;", "x", (TinyMatrix<1>{false})); CHECK_AFFECTATION_RESULT("let x : R^1x1, x = -2.3;", "x", (TinyMatrix<1>{-2.3})); - CHECK_AFFECTATION_RESULT("let x : R^1x1; x[0,0] = -1;", "x", (TinyMatrix<1>{-1})); - CHECK_AFFECTATION_RESULT("let x : R^1x1; x[0,0] = true;", "x", (TinyMatrix<1>{true})); - CHECK_AFFECTATION_RESULT("let x : R^1x1; x[0,0] = false;", "x", (TinyMatrix<1>{false})); - CHECK_AFFECTATION_RESULT("let x : R^1x1; x[0,0] = -2.3;", "x", (TinyMatrix<1>{-2.3})); - CHECK_AFFECTATION_RESULT("let x : R^1x1; x = 0;", "x", (TinyMatrix<1>{zero})); } @@ -153,13 +141,6 @@ TEST_CASE("AffectationProcessor", "[language]") CHECK_AFFECTATION_RESULT("let x : R^2x2, x = (true, false, 1==2, 2==2);", "x", (TinyMatrix<2>{true, false, false, true})); CHECK_AFFECTATION_RESULT("let x : R^2x2, x = (-0.3, 12, 2, -3);", "x", (TinyMatrix<2>{-0.3, 12, 2, -3})); - CHECK_AFFECTATION_RESULT("let x : R^2x2; x[0,0] = -1; x[0,1] = true; x[1,0] = 2; x[1,1] = 3.3;", "x", - (TinyMatrix<2>{-1, true, 2, 3.3})); - CHECK_AFFECTATION_RESULT("let x : R^2x2; x[0,0] = true; x[0,1] = false; x[1,0] = 2.1; x[1,1] = -1;", "x", - (TinyMatrix<2>{true, false, 2.1, -1})); - CHECK_AFFECTATION_RESULT("let x : R^2x2; x[0,0] = -0.3; x[0,1] = 12; x[1,0] = 1.3; x[1,1] = 7;", "x", - (TinyMatrix<2>{-0.3, 12, 1.3, 7})); - CHECK_AFFECTATION_RESULT("let x : R^2x2, x = 0;", "x", (TinyMatrix<2>{zero})); } @@ -169,10 +150,6 @@ TEST_CASE("AffectationProcessor", "[language]") (TinyMatrix<3>{-1, true, false, 2, 3.1, 4, -1, true, 2})); CHECK_AFFECTATION_RESULT("let x : R^3x3, x = (-0.3, 12, 6.2, 7.1, 3.2, 2-3, 2, -1, 0);", "x", (TinyMatrix<3>{-0.3, 12, 6.2, 7.1, 3.2, 2 - 3, 2, -1, 0})); - CHECK_AFFECTATION_RESULT("let x : R^3x3; x[0,0] = -1; x[0,1] = true; x[0,2] = false; x[1,0] = -11; x[1,1] = 4; " - "x[1,2] = 3; x[2,0] = 6; x[2,1] = -3; x[2,2] = 5;", - "x", (TinyMatrix<3>{-1, true, false, -11, 4, 3, 6, -3, 5})); - CHECK_AFFECTATION_RESULT("let x : R^3x3, x = 0;", "x", (TinyMatrix<3>{zero})); } } @@ -208,23 +185,18 @@ TEST_CASE("AffectationProcessor", "[language]") { CHECK_AFFECTATION_RESULT("let x : R^1, x = -1; let y : R^1, y = 1; x += y;", "x", (TinyVector<1>{-1} + TinyVector<1>{1})); - CHECK_AFFECTATION_RESULT("let x : R^1, x = 2; x[0] += 1;", "x", (TinyVector<1>{2} + TinyVector<1>{1})); } SECTION("R^2") { CHECK_AFFECTATION_RESULT("let x : R^2, x = (-1, true); let y : R^2, y = (1,3); x += y;", "x", (TinyVector<2>{-1, true} + TinyVector<2>{1, 3})); - CHECK_AFFECTATION_RESULT("let x : R^2, x = (-1, true); x[0] += 2; x[1] += 1;", "x", - (TinyVector<2>{-1, true} + TinyVector<2>{2, 1})); } SECTION("R^3") { CHECK_AFFECTATION_RESULT("let x : R^3, x = (-1, true, false); let y : R^3, y = (1,2,3); x += y;", "x", (TinyVector<3>{-1, true, false} + TinyVector<3>{1, 2, 3})); - CHECK_AFFECTATION_RESULT("let x : R^3, x = (-0.3, 12, 6.2); x[0] += 1; x[1] += -3; x[2] += 1;", "x", - (TinyVector<3>{-0.3, 12, 6.2} + TinyVector<3>{1, -3, 1})); } } @@ -259,23 +231,18 @@ TEST_CASE("AffectationProcessor", "[language]") { CHECK_AFFECTATION_RESULT("let x : R^1, x = -1; let y : R^1, y = 1; x -= y;", "x", (TinyVector<1>{-1} - TinyVector<1>{1})); - CHECK_AFFECTATION_RESULT("let x : R^1, x = 2; x[0] -= 1;", "x", (TinyVector<1>{2} - TinyVector<1>{1})); } SECTION("R^2") { CHECK_AFFECTATION_RESULT("let x : R^2, x = (-1, true); let y : R^2, y = (1,3); x -= y;", "x", (TinyVector<2>{-1, true} - TinyVector<2>{1, 3})); - CHECK_AFFECTATION_RESULT("let x : R^2, x = (-1, true); x[0] -= 2; x[1] -= 1;", "x", - (TinyVector<2>{-1, true} - TinyVector<2>{2, 1})); } SECTION("R^3") { CHECK_AFFECTATION_RESULT("let x : R^3, x = (-1, true, false); let y : R^3, y = (1,2,3); x-=y;", "x", (TinyVector<3>{-1, true, false} - TinyVector<3>{1, 2, 3})); - CHECK_AFFECTATION_RESULT("let x : R^3, x = (-0.3, 12, 6.2); x[0] -= 1; x[1] -= -3; x[2] -= 1;", "x", - (TinyVector<3>{-0.3, 12, 6.2} - TinyVector<3>{1, -3, 1})); } } @@ -309,46 +276,35 @@ TEST_CASE("AffectationProcessor", "[language]") SECTION("R^1") { CHECK_AFFECTATION_RESULT("let x : R^1, x = 2; x *= 2;", "x", (TinyVector<1>{TinyVector<1>{2} *= 2})); - CHECK_AFFECTATION_RESULT("let x : R^1, x = 2; x[0] *= 1.3;", "x", (TinyVector<1>{2 * 1.3})); } SECTION("R^2") { CHECK_AFFECTATION_RESULT("let x : R^2, x = (-1, true); x *= 3;", "x", (TinyVector<2>{TinyVector<2>{-1, true} *= 3})); - CHECK_AFFECTATION_RESULT("let x : R^2, x = (-1, true); x[0] *= 2; x[1] *= 3;", "x", - (TinyVector<2>{-1 * 2, true * 3})); } SECTION("R^3") { CHECK_AFFECTATION_RESULT("let x : R^3, x = (-1, true, false); x*=5.2;", "x", (TinyVector<3>{TinyVector<3>{-1, true, false} *= 5.2})); - CHECK_AFFECTATION_RESULT("let x : R^3, x = (-0.3, 12, 6.2); x[0] *= -1; x[1] *= -3; x[2] *= 2;", "x", - (TinyVector<3>{-0.3 * -1, 12 * -3, 6.2 * 2})); } SECTION("R^1x1") { CHECK_AFFECTATION_RESULT("let x : R^1x1, x = 2; x *= 2;", "x", (TinyMatrix<1>{TinyMatrix<1>{2} *= 2})); - CHECK_AFFECTATION_RESULT("let x : R^1x1, x = 2; x[0,0] *= 1.3;", "x", (TinyMatrix<1>{2 * 1.3})); } SECTION("R^2x2") { CHECK_AFFECTATION_RESULT("let x : R^2x2, x = (-1, true, 3, 6); x *= 3;", "x", (TinyMatrix<2>{TinyMatrix<2>{-1, true, 3, 6} *= 3})); - CHECK_AFFECTATION_RESULT("let x : R^2x2, x = (-1, true, 3, 6); x[0,0] *= 2; x[1,1] *= 3;", "x", - (TinyMatrix<2>{-1 * 2, true, 3, 6 * 3})); } SECTION("R^3x3") { CHECK_AFFECTATION_RESULT("let x : R^3x3, x = (-1, true, false, 2, -3, 11, 5, -4, 2); x*=5.2;", "x", (TinyMatrix<3>{TinyMatrix<3>{-1, true, false, 2, -3, 11, 5, -4, 2} *= 5.2})); - CHECK_AFFECTATION_RESULT("let x : R^3x3, x = (-0.3, 12, 6.2, 2, -3, 11, 5, -4, 2); x[0,0] *= -1; x[0,1] *= -3; " - "x[0,2] *= 2; x[1,1] *= 2; x[2,1] *= 6; x[2,2] *= 2;", - "x", (TinyMatrix<3>{-0.3 * -1, 12 * -3, 6.2 * 2, 2, -3 * 2, 11, 5, (-4) * 6, 2 * 2})); } } @@ -375,45 +331,6 @@ TEST_CASE("AffectationProcessor", "[language]") CHECK_AFFECTATION_RESULT("let r : R, r = 1.1; r /= true;", "r", (1.1 / true)); CHECK_AFFECTATION_RESULT("let r : R, r = 2; r /= 1.1;", "r", (2. / 1.1)); } - - SECTION("R^1") - { - CHECK_AFFECTATION_RESULT("let x : R^1, x = 2; x[0] /= 1.3;", "x", (TinyVector<1>{2 / 1.3})); - } - - SECTION("R^2") - { - CHECK_AFFECTATION_RESULT("let x : R^2, x = (-1, true); x[0] /= 2; x[1] /= 3;", "x", - (TinyVector<2>{-1. / 2., true / 3.})); - } - - SECTION("R^3") - { - CHECK_AFFECTATION_RESULT("let x : R^3, x = (-0.3, 12, 6.2); x[0] /= -1.2; x[1] /= -3.1; x[2] /= 2.4;", "x", - (TinyVector<3>{-0.3 / -1.2, 12 / -3.1, 6.2 / 2.4})); - } - - SECTION("R^1x1") - { - CHECK_AFFECTATION_RESULT("let x : R^1x1, x = 2; x[0,0] /= 1.3;", "x", (TinyMatrix<1>{2 / 1.3})); - } - - SECTION("R^2x2") - { - CHECK_AFFECTATION_RESULT("let x : R^2x2, x = (-1, true, 3, 1); x[0,0] /= 2; x[0,1] /= 3; x[1,0] /= 0.5; x[1,1] " - "/= 4;", - "x", (TinyMatrix<2>{-1. / 2., true / 3., 3 / 0.5, 1. / 4})); - } - - SECTION("R^3x3") - { - CHECK_AFFECTATION_RESULT("let x : R^3x3, x = (-0.3, 12, 6.2, 1.2, 3, 5, 1, 11, 2); x[0,0] /= -1.2; x[0,1] /= " - "-3.1; x[0,2] /= 2.4; x[1,0] /= -1.6; x[1,1] /= -3.1; x[1,2] /= 2.4; x[2,0] /= 0.4; " - "x[2,1] /= -1.7; x[2,2] /= 1.2;", - "x", - (TinyMatrix<3>{-0.3 / -1.2, 12 / -3.1, 6.2 / 2.4, 1.2 / -1.6, 3 / -3.1, 5 / 2.4, 1 / 0.4, - 11 / -1.7, 2 / 1.2})); - } } SECTION("errors") @@ -518,8 +435,122 @@ TEST_CASE("AffectationProcessor", "[language]") "incompatible dimensions in affectation: expecting 3, but provided 4"); } + SECTION("-> R^n (affectation of components is forbidden)") + { + CHECK_BUILD_THROWS_WITH("let x : R^1; x[0] = -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^2; x[0] = -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^3; x[0] = -1;", + "parse error, using subscript expression as lvalue is not allowed"); + + CHECK_BUILD_THROWS_WITH("let x : R^1, x=0; x[0] = -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^2, x=0; x[0] = -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^3, x=0; x[0] = -1;", + "parse error, using subscript expression as lvalue is not allowed"); + + CHECK_BUILD_THROWS_WITH("let x : R^1, x=0; x[0] += -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^2, x=0; x[0] += -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^3, x=0; x[0] += -1;", + "parse error, using subscript expression as lvalue is not allowed"); + + CHECK_BUILD_THROWS_WITH("let x : R^1, x=0; x[0] -= -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^2, x=0; x[0] -= -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^3, x=0; x[0] -= -1;", + "parse error, using subscript expression as lvalue is not allowed"); + + CHECK_BUILD_THROWS_WITH("let x : R^1, x=0; x[0] *= -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^2, x=0; x[0] *= -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^3, x=0; x[0] *= -1;", + "parse error, using subscript expression as lvalue is not allowed"); + + CHECK_AFFECTATION_THROWS_WITH("let x : R^2, x = \"foobar\";", "undefined affectation type: R^2 = string"); + CHECK_AFFECTATION_THROWS_WITH("let x : R^3, x = \"foobar\";", "undefined affectation type: R^3 = string"); + + CHECK_AFFECTATION_THROWS_WITH("let x : R^2, x = 3.2;", "undefined affectation type: R^2 = R"); + CHECK_AFFECTATION_THROWS_WITH("let x : R^3, x = 2.3;", "undefined affectation type: R^3 = R"); + + CHECK_AFFECTATION_THROWS_WITH("let x : R^1; let y : R^1x1, y = 1; x = y;", + "undefined affectation type: R^1 = R^1x1"); + CHECK_AFFECTATION_THROWS_WITH("let x : R^2; let y : R^2x2, y = (1,2,4,4); x = y;", + "undefined affectation type: R^2 = R^2x2"); + CHECK_AFFECTATION_THROWS_WITH("let x : R^3; let y : R^3x3, y = (1,2,3,4,5,6,7,8,9); x = y;", + "undefined affectation type: R^3 = R^3x3"); + + CHECK_AFFECTATION_THROWS_WITH("let x : R^2, x = 4;", "invalid integral value (0 is the solely valid value)"); + CHECK_AFFECTATION_THROWS_WITH("let x : R^3, x = 3;", "invalid integral value (0 is the solely valid value)"); + + CHECK_AFFECTATION_THROWS_WITH("let x : R^1, x = 0; let y : R^2, y = x;", + "undefined affectation type: R^2 = R^1"); + CHECK_AFFECTATION_THROWS_WITH("let x : R^1, x = 0; let y : R^3, y = x;", + "undefined affectation type: R^3 = R^1"); + + CHECK_AFFECTATION_THROWS_WITH("let x : R^2, x = 0; let y : R^1, y = x;", + "undefined affectation type: R^1 = R^2"); + CHECK_AFFECTATION_THROWS_WITH("let x : R^2, x = 0; let y : R^3, y = x;", + "undefined affectation type: R^3 = R^2"); + + CHECK_AFFECTATION_THROWS_WITH("let x : R^3, x = 0; let y : R^1, y = x;", + "undefined affectation type: R^1 = R^3"); + CHECK_AFFECTATION_THROWS_WITH("let x : R^3, x = 0; let y : R^2, y = x;", + "undefined affectation type: R^2 = R^3"); + + CHECK_AFFECTATION_THROWS_WITH("let x : R^1, x = (1,2);", "undefined affectation type: R^1 = list"); + + CHECK_AFFECTATION_THROWS_WITH("let x : R^2, x = (1,2,3);", + "incompatible dimensions in affectation: expecting 2, but provided 3"); + + CHECK_AFFECTATION_THROWS_WITH("let x : R^3, x = (1,2);", + "incompatible dimensions in affectation: expecting 3, but provided 2"); + CHECK_AFFECTATION_THROWS_WITH("let x : R^3, x = (1,2,3,4);", + "incompatible dimensions in affectation: expecting 3, but provided 4"); + } + SECTION("-> R^nxn") { + CHECK_BUILD_THROWS_WITH("let x : R^1x1; x[0,0] = -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^2x2; x[0,0] = -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^3x3; x[0,0] = -1;", + "parse error, using subscript expression as lvalue is not allowed"); + + CHECK_BUILD_THROWS_WITH("let x : R^1x1, x=0; x[0,0] = -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^2x2, x=0; x[0,0] = -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^3x3, x=0; x[0,0] = -1;", + "parse error, using subscript expression as lvalue is not allowed"); + + CHECK_BUILD_THROWS_WITH("let x : R^1x1, x=0; x[0,0] += -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^2x2, x=0; x[0,0] += -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^3x3, x=0; x[0,0] += -1;", + "parse error, using subscript expression as lvalue is not allowed"); + + CHECK_BUILD_THROWS_WITH("let x : R^1x1, x=0; x[0,0] -= -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^2x2, x=0; x[0,0] -= -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^3x3, x=0; x[0,0] -= -1;", + "parse error, using subscript expression as lvalue is not allowed"); + + CHECK_BUILD_THROWS_WITH("let x : R^1x1, x=0; x[0,0] *= -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^2x2, x=0; x[0,0] *= -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_BUILD_THROWS_WITH("let x : R^3x3, x=0; x[0,0] *= -1;", + "parse error, using subscript expression as lvalue is not allowed"); + CHECK_AFFECTATION_THROWS_WITH("let x : R^2x2, x = \"foobar\";", "undefined affectation type: R^2x2 = string"); CHECK_AFFECTATION_THROWS_WITH("let x : R^3x3, x = \"foobar\";", "undefined affectation type: R^3x3 = string"); diff --git a/tests/test_ListAffectationProcessor.cpp b/tests/test_ListAffectationProcessor.cpp index 94dc1845cddcd898a3b3b0f2f08c80e164898660..f84ee471a7b2b4621ca4ef45d7c9a07610484a38 100644 --- a/tests/test_ListAffectationProcessor.cpp +++ b/tests/test_ListAffectationProcessor.cpp @@ -100,22 +100,5 @@ TEST_CASE("ListAffectationProcessor", "[language]") CHECK_AFFECTATION_RESULT(R"(let (x,y,z):R^3x3*R^2x2*R^1x1, (x,y,z) = (0,0,0);)", "y", (TinyMatrix<2>{zero})); CHECK_AFFECTATION_RESULT(R"(let (x,y,z):R^3x3*R^2x2*R^1x1, (x,y,z) = (0,0,0);)", "z", (TinyMatrix<1>{zero})); } - - SECTION("compound with subscript values") - { - CHECK_AFFECTATION_RESULT(R"(let x:R^3; (x[0], x[2], x[1]) = (4, 6, 5);)", "x", (TinyVector<3>{4, 5, 6})); - CHECK_AFFECTATION_RESULT(R"(let x:R^2; (x[1], x[0]) = (3, 6);)", "x", (TinyVector<2>{6, 3})); - CHECK_AFFECTATION_RESULT(R"(let x:R^1; let y:R; (y, x[0]) = (4, 2.3);)", "x", (TinyVector<1>{2.3})); - } - - SECTION("compound with subscript values") - { - CHECK_AFFECTATION_RESULT( - R"(let x:R^3x3; (x[0,0], x[1,0], x[1,2], x[2,0], x[0,1], x[0,2], x[1,1], x[2,1], x[2,2]) = (1, 4, 6, 7, 2, 3, 5, 8, 9);)", - "x", (TinyMatrix<3>{1, 2, 3, 4, 5, 6, 7, 8, 9})); - CHECK_AFFECTATION_RESULT(R"(let x:R^2x2; (x[1,1], x[0,0], x[1,0], x[0,1]) = (3, 6, 2, 4);)", "x", - (TinyMatrix<2>{6, 4, 2, 3})); - CHECK_AFFECTATION_RESULT(R"(let x:R^1x1; let y:R; (y, x[0,0]) = (4, 2.3);)", "x", (TinyMatrix<1>{2.3})); - } } }