diff --git a/tests/test_ASTNodeNaturalConversionChecker.cpp b/tests/test_ASTNodeNaturalConversionChecker.cpp index 7bf6e8b890b391b92d05f0f2d39c0d9387d24eb7..0142271ce7c0b9ed9421a07ca81497d6b6f1f41f 100644 --- a/tests/test_ASTNodeNaturalConversionChecker.cpp +++ b/tests/test_ASTNodeNaturalConversionChecker.cpp @@ -84,6 +84,145 @@ TEST_CASE("ASTNodeNaturalConversionChecker", "[language]") } } + SECTION("-> R^dxd") + { + SECTION("R^1x1 -> R^1x1") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, 1); + REQUIRE_NOTHROW( + ASTNodeNaturalConversionChecker{*data_node, ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, 1)}); + } + + SECTION("list -> R^1x1") + { + data_node->m_data_type = + ASTNodeDataType::build<ASTNodeDataType::list_t>({std::make_shared<const ASTNodeDataType>(double_dt)}); + { + std::unique_ptr list0_node = std::make_unique<ASTNode>(); + list0_node->m_data_type = double_dt; + data_node->emplace_back(std::move(list0_node)); + } + REQUIRE_NOTHROW( + ASTNodeNaturalConversionChecker{*data_node, ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, 1)}); + } + + SECTION("'0' -> R^dxd") + { + data_node->m_data_type = int_dt; + data_node->set_type<language::integer>(); + data_node->source = "0"; + auto& source = data_node->source; + data_node->m_begin = TAO_PEGTL_NAMESPACE::internal::iterator{&source[0]}; + data_node->m_end = TAO_PEGTL_NAMESPACE::internal::iterator{&source[source.size()]}; + + SECTION("d = 1") + { + REQUIRE_NOTHROW( + ASTNodeNaturalConversionChecker{*data_node, ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, 1)}); + } + SECTION("d = 2") + { + REQUIRE_NOTHROW( + ASTNodeNaturalConversionChecker{*data_node, ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2)}); + } + SECTION("d = 3") + { + REQUIRE_NOTHROW( + ASTNodeNaturalConversionChecker{*data_node, ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3)}); + } + } + + SECTION("R^2x2 -> R^2x2") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2); + REQUIRE_NOTHROW( + ASTNodeNaturalConversionChecker{*data_node, ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2)}); + } + + SECTION("list -> R^2x2") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::list_t>( + {std::make_shared<const ASTNodeDataType>(double_dt), std::make_shared<const ASTNodeDataType>(unsigned_int_dt), + std::make_shared<const ASTNodeDataType>(unsigned_int_dt), + std::make_shared<const ASTNodeDataType>(unsigned_int_dt)}); + { + std::unique_ptr list0_node = std::make_unique<ASTNode>(); + list0_node->m_data_type = double_dt; + data_node->emplace_back(std::move(list0_node)); + + std::unique_ptr list1_node = std::make_unique<ASTNode>(); + list1_node->m_data_type = unsigned_int_dt; + data_node->emplace_back(std::move(list1_node)); + + std::unique_ptr list2_node = std::make_unique<ASTNode>(); + list2_node->m_data_type = unsigned_int_dt; + data_node->emplace_back(std::move(list2_node)); + + std::unique_ptr list3_node = std::make_unique<ASTNode>(); + list3_node->m_data_type = unsigned_int_dt; + data_node->emplace_back(std::move(list3_node)); + } + REQUIRE_NOTHROW( + ASTNodeNaturalConversionChecker{*data_node, ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2)}); + } + + SECTION("R^3x3 -> R^3x3") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3); + REQUIRE_NOTHROW( + ASTNodeNaturalConversionChecker{*data_node, ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3)}); + } + + SECTION("list -> R^3x3") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::list_t>( + {std::make_shared<const ASTNodeDataType>(double_dt), std::make_shared<const ASTNodeDataType>(unsigned_int_dt), + std::make_shared<const ASTNodeDataType>(int_dt), std::make_shared<const ASTNodeDataType>(double_dt), + std::make_shared<const ASTNodeDataType>(unsigned_int_dt), std::make_shared<const ASTNodeDataType>(int_dt), + std::make_shared<const ASTNodeDataType>(double_dt), std::make_shared<const ASTNodeDataType>(unsigned_int_dt), + std::make_shared<const ASTNodeDataType>(int_dt)}); + { + std::unique_ptr list0_node = std::make_unique<ASTNode>(); + list0_node->m_data_type = double_dt; + data_node->emplace_back(std::move(list0_node)); + + std::unique_ptr list1_node = std::make_unique<ASTNode>(); + list1_node->m_data_type = unsigned_int_dt; + data_node->emplace_back(std::move(list1_node)); + + std::unique_ptr list2_node = std::make_unique<ASTNode>(); + list2_node->m_data_type = int_dt; + data_node->emplace_back(std::move(list2_node)); + + std::unique_ptr list3_node = std::make_unique<ASTNode>(); + list3_node->m_data_type = double_dt; + data_node->emplace_back(std::move(list3_node)); + + std::unique_ptr list4_node = std::make_unique<ASTNode>(); + list4_node->m_data_type = unsigned_int_dt; + data_node->emplace_back(std::move(list4_node)); + + std::unique_ptr list5_node = std::make_unique<ASTNode>(); + list5_node->m_data_type = int_dt; + data_node->emplace_back(std::move(list5_node)); + + std::unique_ptr list6_node = std::make_unique<ASTNode>(); + list6_node->m_data_type = double_dt; + data_node->emplace_back(std::move(list6_node)); + + std::unique_ptr list7_node = std::make_unique<ASTNode>(); + list7_node->m_data_type = unsigned_int_dt; + data_node->emplace_back(std::move(list7_node)); + + std::unique_ptr list8_node = std::make_unique<ASTNode>(); + list8_node->m_data_type = int_dt; + data_node->emplace_back(std::move(list8_node)); + } + REQUIRE_NOTHROW( + ASTNodeNaturalConversionChecker{*data_node, ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3)}); + } + } + SECTION("-> R^d") { SECTION("R^1 -> R^1") @@ -718,6 +857,423 @@ TEST_CASE("ASTNodeNaturalConversionChecker", "[language]") { std::unique_ptr data_node = std::make_unique<ASTNode>(); + SECTION("-> R^dxd") + { + SECTION("R^2x2 -> R^1x2") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2); + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, 1)}), + "invalid implicit conversion: R^2x2 -> R^1x1"); + } + + SECTION("R^3x3 -> R^1x1") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3); + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, 1)}), + "invalid implicit conversion: R^3x3 -> R^1x1"); + } + + SECTION("R^1x1 -> R^2x2") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, 1); + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2)}), + "invalid implicit conversion: R^1x1 -> R^2x2"); + } + + SECTION("R^3x3 -> R^2x2") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3); + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2)}), + "invalid implicit conversion: R^3x3 -> R^2x2"); + } + + SECTION("R^1x1 -> R^3x3") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, 1); + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3)}), + "invalid implicit conversion: R^1x1 -> R^3x3"); + } + + SECTION("R^2x2 -> R^3x3") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2); + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3)}), + "invalid implicit conversion: R^2x2 -> R^3x3"); + } + + SECTION("list1 -> R^dxd") + { + data_node->m_data_type = + ASTNodeDataType::build<ASTNodeDataType::list_t>({std::make_shared<const ASTNodeDataType>(double_dt)}); + { + std::unique_ptr list0_node = std::make_unique<ASTNode>(); + list0_node->m_data_type = double_dt; + data_node->emplace_back(std::move(list0_node)); + } + + SECTION("d=2") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, + 2)}), + "incompatible dimensions in affectation"); + } + + SECTION("d=3") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, + 3)}), + "incompatible dimensions in affectation"); + } + } + + SECTION("list2 -> R^dxd") + { + data_node->m_data_type = list_dt; + { + std::unique_ptr list0_node = std::make_unique<ASTNode>(); + list0_node->m_data_type = double_dt; + data_node->emplace_back(std::move(list0_node)); + + std::unique_ptr list1_node = std::make_unique<ASTNode>(); + list1_node->m_data_type = unsigned_int_dt; + data_node->emplace_back(std::move(list1_node)); + } + + SECTION("d=1") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, + 1)}), + "incompatible dimensions in affectation"); + } + + SECTION("d=3") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, + 3)}), + "incompatible dimensions in affectation"); + } + } + + SECTION("list3 -> R^dxd") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::list_t>( + {std::make_shared<const ASTNodeDataType>(double_dt), std::make_shared<const ASTNodeDataType>(unsigned_int_dt), + std::make_shared<const ASTNodeDataType>(int_dt)}); + { + std::unique_ptr list0_node = std::make_unique<ASTNode>(); + list0_node->m_data_type = double_dt; + data_node->emplace_back(std::move(list0_node)); + + std::unique_ptr list1_node = std::make_unique<ASTNode>(); + list1_node->m_data_type = unsigned_int_dt; + data_node->emplace_back(std::move(list1_node)); + + std::unique_ptr list2_node = std::make_unique<ASTNode>(); + list2_node->m_data_type = int_dt; + data_node->emplace_back(std::move(list2_node)); + } + + SECTION("d=1") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, + 1)}), + "incompatible dimensions in affectation"); + } + + SECTION("d=2") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, + 2)}), + "incompatible dimensions in affectation"); + } + } + + SECTION("tuple -> R^dxd") + { + SECTION("tuple(N) -> R^1x1") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::tuple_t>(unsigned_int_dt); + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, + 1)}), + "invalid implicit conversion: tuple(N) -> R^1x1"); + } + + SECTION("tuple(R) -> R^1x1") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::tuple_t>(double_dt); + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, + 1)}), + "invalid implicit conversion: tuple(R) -> R^1x1"); + } + + SECTION("tuple(R) -> R^2x2") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::tuple_t>(double_dt); + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, + 2)}), + "invalid implicit conversion: tuple(R) -> R^2x2"); + } + + SECTION("tuple(B) -> R^2x2") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::tuple_t>(bool_dt); + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, + 2)}), + "invalid implicit conversion: tuple(B) -> R^2x2"); + } + + SECTION("tuple(Z) -> R^3x2") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::tuple_t>(int_dt); + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, + 3)}), + "invalid implicit conversion: tuple(Z) -> R^3x3"); + } + + SECTION("tuple(R) -> R^3x3") + { + data_node->m_data_type = ASTNodeDataType::build<ASTNodeDataType::tuple_t>(double_dt); + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, + 3)}), + "invalid implicit conversion: tuple(R) -> R^3x3"); + } + + SECTION("tuple(R^1) -> tuple(R^3x3)") + { + auto tuple_R1 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::vector_t>(1)); + auto tuple_R3x3 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3)); + data_node->m_data_type = tuple_R1; + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, tuple_R3x3}), + "invalid implicit conversion: R^1 -> R^3x3"); + } + + SECTION("tuple(R^2) -> tuple(R^3x3)") + { + auto tuple_R2 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::vector_t>(2)); + auto tuple_R3x3 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3)); + data_node->m_data_type = tuple_R2; + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, tuple_R3x3}), + "invalid implicit conversion: R^2 -> R^3x3"); + } + + SECTION("tuple(R^2) -> tuple(R^1x1)") + { + auto tuple_R1x1 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, 1)); + auto tuple_R2 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::vector_t>(2)); + data_node->m_data_type = tuple_R2; + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, tuple_R1x1}), + "invalid implicit conversion: R^2 -> R^1x1"); + } + + SECTION("tuple(R^1x1) -> tuple(R^3x3)") + { + auto tuple_R1x1 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, 1)); + auto tuple_R3x3 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3)); + data_node->m_data_type = tuple_R1x1; + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, tuple_R3x3}), + "invalid implicit conversion: R^1x1 -> R^3x3"); + } + + SECTION("tuple(R^2x2) -> tuple(R^3x3)") + { + auto tuple_R2x2 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2)); + auto tuple_R3x3 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3)); + data_node->m_data_type = tuple_R2x2; + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, tuple_R3x3}), + "invalid implicit conversion: R^2x2 -> R^3x3"); + } + + SECTION("tuple(R^2x2) -> tuple(R^1x1)") + { + auto tuple_R1x1 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, 1)); + auto tuple_R2x2 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2)); + data_node->m_data_type = tuple_R2x2; + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, tuple_R1x1}), + "invalid implicit conversion: R^2x2 -> R^1x1"); + } + } + + SECTION("R -> R^dxd") + { + data_node->m_data_type = double_dt; + + SECTION("d=1") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, + 1)}), + "invalid implicit conversion: R -> R^1x1"); + } + + SECTION("d=2") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, + 2)}), + "invalid implicit conversion: R -> R^2x2"); + } + + SECTION("d=3") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, + 3)}), + "invalid implicit conversion: R -> R^3x3"); + } + } + + SECTION("Z -> R^dxd (non-zero)") + { + data_node->m_data_type = int_dt; + data_node->set_type<language::integer>(); + data_node->source = "1"; + auto& source = data_node->source; + data_node->m_begin = TAO_PEGTL_NAMESPACE::internal::iterator{&source[0]}; + data_node->m_end = TAO_PEGTL_NAMESPACE::internal::iterator{&source[source.size()]}; + + SECTION("d=1") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, + 1)}), + "invalid implicit conversion: Z -> R^1x1"); + } + + SECTION("d=2") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, + 2)}), + "invalid implicit conversion: Z -> R^2x2"); + } + + SECTION("d=3") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, + 3)}), + "invalid implicit conversion: Z -> R^3x3"); + } + } + + SECTION("N -> R^dxd") + { + data_node->m_data_type = unsigned_int_dt; + + SECTION("d=1") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, + 1)}), + "invalid implicit conversion: N -> R^1x1"); + } + + SECTION("d=2") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, + 2)}), + "invalid implicit conversion: N -> R^2x2"); + } + + SECTION("d=3") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, + 3)}), + "invalid implicit conversion: N -> R^3x3"); + } + } + + SECTION("B -> R^dxd") + { + data_node->m_data_type = bool_dt; + + SECTION("d=1") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, + 1)}), + "invalid implicit conversion: B -> R^1x1"); + } + + SECTION("d=2") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, + 2)}), + "invalid implicit conversion: B -> R^2x2"); + } + + SECTION("d=3") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, + 3)}), + "invalid implicit conversion: B -> R^3x3"); + } + } + + SECTION("string -> R^dxd") + { + data_node->m_data_type = string_dt; + + SECTION("d=1") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, + 1)}), + "invalid implicit conversion: string -> R^1x1"); + } + + SECTION("d=2") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, + 2)}), + "invalid implicit conversion: string -> R^2x2"); + } + + SECTION("d=3") + { + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, + 3)}), + "invalid implicit conversion: string -> R^3x3"); + } + } + } + SECTION("-> R^d") { SECTION("R^2 -> R^1") @@ -905,6 +1461,39 @@ TEST_CASE("ASTNodeNaturalConversionChecker", "[language]") "invalid implicit conversion: tuple(R) -> R^3"); } + SECTION("tuple(R^1x1) -> tuple(R^3)") + { + auto tuple_R1x1 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, 1)); + auto tuple_R3 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::vector_t>(3)); + data_node->m_data_type = tuple_R1x1; + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, tuple_R3}), + "invalid implicit conversion: R^1x1 -> R^3"); + } + + SECTION("tuple(R^2x2) -> tuple(R^3)") + { + auto tuple_R2x2 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2)); + auto tuple_R3 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::vector_t>(3)); + data_node->m_data_type = tuple_R2x2; + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, tuple_R3}), + "invalid implicit conversion: R^2x2 -> R^3"); + } + + SECTION("tuple(R^2x2) -> tuple(R^1)") + { + auto tuple_R1 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::vector_t>(1)); + auto tuple_R2x2 = + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2)); + data_node->m_data_type = tuple_R2x2; + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, tuple_R1}), + "invalid implicit conversion: R^2x2 -> R^1"); + } + SECTION("tuple(R^1) -> tuple(R^3)") { auto tuple_R1 = @@ -1415,6 +2004,36 @@ TEST_CASE("ASTNodeNaturalConversionChecker", "[language]") "invalid implicit conversion: R -> N"); } + SECTION("R^1x1 -> tuple(R^2x2)") + { + auto R1x1 = ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, 1); + auto R2x2 = ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2); + data_node->m_data_type = R1x1; + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(R2x2)}), + "invalid implicit conversion: R^1x1 -> R^2x2"); + } + + SECTION("R^2x2 -> tuple(R^3x3)") + { + auto R2x2 = ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2); + auto R3x3 = ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3); + data_node->m_data_type = R2x2; + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(R3x3)}), + "invalid implicit conversion: R^2x2 -> R^3x3"); + } + + SECTION("R^3x3 -> tuple(R^2x2)") + { + auto R3x3 = ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3); + auto R2x2 = ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2); + data_node->m_data_type = R3x3; + REQUIRE_THROWS_WITH((ASTNodeNaturalConversionChecker{*data_node, + ASTNodeDataType::build<ASTNodeDataType::tuple_t>(R2x2)}), + "invalid implicit conversion: R^3x3 -> R^2x2"); + } + SECTION("R^1 -> tuple(R^2)") { auto R1 = ASTNodeDataType::build<ASTNodeDataType::vector_t>(1);