Skip to content
Snippets Groups Projects
Select Git revision
  • 6a9f3e72ac873cacaa2ecfe5e980a9141f548239
  • develop default protected
  • feature/advection
  • feature/composite-scheme-other-fluxes
  • origin/stage/bouguettaia
  • save_clemence
  • feature/local-dt-fsi
  • feature/variational-hydro
  • feature/gmsh-reader
  • feature/reconstruction
  • feature/kinetic-schemes
  • feature/composite-scheme-sources
  • feature/serraille
  • feature/composite-scheme
  • hyperplastic
  • feature/polynomials
  • feature/gks
  • feature/implicit-solver-o2
  • feature/coupling_module
  • feature/implicit-solver
  • feature/merge-local-dt-fsi
  • v0.5.0 protected
  • v0.4.1 protected
  • v0.4.0 protected
  • v0.3.0 protected
  • v0.2.0 protected
  • v0.1.0 protected
  • Kidder
  • v0.0.4 protected
  • v0.0.3 protected
  • v0.0.2 protected
  • v0 protected
  • v0.0.1 protected
33 results

test_AffectationProcessor.cpp

Blame
  • test_AffectationProcessor.cpp 53.80 KiB
    #include <catch2/catch_test_macros.hpp>
    #include <catch2/matchers/catch_matchers_all.hpp>
    
    #include <language/ast/ASTBuilder.hpp>
    #include <language/ast/ASTModulesImporter.hpp>
    #include <language/ast/ASTNodeAffectationExpressionBuilder.hpp>
    #include <language/ast/ASTNodeDataTypeBuilder.hpp>
    #include <language/ast/ASTNodeDeclarationToAffectationConverter.hpp>
    #include <language/ast/ASTNodeExpressionBuilder.hpp>
    #include <language/ast/ASTNodeTypeCleaner.hpp>
    #include <language/ast/ASTSymbolTableBuilder.hpp>
    #include <language/utils/ASTPrinter.hpp>
    #include <language/utils/DataHandler.hpp>
    #include <language/utils/TypeDescriptor.hpp>
    #include <utils/Demangle.hpp>
    #include <utils/Stringify.hpp>
    
    #include <FixturesForBuiltinT.hpp>
    #include <language/utils/BasicAffectationRegistrerFor.hpp>
    
    #include <pegtl/string_input.hpp>
    
    #include <sstream>
    
    #define CHECK_AFFECTATION_RESULT(data, variable_name, expected_value)         \
      {                                                                           \
        TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"};                \
        auto ast = ASTBuilder::build(input);                                      \
                                                                                  \
        ASTModulesImporter{*ast};                                                 \
                                                                                  \
        ASTSymbolTableBuilder{*ast};                                              \
        ASTNodeDataTypeBuilder{*ast};                                             \
                                                                                  \
        ASTNodeDeclarationToAffectationConverter{*ast};                           \
        ASTNodeTypeCleaner<language::var_declaration>{*ast};                      \
                                                                                  \
        ASTNodeExpressionBuilder{*ast};                                           \
        ExecutionPolicy exec_policy;                                              \
        ast->execute(exec_policy);                                                \
                                                                                  \
        auto symbol_table = ast->m_symbol_table;                                  \
                                                                                  \
        using namespace TAO_PEGTL_NAMESPACE;                                      \
        position use_position{internal::iterator{"fixture"}, "fixture"};          \
        use_position.byte    = 10000;                                             \
        auto [symbol, found] = symbol_table->find(variable_name, use_position);   \
                                                                                  \
        auto attributes = symbol->attributes();                                   \
        auto value      = std::get<decltype(expected_value)>(attributes.value()); \
                                                                                  \
        REQUIRE(value == expected_value);                                         \
      }
    
    #define CHECK_BUILTIN_AFFECTATION_RESULT(data, variable_name, expected_value)                                   \
      {                                                                                                             \
        TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"};                                                  \
        auto ast = ASTBuilder::build(input);                                                                        \
                                                                                                                    \
        ASTModulesImporter{*ast};                                                                                   \
                                                                                                                    \
        BasicAffectationRegisterFor<EmbeddedData>{ASTNodeDataType::build<ASTNodeDataType::type_id_t>("builtin_t")}; \
                                                                                                                    \
        SymbolTable& symbol_table = *ast->m_symbol_table;                                                           \
        auto [i_symbol, success]  = symbol_table.add(builtin_data_type.nameOfTypeId(), ast->begin());               \
        if (not success) {                                                                                          \
          throw UnexpectedError("cannot add '" + builtin_data_type.nameOfTypeId() + "' type for testing");          \
        }                                                                                                           \
                                                                                                                    \
        i_symbol->attributes().setDataType(ASTNodeDataType::build<ASTNodeDataType::type_name_id_t>());              \
        i_symbol->attributes().setIsInitialized();                                                                  \
        i_symbol->attributes().value() = symbol_table.typeEmbedderTable().size();                                   \
        symbol_table.typeEmbedderTable().add(std::make_shared<TypeDescriptor>(builtin_data_type.nameOfTypeId()));   \
                                                                                                                    \
        auto [i_symbol_bt_a, success_bt_a] = symbol_table.add("bt_a", ast->begin());                                \
        if (not success_bt_a) {                                                                                     \
          throw UnexpectedError("cannot add 'bt_a' of type builtin_t for testing");                                 \
        }                                                                                                           \
        i_symbol_bt_a->attributes().setDataType(ast_node_data_type_from<std::shared_ptr<const double>>);            \
        i_symbol_bt_a->attributes().setIsInitialized();                                                             \
        i_symbol_bt_a->attributes().value() =                                                                       \
          EmbeddedData(std::make_shared<DataHandler<const double>>(std::make_shared<double>(3.2)));                 \
                                                                                                                    \
        auto [i_symbol_bt_b, success_bt_b] = symbol_table.add("bt_b", ast->begin());                                \
        if (not success_bt_b) {                                                                                     \
          throw UnexpectedError("cannot add 'bt_b' of type builtin_t for testing");                                 \
        }                                                                                                           \
        i_symbol_bt_b->attributes().setDataType(ast_node_data_type_from<std::shared_ptr<const double>>);            \
        i_symbol_bt_b->attributes().setIsInitialized();                                                             \
        i_symbol_bt_b->attributes().value() =                                                                       \
          EmbeddedData(std::make_shared<DataHandler<const double>>(std::make_shared<double>(5.3)));                 \
                                                                                                                    \
        ASTSymbolTableBuilder{*ast};                                                                                \
        ASTNodeDataTypeBuilder{*ast};                                                                               \
                                                                                                                    \
        ASTNodeDeclarationToAffectationConverter{*ast};                                                             \
        ASTNodeTypeCleaner<language::var_declaration>{*ast};                                                        \
                                                                                                                    \
        ASTNodeExpressionBuilder{*ast};                                                                             \
        ExecutionPolicy exec_policy;                                                                                \
        ast->execute(exec_policy);                                                                                  \
                                                                                                                    \
        using namespace TAO_PEGTL_NAMESPACE;                                                                        \
        position use_position{internal::iterator{"fixture"}, "fixture"};                                            \
        use_position.byte    = 10000;                                                                               \
        auto [symbol, found] = symbol_table.find(variable_name, use_position);                                      \
                                                                                                                    \
        auto attributes     = symbol->attributes();                                                                 \
        auto embedded_value = std::get<EmbeddedData>(attributes.value());                                           \
                                                                                                                    \
        double value = *dynamic_cast<const DataHandler<const double>&>(embedded_value.get()).data_ptr();            \
        REQUIRE(value == expected);                                                                                 \
      }
    
    #define CHECK_AFFECTATION_THROWS_WITH(data, error_message)              \
      {                                                                     \
        TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"};          \
        auto ast = ASTBuilder::build(input);                                \
                                                                            \
        ASTModulesImporter{*ast};                                           \
                                                                            \
        ASTSymbolTableBuilder{*ast};                                        \
        ASTNodeDataTypeBuilder{*ast};                                       \
                                                                            \
        ASTNodeDeclarationToAffectationConverter{*ast};                     \
        ASTNodeTypeCleaner<language::var_declaration>{*ast};                \
                                                                            \
        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); \
      }
    
    #define CHECK_AFFECTATION_EXEC_THROWS_WITH(data, error_message)    \
      {                                                                \
        TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"};     \
        auto ast = ASTBuilder::build(input);                           \
                                                                       \
        ASTModulesImporter{*ast};                                      \
                                                                       \
        ASTSymbolTableBuilder{*ast};                                   \
        ASTNodeDataTypeBuilder{*ast};                                  \
                                                                       \
        ASTNodeDeclarationToAffectationConverter{*ast};                \
        ASTNodeTypeCleaner<language::var_declaration>{*ast};           \
                                                                       \
        ASTNodeExpressionBuilder{*ast};                                \
        ExecutionPolicy exec_policy;                                   \
                                                                       \
        REQUIRE_THROWS_WITH(ast->execute(exec_policy), error_message); \
      }
    
    // clazy:excludeall=non-pod-global-static
    
    TEST_CASE("AffectationProcessor", "[language]")
    {
      SECTION("Affectations")
      {
        SECTION("from value")
        {
          SECTION("-> B")
          {
            CHECK_AFFECTATION_RESULT("let b : B; b = true;", "b", true);
          }
    
          SECTION("-> N")
          {
            CHECK_AFFECTATION_RESULT("let n : N, n = 1;", "n", 1ul);
            CHECK_AFFECTATION_RESULT("let m : N, m = 2; let n : N, n = m;", "n", 2ul);
            CHECK_AFFECTATION_RESULT("let n : N, n = true;", "n", 1ul);
            CHECK_AFFECTATION_RESULT("let n : N, n = false;", "n", 0ul);
          }
    
          SECTION("-> Z")
          {
            CHECK_AFFECTATION_RESULT("let z : Z, z = -1;", "z", -1l);
            CHECK_AFFECTATION_RESULT("let z : Z, z = true;", "z", 1l);
            CHECK_AFFECTATION_RESULT("let z : Z, z = false;", "z", 0l);
          }
    
          SECTION("-> R")
          {
            CHECK_AFFECTATION_RESULT("let r : R, r = -1;", "r", double{-1});
            CHECK_AFFECTATION_RESULT("let r : R, r = true;", "r", double{1});
            CHECK_AFFECTATION_RESULT("let r : R, r = false;", "r", double{0});
            CHECK_AFFECTATION_RESULT("let r : R, r = -2.3;", "r", double{-2.3});
          }
    
          SECTION("-> R^1")
          {
            CHECK_AFFECTATION_RESULT("let x : R^1, x = -1;", "x", (TinyVector<1>{-1}));
            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 = [-1];", "x", (TinyVector<1>{-1}));
            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;", "x", (TinyVector<1>{zero}));
          }
    
          SECTION("-> R^2")
          {
            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;", "x", (TinyVector<2>{zero}));
          }
    
          SECTION("-> R^3")
          {
            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;", "x", (TinyVector<3>{zero}));
          }
    
          SECTION("-> R^1x1")
          {
            CHECK_AFFECTATION_RESULT("let x : R^1x1, x = -1;", "x", (TinyMatrix<1>{-1}));
            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 = [[-1]];", "x", (TinyMatrix<1>{-1}));
            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;", "x", (TinyMatrix<1>{zero}));
          }
    
          SECTION("-> R^2x2")
          {
            CHECK_AFFECTATION_RESULT("let x : R^2x2, x = [[-1, true], [3, 5]];", "x", (TinyMatrix<2>{-1, true, 3, 5}));
            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;", "x", (TinyMatrix<2>{zero}));
          }
    
          SECTION("-> R^3x3")
          {
            CHECK_AFFECTATION_RESULT("let x : R^3x3, x = [[-1, true, false], [2, 3.1, 4], [-1, true, 2]];", "x",
                                     (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;", "x", (TinyMatrix<3>{zero}));
          }
    
          SECTION("-> string")
          {
            CHECK_AFFECTATION_RESULT("let x : string, x = true;", "x", (stringify(true)));
            CHECK_AFFECTATION_RESULT("let n:N, n = 3; let x : string, x = n;", "x", (stringify(3ul)));
            CHECK_AFFECTATION_RESULT("let x : string, x = -2;", "x", (stringify(-2l)));
            CHECK_AFFECTATION_RESULT("let x : string, x = 1.7;", "x", (stringify(double{1.7})));
    
            CHECK_AFFECTATION_RESULT("let x : string, x = [1.7];", "x", (stringify(TinyVector<1>{1.7})));
            CHECK_AFFECTATION_RESULT("let x : string, x = [1.7, 2];", "x", (stringify(TinyVector<2>{1.7, 2})));
            CHECK_AFFECTATION_RESULT("let x : string, x = [1.7, 5, 2];", "x", (stringify(TinyVector<3>{1.7, 5, 2})));
    
            CHECK_AFFECTATION_RESULT("let x : string, x = [[1.7]];", "x", (stringify(TinyMatrix<1>{1.7})));
            CHECK_AFFECTATION_RESULT("let x : string, x = [[1.7, 2],[1,3]];", "x",
                                     (stringify(TinyMatrix<2>{1.7, 2, 1, 3})));
            CHECK_AFFECTATION_RESULT("let x : string, x = [[1.7, 5, 2],[1,3,5],[-1,2,6]];", "x",
                                     (stringify(TinyMatrix<3>{1.7, 5, 2, 1, 3, 5, -1, 2, 6})));
    
            CHECK_AFFECTATION_RESULT("let x : string, x = \"foobar\";", "x", (std::string{"foobar"}));
          }
    
          SECTION("-> builtin_t")
          {
            const double expected = double{3.2};
            CHECK_BUILTIN_AFFECTATION_RESULT("let b:builtin_t, b = bt_a;", "b", expected);
          }
        }
    
        SECTION("from tuple")
        {
          SECTION("-> B")
          {
            CHECK_AFFECTATION_RESULT("let b : B; b = true;", "b", true);
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(B), t = true;
    let b:B, b = t;
    )"},
                                     "b", true);
          }
    
          SECTION("-> N")
          {
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(B), t = true;
    let n:N, n = t;
    )"},
                                     "n", 1ul);
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(N), t = 1;
    let n:N, n = t;
    )"},
                                     "n", 1ul);
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(Z), t = 2;
    let n:N, n = t;
    )"},
                                     "n", 2ul);
          }
    
          SECTION("-> Z")
          {
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(B), t = true;
    let z:Z, z = t;
    )"},
                                     "z", 1l);
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(N), t = 2;
    let z:Z, z = t;
    )"},
                                     "z", 2l);
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(Z), t = 3;
    let z:Z, z = t;
    )"},
                                     "z", 3l);
          }
    
          SECTION("-> R")
          {
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(B), t = true;
    let r:R, r = t;
    )"},
                                     "r", double{1});
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(N), t = 2;
    let r:R, r = t;
    )"},
                                     "r", double{2});
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(Z), t =-3;
    let r:R, r = t;
    )"},
                                     "r", double{-3});
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(R), t =-3.2;
    let r:R, r = t;
    )"},
                                     "r", double{-3.2});
          }
    
          SECTION("-> R^1")
          {
            using R1x1 = TinyVector<1>;
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(B), t = true;
    let r:R^1, r = t;
    )"},
                                     "r", R1x1{1});
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(N), t = 2;
    let r:R^1, r = t;
    )"},
                                     "r", R1x1{2});
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(Z), t =-3;
    let r:R^1, r = t;
    )"},
                                     "r", R1x1{-3});
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(R), t =-3.2;
    let r:R^1, r = t;
    )"},
                                     "r", R1x1{-3.2});
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(R^1), t =-1.2;
    let r:R^1, r = t;
    )"},
                                     "r", R1x1{-1.2});
          }
    
          SECTION("-> R^2")
          {
            using R2 = TinyVector<2>;
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(R^2), t =[-1.2, 2];
    let r:R^2, r = t;
    )"},
                                     "r", (R2{-1.2, 2}));
          }
    
          SECTION("-> R^3")
          {
            using R3 = TinyVector<3>;
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(R^3), t =[-1.2, 2, 1];
    let r:R^3, r = t;
    )"},
                                     "r", (R3{-1.2, 2, 1}));
          }
    
          SECTION("-> R^1x1")
          {
            using R1x1 = TinyMatrix<1>;
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(B), t = true;
    let r:R^1x1, r = t;
    )"},
                                     "r", R1x1{1});
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(N), t = 2;
    let r:R^1x1, r = t;
    )"},
                                     "r", R1x1{2});
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(Z), t =-3;
    let r:R^1x1, r = t;
    )"},
                                     "r", R1x1{-3});
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(R), t =-3.2;
    let r:R^1x1, r = t;
    )"},
                                     "r", R1x1{-3.2});
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(R^1x1), t =-1.2;
    let r:R^1x1, r = t;
    )"},
                                     "r", R1x1{-1.2});
          }
    
          SECTION("-> R^2x2")
          {
            using R2x2 = TinyMatrix<2>;
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(R^2x2), t =[[-1.2, 2],[1,3]];
    let r:R^2x2, r = t;
    )"},
                                     "r", (R2x2{-1.2, 2, 1, 3}));
          }
    
          SECTION("-> R^3x3")
          {
            using R3x3 = TinyMatrix<3>;
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(R^3x3), t = [[-1.2, 2, 1],[-2.2, 1, 7],[-3, 1, 2]];
    let r:R^3x3, r = t;
    )"},
                                     "r", (R3x3{-1.2, 2, 1, -2.2, 1, 7, -3, 1, 2}));
          }
    
          SECTION("-> string")
          {
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(B), t = true;
    let x:string, x = t;
    )"},
                                     "x", (stringify(true)));
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(N), t = 3;
    let x:string, x = t;
    )"},
                                     "x", (stringify(3ul)));
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(Z), t = -2;
    let x:string, x = t;
    )"},
                                     "x", (stringify(-2l)));
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(R), t = 1.7;
    let x:string, x = t;
    )"},
                                     "x", (stringify(double{1.7})));
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(R^1), t = [1.7];
    let x:string, x = t;
    )"},
                                     "x", (stringify(TinyVector<1>{1.7})));
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(R^2), t = [1.7, 2];
    let x:string, x = t;
    )"},
                                     "x", (stringify(TinyVector<2>{1.7, 2})));
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(R^3), t = [1.7, 5, 2];
    let x:string, x = t;
    )"},
                                     "x", (stringify(TinyVector<3>{1.7, 5, 2})));
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(R^1x1), t = [[1.7]];
    let x:string, x = t;
    )"},
                                     "x", (stringify(TinyMatrix<1>{1.7})));
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(R^2x2), t = [[1.7, 2],[1,3]];
    let x:string, x = t;
    )"},
                                     "x", (stringify(TinyMatrix<2>{1.7, 2, 1, 3})));
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(R^3x3), t = [[1.7, 5, 2],[1,3,5],[-1,2,6]];
    let x:string, x = t;
    )"},
                                     "x", (stringify(TinyMatrix<3>{1.7, 5, 2, 1, 3, 5, -1, 2, 6})));
    
            CHECK_AFFECTATION_RESULT(std::string{R"(
    let t:(string), t = "foobar";
    let x:string, x = t;
    )"},
                                     "x", (std::string{"foobar"}));
          }
    
          SECTION("-> builtin_t")
          {
            const double expected = double{3.2};
            CHECK_BUILTIN_AFFECTATION_RESULT(std::string{R"(
    let t:(builtin_t), t = bt_a;
    let x:builtin_t, x = t;
    )"},
                                             "x", expected);
          }
        }
      }
    
      SECTION("+=")
      {
        SECTION("N")
        {
          CHECK_AFFECTATION_RESULT("let n : N, n = 1; n += 3;", "n", 4ul);
          CHECK_AFFECTATION_RESULT("let m : N, m = 2; let n : N, n = 1; n += m;", "n", 3ul);
          CHECK_AFFECTATION_RESULT("let n : N, n = 1; n += true;", "n", 2ul);
          CHECK_AFFECTATION_RESULT("let n : N, n = 3; n += false;", "n", 3ul);
        }
    
        SECTION("Z")
        {
          CHECK_AFFECTATION_RESULT("let z : Z, z = 1; z += 3;", "z", 4l);
          CHECK_AFFECTATION_RESULT("let m : N, m = 2; let z : Z, z = 1; z += m;", "z", 3l);
          CHECK_AFFECTATION_RESULT("let z : Z, z = 1; z += true;", "z", 2l);
          CHECK_AFFECTATION_RESULT("let z : Z, z = 3; z += false;", "z", 3l);
        }
    
        SECTION("R")
        {
          CHECK_AFFECTATION_RESULT("let r : R, r = 1.2; r += 2.3;", "r", 3.5);
          CHECK_AFFECTATION_RESULT("let m : N, m = 2; let r : R, r = 1.3; r += m;", "r", 3.3);
          CHECK_AFFECTATION_RESULT("let r : R, r = 1.1; r += true;", "r", 2.1);
          CHECK_AFFECTATION_RESULT("let r : R, r = 3.3; r += false;", "r", 3.3);
          CHECK_AFFECTATION_RESULT("let r : R, r = 2; r += 1.1;", "r", 3.1);
        }
    
        SECTION("R^1")
        {
          CHECK_AFFECTATION_RESULT("let x : R^1, x = -1; let y : R^1, y = 1; x += y;", "x",
                                   (TinyVector<1>{-1} + TinyVector<1>{1}));
        }
    
        SECTION("R^2")
        {
          CHECK_AFFECTATION_RESULT("let x : R^2, x = [-1, true]; x += [1,3];", "x",
                                   (TinyVector<2>{-1, true} + TinyVector<2>{1, 3}));
        }
    
        SECTION("R^3")
        {
          CHECK_AFFECTATION_RESULT("let x : R^3, x = [-1, true, false]; x += [1,2,3];", "x",
                                   (TinyVector<3>{-1, true, false} + TinyVector<3>{1, 2, 3}));
        }
      }
    
      SECTION("-=")
      {
        SECTION("N")
        {
          CHECK_AFFECTATION_RESULT("let n : N, n = 3; n -= 2;", "n", 1ul);
          CHECK_AFFECTATION_RESULT("let m : N, m = 2; let n : N, n = 4; n -= m;", "n", 2ul);
          CHECK_AFFECTATION_RESULT("let n : N, n = 1; n -= true;", "n", 0ul);
          CHECK_AFFECTATION_RESULT("let n : N, n = 3; n -= false;", "n", 3ul);
        }
    
        SECTION("Z")
        {
          CHECK_AFFECTATION_RESULT("let z : Z, z = 1; z -= 3;", "z", -2l);
          CHECK_AFFECTATION_RESULT("let m : N, m = 2; let z : Z, z = 1; z -= m;", "z", -1l);
          CHECK_AFFECTATION_RESULT("let z : Z, z = 1; z -= true;", "z", 0l);
          CHECK_AFFECTATION_RESULT("let z : Z, z = 3; z -= false;", "z", 3l);
        }
    
        SECTION("R")
        {
          CHECK_AFFECTATION_RESULT("let r : R, r = 1.1; r -= 2;", "r", (1.1 - 2l));
          CHECK_AFFECTATION_RESULT("let m : N, m = 2; let r : R, r = 1.3; r -= m;", "r", (1.3 - 2ul));
          CHECK_AFFECTATION_RESULT("let r : R, r = 1.1; r -= true;", "r", (1.1 - true));
          CHECK_AFFECTATION_RESULT("let r : R, r = 3.3; r -= false;", "r", 3.3);
          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 = [-1];  x -= [1];", "x", (TinyVector<1>{-1} - TinyVector<1>{1}));
        }
    
        SECTION("R^2")
        {
          CHECK_AFFECTATION_RESULT("let x : R^2, x = [-1, true]; x -= [1,3];", "x",
                                   (TinyVector<2>{-1, true} - TinyVector<2>{1, 3}));
        }
    
        SECTION("R^3")
        {
          CHECK_AFFECTATION_RESULT("let x : R^3, x = [-1, true, false]; x-=[1,2,3];", "x",
                                   (TinyVector<3>{-1, true, false} - TinyVector<3>{1, 2, 3}));
        }
      }
    
      SECTION("*=")
      {
        SECTION("N")
        {
          CHECK_AFFECTATION_RESULT("let n : N, n = 3; n *= 2;", "n", 6ul);
          CHECK_AFFECTATION_RESULT("let m : N, m = 2; let n : N, n = 4; n *= m;", "n", 8ul);
          CHECK_AFFECTATION_RESULT("let n : N, n = 1; n *= true;", "n", 1ul);
          CHECK_AFFECTATION_RESULT("let n : N, n = 3; n *= false;", "n", 0ul);
        }
    
        SECTION("Z")
        {
          CHECK_AFFECTATION_RESULT("let z : Z, z = 1; z *= 3;", "z", 3l);
          CHECK_AFFECTATION_RESULT("let m : N, m = 2; let z : Z, z = -2; z *= m;", "z", -4l);
          CHECK_AFFECTATION_RESULT("let z : Z, z = 1; z *= true;", "z", 1l);
          CHECK_AFFECTATION_RESULT("let z : Z, z = 3; z *= false;", "z", 0l);
        }
    
        SECTION("R")
        {
          CHECK_AFFECTATION_RESULT("let r : R, r = 1.1; r *= 2;", "r", (1.1 * 2l));
          CHECK_AFFECTATION_RESULT("let m : N, m = 2; let r : R, r = 1.3; r *= m;", "r", (1.3 * 2ul));
          CHECK_AFFECTATION_RESULT("let r : R, r = 1.1; r *= true;", "r", (1.1 * true));
          CHECK_AFFECTATION_RESULT("let r : R, r = 3.3; r *= false;", "r", (3.3 * false));
          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 *= 2;", "x", (TinyVector<1>{TinyVector<1>{2} *= 2}));
        }
    
        SECTION("R^2")
        {
          CHECK_AFFECTATION_RESULT("let x : R^2, x = [-1, true];  x *= 3;", "x",
                                   (TinyVector<2>{TinyVector<2>{-1, 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}));
        }
    
        SECTION("R^1x1")
        {
          CHECK_AFFECTATION_RESULT("let x : R^1x1, x = 2; x *= 2;", "x", (TinyMatrix<1>{TinyMatrix<1>{2} *= 2}));
        }
    
        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}));
        }
    
        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}));
        }
      }
    
      SECTION("/=")
      {
        SECTION("N")
        {
          CHECK_AFFECTATION_RESULT("let n : N, n = 4; n /= 2;", "n", 2ul);
          CHECK_AFFECTATION_RESULT("let m : N, m = 2; let n : N, n = 6; n /= m;", "n", 3ul);
        }
    
        SECTION("Z")
        {
          CHECK_AFFECTATION_RESULT("let z : Z, z = 7; z /= -3;", "z", -2l);
          CHECK_AFFECTATION_RESULT("let m : N, m = 3; let z : Z, z = 6; z /= m;", "z", 2l);
        }
    
        SECTION("R")
        {
          CHECK_AFFECTATION_RESULT("let r : R, r = 1.1; r /= 2;", "r", (1.1 / 2l));
          CHECK_AFFECTATION_RESULT("let m : N, m = 2; let r : R, r = 1.3; r /= m;", "r", (1.3 / 2ul));
          CHECK_AFFECTATION_RESULT("let r : R, r = 2; r /= 1.1;", "r", (2. / 1.1));
        }
      }
    
      SECTION("errors")
      {
        SECTION("invalid affectations")
        {
          SECTION("tuple -> value")
          {
            CHECK_AFFECTATION_EXEC_THROWS_WITH(
              std::string_view{
                R"(
    let t : (B), t = (true, 2>1, false);
    let b : B; b = t;
    )"},
              "cannot affect a (B) of size 3 to a B");
    
            CHECK_AFFECTATION_EXEC_THROWS_WITH(
              std::string_view{
                R"(
    let t :(N), t = (2, 3, 6);
    let z : Z; z = t;
    )"},
              "cannot affect a (N) of size 3 to a Z");
    
            CHECK_AFFECTATION_EXEC_THROWS_WITH(
              std::string_view{
                R"(
    let t :(R^1), t = (2, 3, 6);
    let r : R^1; r = t;
    )"},
              "cannot affect a (R^1) of size 3 to a R^1");
          }
    
          SECTION("-> B")
          {
            CHECK_AFFECTATION_THROWS_WITH("let n : N, n = 1; let b : B; b = n;", "undefined affectation type: B = N");
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b = 1;", "undefined affectation type: B = Z");
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b = 2.3;", "undefined affectation type: B = R");
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b = \"foo\";", "undefined affectation type: B = string");
    
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b += b;", "undefined affectation type: B += B");
            CHECK_AFFECTATION_THROWS_WITH("let n : N, n = 1; let b : B; b += n;", "undefined affectation type: B += N");
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b += 1;", "undefined affectation type: B += Z");
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b += 1.2;", "undefined affectation type: B += R");
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b += \"foo\";", "undefined affectation type: B += string");
    
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b -= b;", "undefined affectation type: B -= B");
            CHECK_AFFECTATION_THROWS_WITH("let n : N, n = 1; let b : B; b -= n;", "undefined affectation type: B -= N");
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b -= 1;", "undefined affectation type: B -= Z");
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b -= 1.2;", "undefined affectation type: B -= R");
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b -= \"foo\";", "undefined affectation type: B -= string");
    
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b *= b;", "undefined affectation type: B *= B");
            CHECK_AFFECTATION_THROWS_WITH("let n : N, n = 1; let b : B; b *= n;", "undefined affectation type: B *= N");
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b *= 1;", "undefined affectation type: B *= Z");
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b *= 1.2;", "undefined affectation type: B *= R");
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b *= \"foo\";", "undefined affectation type: B *= string");
    
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b /= b;", "undefined affectation type: B /= B");
            CHECK_AFFECTATION_THROWS_WITH("let n : N, n = 1; let b : B; b /= n;", "undefined affectation type: B /= N");
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b /= 1;", "undefined affectation type: B /= Z");
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b /= 1.2;", "undefined affectation type: B /= R");
            CHECK_AFFECTATION_THROWS_WITH("let b : B; b /= \"foo\";", "undefined affectation type: B /= string");
          }
    
          SECTION("-> N")
          {
            CHECK_AFFECTATION_THROWS_WITH("let n : N, n = 2.3;", "undefined affectation type: N = R");
            CHECK_AFFECTATION_THROWS_WITH("let n : N, n = \"bar\";", "undefined affectation type: N = string");
            CHECK_AFFECTATION_EXEC_THROWS_WITH("let n : N, n = -2;", "trying to affect negative value (-2)");
    
            CHECK_AFFECTATION_THROWS_WITH("let n : N, n = 2; n += 1.1;", "undefined affectation type: N += R");
            CHECK_AFFECTATION_THROWS_WITH("let n : N, n = 2; n += \"foo\";", "undefined affectation type: N += string");
            CHECK_AFFECTATION_EXEC_THROWS_WITH("let n : N, n = 2; n+=-3;",
                                               "trying to affect negative value (lhs: 2 rhs: -3)");
    
            CHECK_AFFECTATION_THROWS_WITH("let n : N, n = 2; n -= 1.1;", "undefined affectation type: N -= R");
            CHECK_AFFECTATION_THROWS_WITH("let n : N, n = 2; n -= \"bar\";", "undefined affectation type: N -= string");
            CHECK_AFFECTATION_EXEC_THROWS_WITH("let n : N, n = 2; n-=3;",
                                               "trying to affect negative value (lhs: 2 rhs: 3)");
    
            CHECK_AFFECTATION_THROWS_WITH("let n : N, n = 2; n *= 2.51;", "undefined affectation type: N *= R");
            CHECK_AFFECTATION_THROWS_WITH("let n : N, n = 2; n *= \"foobar\";", "undefined affectation type: N *= string");
            CHECK_AFFECTATION_EXEC_THROWS_WITH("let n : N, n = 2; n*= -2;", "trying to affect negative value (-2)");
    
            CHECK_AFFECTATION_THROWS_WITH("let n : N, n = 2; n /= true;", "undefined affectation type: N /= B");
            CHECK_AFFECTATION_THROWS_WITH("let n : N, n = 2; n /= 2.51;", "undefined affectation type: N /= R");
            CHECK_AFFECTATION_THROWS_WITH("let n : N, n = 2; n /= \"foo\";", "undefined affectation type: N /= string");
            CHECK_AFFECTATION_EXEC_THROWS_WITH("let n : N, n = 2; n/= -2;", "trying to affect negative value (-2)");
          }
    
          SECTION("-> Z")
          {
            CHECK_AFFECTATION_THROWS_WITH("let z : Z, z = -2.3;", "undefined affectation type: Z = R");
            CHECK_AFFECTATION_THROWS_WITH("let z : Z, z = \"foobar\";", "undefined affectation type: Z = string");
    
            CHECK_AFFECTATION_THROWS_WITH("let z : Z, z = 2; z += 1.1;", "undefined affectation type: Z += R");
            CHECK_AFFECTATION_THROWS_WITH("let z : Z, z = 2; z += \"foo\";", "undefined affectation type: Z += string");
    
            CHECK_AFFECTATION_THROWS_WITH("let z : Z, z = 2; z -= 2.1;", "undefined affectation type: Z -= R");
            CHECK_AFFECTATION_THROWS_WITH("let z : Z, z = 2; z -= \"bar\";", "undefined affectation type: Z -= string");
    
            CHECK_AFFECTATION_THROWS_WITH("let z : Z, z = 2; z *= -2.51;", "undefined affectation type: Z *= R");
            CHECK_AFFECTATION_THROWS_WITH("let z : Z, z = 2; z *= \"foobar\";", "undefined affectation type: Z *= string");
    
            CHECK_AFFECTATION_THROWS_WITH("let z : Z, z = 4; z /= true;", "undefined affectation type: Z /= B");
            CHECK_AFFECTATION_THROWS_WITH("let z : Z, z = 4; z /= -2.;", "undefined affectation type: Z /= R");
            CHECK_AFFECTATION_THROWS_WITH("let z : Z, z = 2; z /= \"foo\";", "undefined affectation type: Z /= string");
          }
    
          SECTION("-> R")
          {
            CHECK_AFFECTATION_THROWS_WITH("let x : R, x = \"foobar\";", "undefined affectation type: R = string");
            CHECK_AFFECTATION_THROWS_WITH("let x : R, x = 2.3; x += \"foo\";", "undefined affectation type: R += string");
            CHECK_AFFECTATION_THROWS_WITH("let x : R, x = 2.1; x -= \"bar\";", "undefined affectation type: R -= string");
            CHECK_AFFECTATION_THROWS_WITH("let x : R, x = 1.2; x *= \"foobar\";",
                                          "undefined affectation type: R *= string");
    
            CHECK_AFFECTATION_THROWS_WITH("let x : R, x =-2.3; x /= true;", "undefined affectation type: R /= B");
            CHECK_AFFECTATION_THROWS_WITH("let x : R, x =-2.3; x /= \"foo\";", "undefined affectation type: R /= string");
          }
    
          SECTION("-> R^n")
          {
            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^1, x = 0; x /= true;", "undefined affectation type: R^1 /= B");
            CHECK_AFFECTATION_THROWS_WITH("let n:N, n=1; let x : R^1, x = 0; x /= n;",
                                          "undefined affectation type: R^1 /= N");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^1, x = 0; x /= 3;", "undefined affectation type: R^1 /= Z");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^1, x = 0; x /= 3.2;", "undefined affectation type: R^1 /= R");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^1, x = 0; x /= \"foo\";", "undefined affectation type: R^1 /= string");
    
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2, x = 0; x /= true;", "undefined affectation type: R^2 /= B");
            CHECK_AFFECTATION_THROWS_WITH("let n:N, n=1; let x : R^2, x = 0; x /= n;",
                                          "undefined affectation type: R^2 /= N");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2, x = 0; x /= 3;", "undefined affectation type: R^2 /= Z");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2, x = 0; x /= 3.2;", "undefined affectation type: R^2 /= R");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2, x = 0; x /= \"foo\";", "undefined affectation type: R^2 /= string");
    
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3, x = 0; x /= true;", "undefined affectation type: R^3 /= B");
            CHECK_AFFECTATION_THROWS_WITH("let n:N, n=1; let x : R^3, x = 0; x /= n;",
                                          "undefined affectation type: R^3 /= N");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3, x = 0; x /= 3;", "undefined affectation type: R^3 /= Z");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3, x = 0; x /= 3.2;", "undefined affectation type: R^3 /= R");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3, x = 0; x /= \"foo\";", "undefined affectation type: R^3 /= string");
    
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2, x = (1,2);", "undefined affectation type: R^2 = list");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3, x = (1,2,3);", "undefined affectation type: R^3 = list");
          }
    
          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; x = [[1]];", "undefined affectation type: R^1 = R^1x1");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2; x = [[1,2],[4,4]];", "undefined affectation type: R^2 = R^2x2");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3; x = [[1,2,3],[4,5,6],[7,8,9]];",
                                          "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);", "undefined affectation type: R^2 = list");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3, x = (1,2,3);", "undefined affectation type: R^3 = list");
          }
    
          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");
    
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2x2, x = 3.2;", "undefined affectation type: R^2x2 = R");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3x3, x = 2.3;", "undefined affectation type: R^3x3 = R");
    
            CHECK_AFFECTATION_THROWS_WITH("let x : R^1x1; x = [1];", "undefined affectation type: R^1x1 = R^1");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2x2; x = [1,2];", "undefined affectation type: R^2x2 = R^2");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3x3; x = [1,2,3];", "undefined affectation type: R^3x3 = R^3");
    
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2x2; x = 3.2;", "undefined affectation type: R^2x2 = R");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3x3; x = 2.3;", "undefined affectation type: R^3x3 = R");
    
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2x2, x = 4;", "invalid integral value (0 is the solely valid value)");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3x3, x = 3;", "invalid integral value (0 is the solely valid value)");
    
            CHECK_AFFECTATION_THROWS_WITH("let y : R^2x2, y = [[0]];", "undefined affectation type: R^2x2 = R^1x1");
            CHECK_AFFECTATION_THROWS_WITH("let y : R^3x3, y = [[0]];", "undefined affectation type: R^3x3 = R^1x1");
    
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2x2, x = 0; let y : R^1x1, y = x;",
                                          "undefined affectation type: R^1x1 = R^2x2");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2x2, x = 0; let y : R^3x3, y = x;",
                                          "undefined affectation type: R^3x3 = R^2x2");
    
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3x3, x = 0; let y : R^1x1, y = x;",
                                          "undefined affectation type: R^1x1 = R^3x3");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3x3, x = 0; let y : R^2x2, y = x;",
                                          "undefined affectation type: R^2x2 = R^3x3");
    
            CHECK_AFFECTATION_THROWS_WITH("let x : R^1x1, x = (1,2);", "undefined affectation type: R^1x1 = list");
    
            CHECK_AFFECTATION_THROWS_WITH("let x : R^1x1, x = 0; x /= true;", "undefined affectation type: R^1x1 /= B");
            CHECK_AFFECTATION_THROWS_WITH("let n:N, n=1; let x : R^1x1, x = 0; x /= n;",
                                          "undefined affectation type: R^1x1 /= N");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^1x1, x = 0; x /= 3;", "undefined affectation type: R^1x1 /= Z");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^1x1, x = 0; x /= 3.2;", "undefined affectation type: R^1x1 /= R");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^1x1, x = 0; x /= \"foo\";",
                                          "undefined affectation type: R^1x1 /= string");
    
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2x2, x = 0; x /= true;", "undefined affectation type: R^2x2 /= B");
            CHECK_AFFECTATION_THROWS_WITH("let n:N, n=1; let x : R^2x2, x = 0; x /= n;",
                                          "undefined affectation type: R^2x2 /= N");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2x2, x = 0; x /= 3;", "undefined affectation type: R^2x2 /= Z");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2x2, x = 0; x /= 3.2;", "undefined affectation type: R^2x2 /= R");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2x2, x = 0; x /= \"foo\";",
                                          "undefined affectation type: R^2x2 /= string");
    
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3x3, x = 0; x /= true;", "undefined affectation type: R^3x3 /= B");
            CHECK_AFFECTATION_THROWS_WITH("let n:N, n=1; let x : R^3x3, x = 0; x /= n;",
                                          "undefined affectation type: R^3x3 /= N");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3x3, x = 0; x /= 3;", "undefined affectation type: R^3x3 /= Z");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3x3, x = 0; x /= 3.2;", "undefined affectation type: R^3x3 /= R");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3x3, x = 0; x /= \"foo\";",
                                          "undefined affectation type: R^3x3 /= string");
    
            CHECK_AFFECTATION_THROWS_WITH("let x : R^2x2, x = (1,2,3,4);", "undefined affectation type: R^2x2 = list");
            CHECK_AFFECTATION_THROWS_WITH("let x : R^3x3, x = (1,2,3,4,5,6,7,8,9);",
                                          "undefined affectation type: R^3x3 = list");
          }
        }
      }
    }