Skip to content
Snippets Groups Projects
Select Git revision
  • 132301c2e7679401f8ce1fa780d41182ee4495c5
  • 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

ASTNodeDataTypeBuilder.hpp

Blame
  • test_ASTNodeListAffectationExpressionBuilder.cpp 71.99 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/ASTNodeDataTypeBuilder.hpp>
    #include <language/ast/ASTNodeDeclarationToAffectationConverter.hpp>
    #include <language/ast/ASTNodeExpressionBuilder.hpp>
    #include <language/ast/ASTNodeListAffectationExpressionBuilder.hpp>
    #include <language/ast/ASTNodeTypeCleaner.hpp>
    #include <language/ast/ASTSymbolTableBuilder.hpp>
    #include <language/utils/ASTNodeDataTypeTraits.hpp>
    #include <language/utils/ASTPrinter.hpp>
    #include <language/utils/BasicAffectationRegistrerFor.hpp>
    #include <language/utils/TypeDescriptor.hpp>
    #include <utils/Demangle.hpp>
    
    #include <pegtl/string_input.hpp>
    
    template <>
    inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const double>> =
      ASTNodeDataType::build<ASTNodeDataType::type_id_t>("builtin_t");
    const auto builtin_data_type = ast_node_data_type_from<std::shared_ptr<const double>>;
    
    #define CHECK_AST(data, expected_output)                                                                        \
      {                                                                                                             \
        static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>);                              \
        static_assert(std::is_same_v<std::decay_t<decltype(expected_output)>, std::string_view> or                  \
                      std::is_same_v<std::decay_t<decltype(expected_output)>, std::string>);                        \
                                                                                                                    \
        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")}; \
                                                                                                                    \
        ASTNodeTypeCleaner<language::import_instruction>{*ast};                                                     \
        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()));   \
                                                                                                                    \
        ASTSymbolTableBuilder{*ast};                                                                                \
        ASTNodeDataTypeBuilder{*ast};                                                                               \
                                                                                                                    \
        ASTNodeDeclarationToAffectationConverter{*ast};                                                             \
        ASTNodeTypeCleaner<language::var_declaration>{*ast};                                                        \
        ASTNodeTypeCleaner<language::fct_declaration>{*ast};                                                        \
                                                                                                                    \
        ASTNodeExpressionBuilder{*ast};                                                                             \
                                                                                                                    \
        std::stringstream ast_output;                                                                               \
        ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::exec_type}};             \
                                                                                                                    \
        REQUIRE(ast_output.str() == expected_output);                                                               \
      }
    
    #define CHECK_AST_THROWS_WITH(data, error)                                         \
      {                                                                                \
        static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>); \
        static_assert(std::is_same_v<std::decay_t<decltype(error)>, std::string>);     \
                                                                                       \
        TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"};                     \
        auto ast = ASTBuilder::build(input);                                           \
                                                                                       \
        ASTModulesImporter{*ast};                                                      \
        ASTNodeTypeCleaner<language::import_instruction>{*ast};                        \
                                                                                       \
        ASTSymbolTableBuilder{*ast};                                                   \
        ASTNodeDataTypeBuilder{*ast};                                                  \
                                                                                       \
        ASTNodeDeclarationToAffectationConverter{*ast};                                \
        ASTNodeTypeCleaner<language::var_declaration>{*ast};                           \
        ASTNodeTypeCleaner<language::fct_declaration>{*ast};                           \
                                                                                       \
        REQUIRE_THROWS_WITH(ASTNodeExpressionBuilder{*ast}, error);                    \
      }
    
    // clazy:excludeall=non-pod-global-static
    
    TEST_CASE("ASTNodeListAffectationExpressionBuilder", "[language]")
    {
      const std::string demangled_stdstring = demangle(typeid(std::string{}).name());
    
      SECTION("Declaration")
      {
        SECTION("without conversion R*R")
        {
          std::string_view data = R"(
    let (x, y) : R*R, (x,y) = (2.3, 6.2);
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:x:NameProcessor)
         |   `-(language::name:y:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::real:2.3:ValueProcessor)
             `-(language::real:6.2:ValueProcessor)
    )";
    
          CHECK_AST(data, result);
        }
    
        SECTION("without conversion B*Z*N")
        {
          std::string_view data = R"(
    let n:N, n = 2;
    let ( b, z , m ): B*Z*N, (b,z,m) = (false, -2, n);
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
     |   +-(language::name:n:NameProcessor)
     |   `-(language::integer:2:ValueProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:b:NameProcessor)
         |   +-(language::name:z:NameProcessor)
         |   `-(language::name:m:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::false_kw:ValueProcessor)
             +-(language::unary_minus:UnaryExpressionProcessor<language::unary_minus, long, long>)
             |   `-(language::integer:2:ValueProcessor)
             `-(language::name:n:NameProcessor)
    )";
    
          CHECK_AST(data, result);
        }
    
        SECTION("with conversion R*B*Z*N")
        {
          std::string_view data = R"(
    let (r,b,z,m) : R*B*Z*N, (r,b,z,m) = (3.2, true, 6, 2);
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:r:NameProcessor)
         |   +-(language::name:b:NameProcessor)
         |   +-(language::name:z:NameProcessor)
         |   `-(language::name:m:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::real:3.2:ValueProcessor)
             +-(language::true_kw:ValueProcessor)
             +-(language::integer:6:ValueProcessor)
             `-(language::integer:2:ValueProcessor)
    )";
    
          CHECK_AST(data, result);
        }
    
        SECTION("with conversion R*R*R*R")
        {
          std::string_view data = R"(
    let (r,b,z,m): R*R*R*R , (r,b,z,m) = (3.2, 1, 6, 2);
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:r:NameProcessor)
         |   +-(language::name:b:NameProcessor)
         |   +-(language::name:z:NameProcessor)
         |   `-(language::name:m:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::real:3.2:ValueProcessor)
             +-(language::integer:1:ValueProcessor)
             +-(language::integer:6:ValueProcessor)
             `-(language::integer:2:ValueProcessor)
    )";
    
          CHECK_AST(data, result);
        }
    
        SECTION("without conversion R^1*R^2*R^3*R")
        {
          std::string_view data = R"(
    let a:R^1, a = 0;
    let b:R^2, b = [1,2];
    let c:R^3, c = [1,2,3];
    let (x1,x2,x3,x) : R^1*R^2*R^3*R,
        (x1,x2,x3,x) = (a, b, c, 2);
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     +-(language::eq_op:AffectationFromZeroProcessor<TinyVector<1ul, double> >)
     |   +-(language::name:a:NameProcessor)
     |   `-(language::integer:0:ValueProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, TinyVector<2ul, double>, TinyVector<2ul, double> >)
     |   +-(language::name:b:NameProcessor)
     |   `-(language::vector_expression:TinyVectorExpressionProcessor<2ul>)
     |       +-(language::integer:1:ValueProcessor)
     |       `-(language::integer:2:ValueProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, TinyVector<3ul, double>, TinyVector<3ul, double> >)
     |   +-(language::name:c:NameProcessor)
     |   `-(language::vector_expression:TinyVectorExpressionProcessor<3ul>)
     |       +-(language::integer:1:ValueProcessor)
     |       +-(language::integer:2:ValueProcessor)
     |       `-(language::integer:3:ValueProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:x1:NameProcessor)
         |   +-(language::name:x2:NameProcessor)
         |   +-(language::name:x3:NameProcessor)
         |   `-(language::name:x:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::name:a:NameProcessor)
             +-(language::name:b:NameProcessor)
             +-(language::name:c:NameProcessor)
             `-(language::integer:2:ValueProcessor)
    )";
    
          CHECK_AST(data, result);
        }
    
        SECTION("without conversion R^1x1*R^2x2*R^3x3*R")
        {
          std::string_view data = R"(
    let a:R^1x1, a = 0;
    let b:R^2x2, b = [[1, 2], [3, 4]];
    let c:R^3x3, c = [[9, 8, 7], [6, 5, 4], [3, 2, 1]];
    let (x1,x2,x3,x) : R^1x1*R^2x2*R^3x3*R,
        (x1,x2,x3,x) = (a, b, c, 2);
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     +-(language::eq_op:AffectationFromZeroProcessor<TinyMatrix<1ul, 1ul, double> >)
     |   +-(language::name:a:NameProcessor)
     |   `-(language::integer:0:ValueProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, TinyMatrix<2ul, 2ul, double>, TinyMatrix<2ul, 2ul, double> >)
     |   +-(language::name:b:NameProcessor)
     |   `-(language::matrix_expression:TinyMatrixExpressionProcessor<2ul, 2ul>)
     |       +-(language::row_expression:FakeProcessor)
     |       |   +-(language::integer:1:ValueProcessor)
     |       |   `-(language::integer:2:ValueProcessor)
     |       `-(language::row_expression:FakeProcessor)
     |           +-(language::integer:3:ValueProcessor)
     |           `-(language::integer:4:ValueProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, TinyMatrix<3ul, 3ul, double>, TinyMatrix<3ul, 3ul, double> >)
     |   +-(language::name:c:NameProcessor)
     |   `-(language::matrix_expression:TinyMatrixExpressionProcessor<3ul, 3ul>)
     |       +-(language::row_expression:FakeProcessor)
     |       |   +-(language::integer:9:ValueProcessor)
     |       |   +-(language::integer:8:ValueProcessor)
     |       |   `-(language::integer:7:ValueProcessor)
     |       +-(language::row_expression:FakeProcessor)
     |       |   +-(language::integer:6:ValueProcessor)
     |       |   +-(language::integer:5:ValueProcessor)
     |       |   `-(language::integer:4:ValueProcessor)
     |       `-(language::row_expression:FakeProcessor)
     |           +-(language::integer:3:ValueProcessor)
     |           +-(language::integer:2:ValueProcessor)
     |           `-(language::integer:1:ValueProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:x1:NameProcessor)
         |   +-(language::name:x2:NameProcessor)
         |   +-(language::name:x3:NameProcessor)
         |   `-(language::name:x:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::name:a:NameProcessor)
             +-(language::name:b:NameProcessor)
             +-(language::name:c:NameProcessor)
             `-(language::integer:2:ValueProcessor)
    )";
    
          CHECK_AST(data, result);
        }
    
        SECTION("Zero initialization")
        {
          std::string_view data = R"(
    let  (x1,x2,x3,x) : R^1*R^2*R^3*R, (x1,x2,x3,x) = (0, 0, 0, 0);
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:x1:NameProcessor)
         |   +-(language::name:x2:NameProcessor)
         |   +-(language::name:x3:NameProcessor)
         |   `-(language::name:x:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::integer:0:ValueProcessor)
             +-(language::integer:0:ValueProcessor)
             +-(language::integer:0:ValueProcessor)
             `-(language::integer:0:ValueProcessor)
    )";
    
          CHECK_AST(data, result);
        }
    
        SECTION("Zero initialization")
        {
          std::string_view data = R"(
    let  (x1,x2,x3,x) : R^1x1*R^2x2*R^3x3*R, (x1,x2,x3,x) = (0, 0, 0, 0);
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:x1:NameProcessor)
         |   +-(language::name:x2:NameProcessor)
         |   +-(language::name:x3:NameProcessor)
         |   `-(language::name:x:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::integer:0:ValueProcessor)
             +-(language::integer:0:ValueProcessor)
             +-(language::integer:0:ValueProcessor)
             `-(language::integer:0:ValueProcessor)
    )";
    
          CHECK_AST(data, result);
        }
    
        SECTION("with tuples from lists")
        {
          std::string_view data = R"(
    let  (x,n,s) : (R)*(N)*(string), (x,n,s) = ((1.2,3.4), (1,2,3), (2.1,4,3.3,17.2));
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:x:NameProcessor)
         |   +-(language::name:n:NameProcessor)
         |   `-(language::name:s:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::inner_expression_list:InnerListToVectorProcessor)
             |   +-(language::real:1.2:ValueProcessor)
             |   `-(language::real:3.4:ValueProcessor)
             +-(language::inner_expression_list:InnerListToVectorProcessor)
             |   +-(language::integer:1:ValueProcessor)
             |   +-(language::integer:2:ValueProcessor)
             |   `-(language::integer:3:ValueProcessor)
             `-(language::inner_expression_list:InnerListToVectorProcessor)
                 +-(language::real:2.1:ValueProcessor)
                 +-(language::integer:4:ValueProcessor)
                 +-(language::real:3.3:ValueProcessor)
                 `-(language::real:17.2:ValueProcessor)
    )";
    
          CHECK_AST(data, result);
        }
    
        SECTION("with tuples from tuples")
        {
          SECTION("tuple of B")
          {
            std::string_view data = R"(
    let b:(B), b = (true, false);
    let  (b1,b2,b3) : (B)*(B)*(B), (b1,b2,b3) = (b, false, (true, true, false));
    )";
    
            std::string_view result = R"(
    (root:ASTNodeListProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<bool>)
     |   +-(language::name:b:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::true_kw:ValueProcessor)
     |       `-(language::false_kw:ValueProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:b1:NameProcessor)
         |   +-(language::name:b2:NameProcessor)
         |   `-(language::name:b3:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::name:b:NameProcessor)
             +-(language::false_kw:ValueProcessor)
             `-(language::inner_expression_list:InnerListToVectorProcessor)
                 +-(language::true_kw:ValueProcessor)
                 +-(language::true_kw:ValueProcessor)
                 `-(language::false_kw:ValueProcessor)
    )";
    
            CHECK_AST(data, result);
          }
    
          SECTION("tuple of N")
          {
            std::string_view data = R"(
    let b:(B), b = (true, false);
    let n:(N), n = (2, 3, 2);
    let z:(Z), z = (1, 3, 4);
    let i1:N, i1 = 3;
    let i2:N, i2 = 3;
    let (n1,n2,n3,n4,n5,n6,n7,n8) : (N)*(N)*(N)*(N)*(N)*(N)*(N)*(N),
        (n1,n2,n3,n4,n5,n6,n7,n8) = (b, n, z, false, 2, i1, (2, 3, 2), (i1, i2));
    )";
    
            std::string_view result = R"(
    (root:ASTNodeListProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<bool>)
     |   +-(language::name:b:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::true_kw:ValueProcessor)
     |       `-(language::false_kw:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<unsigned long>)
     |   +-(language::name:n:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::integer:2:ValueProcessor)
     |       +-(language::integer:3:ValueProcessor)
     |       `-(language::integer:2:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<long>)
     |   +-(language::name:z:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::integer:1:ValueProcessor)
     |       +-(language::integer:3:ValueProcessor)
     |       `-(language::integer:4:ValueProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
     |   +-(language::name:i1:NameProcessor)
     |   `-(language::integer:3:ValueProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
     |   +-(language::name:i2:NameProcessor)
     |   `-(language::integer:3:ValueProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:n1:NameProcessor)
         |   +-(language::name:n2:NameProcessor)
         |   +-(language::name:n3:NameProcessor)
         |   +-(language::name:n4:NameProcessor)
         |   +-(language::name:n5:NameProcessor)
         |   +-(language::name:n6:NameProcessor)
         |   +-(language::name:n7:NameProcessor)
         |   `-(language::name:n8:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::name:b:NameProcessor)
             +-(language::name:n:NameProcessor)
             +-(language::name:z:NameProcessor)
             +-(language::false_kw:ValueProcessor)
             +-(language::integer:2:ValueProcessor)
             +-(language::name:i1:NameProcessor)
             +-(language::inner_expression_list:InnerListToVectorProcessor)
             |   +-(language::integer:2:ValueProcessor)
             |   +-(language::integer:3:ValueProcessor)
             |   `-(language::integer:2:ValueProcessor)
             `-(language::inner_expression_list:InnerListToVectorProcessor)
                 +-(language::name:i1:NameProcessor)
                 `-(language::name:i2:NameProcessor)
    )";
    
            CHECK_AST(data, result);
          }
    
          SECTION("tuple of Z")
          {
            std::string_view data = R"(
    let b:(B), b = (true, false);
    let n:(N), n = (2, 3, 2);
    let z:(Z), z = (1, 3, 4);
    let i1:N, i1 = 3;
    let i2:N, i2 = 3;
    let (z1,z2,z3,z4,z5,z6,z7,z8) : (Z)*(Z)*(Z)*(Z)*(Z)*(Z)*(Z)*(Z),
        (z1,z2,z3,z4,z5,z6,z7,z8) = (b, n, z, false, 2, i1, (2, 3, 2), (i1, i2));
    )";
    
            std::string_view result = R"(
    (root:ASTNodeListProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<bool>)
     |   +-(language::name:b:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::true_kw:ValueProcessor)
     |       `-(language::false_kw:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<unsigned long>)
     |   +-(language::name:n:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::integer:2:ValueProcessor)
     |       +-(language::integer:3:ValueProcessor)
     |       `-(language::integer:2:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<long>)
     |   +-(language::name:z:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::integer:1:ValueProcessor)
     |       +-(language::integer:3:ValueProcessor)
     |       `-(language::integer:4:ValueProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
     |   +-(language::name:i1:NameProcessor)
     |   `-(language::integer:3:ValueProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
     |   +-(language::name:i2:NameProcessor)
     |   `-(language::integer:3:ValueProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:z1:NameProcessor)
         |   +-(language::name:z2:NameProcessor)
         |   +-(language::name:z3:NameProcessor)
         |   +-(language::name:z4:NameProcessor)
         |   +-(language::name:z5:NameProcessor)
         |   +-(language::name:z6:NameProcessor)
         |   +-(language::name:z7:NameProcessor)
         |   `-(language::name:z8:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::name:b:NameProcessor)
             +-(language::name:n:NameProcessor)
             +-(language::name:z:NameProcessor)
             +-(language::false_kw:ValueProcessor)
             +-(language::integer:2:ValueProcessor)
             +-(language::name:i1:NameProcessor)
             +-(language::inner_expression_list:InnerListToVectorProcessor)
             |   +-(language::integer:2:ValueProcessor)
             |   +-(language::integer:3:ValueProcessor)
             |   `-(language::integer:2:ValueProcessor)
             `-(language::inner_expression_list:InnerListToVectorProcessor)
                 +-(language::name:i1:NameProcessor)
                 `-(language::name:i2:NameProcessor)
    )";
    
            CHECK_AST(data, result);
          }
    
          SECTION("tuple of R")
          {
            std::string_view data = R"(
    let b:(B), b = (true, false);
    let n:(N), n = (2, 3, 2);
    let z:(Z), z = (1, 3, 4);
    let r:(R), r = (1.2, 3.3, 2.4);
    let i1:N, i1 = 3;
    let i2:N, i2 = 3;
    let (r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11) : (R)*(R)*(R)*(R)*(R)*(R)*(R)*(R)*(R)*(R)*(R),
        (r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11) = (b, n, z, r, true, 2, i1, 2.3, (2, 3, 2), (i1, i2), (2.2, 1.4));
    )";
    
            std::string_view result = R"(
    (root:ASTNodeListProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<bool>)
     |   +-(language::name:b:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::true_kw:ValueProcessor)
     |       `-(language::false_kw:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<unsigned long>)
     |   +-(language::name:n:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::integer:2:ValueProcessor)
     |       +-(language::integer:3:ValueProcessor)
     |       `-(language::integer:2:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<long>)
     |   +-(language::name:z:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::integer:1:ValueProcessor)
     |       +-(language::integer:3:ValueProcessor)
     |       `-(language::integer:4:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<double>)
     |   +-(language::name:r:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::real:1.2:ValueProcessor)
     |       +-(language::real:3.3:ValueProcessor)
     |       `-(language::real:2.4:ValueProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
     |   +-(language::name:i1:NameProcessor)
     |   `-(language::integer:3:ValueProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
     |   +-(language::name:i2:NameProcessor)
     |   `-(language::integer:3:ValueProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:r1:NameProcessor)
         |   +-(language::name:r2:NameProcessor)
         |   +-(language::name:r3:NameProcessor)
         |   +-(language::name:r4:NameProcessor)
         |   +-(language::name:r5:NameProcessor)
         |   +-(language::name:r6:NameProcessor)
         |   +-(language::name:r7:NameProcessor)
         |   +-(language::name:r8:NameProcessor)
         |   +-(language::name:r9:NameProcessor)
         |   +-(language::name:r10:NameProcessor)
         |   `-(language::name:r11:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::name:b:NameProcessor)
             +-(language::name:n:NameProcessor)
             +-(language::name:z:NameProcessor)
             +-(language::name:r:NameProcessor)
             +-(language::true_kw:ValueProcessor)
             +-(language::integer:2:ValueProcessor)
             +-(language::name:i1:NameProcessor)
             +-(language::real:2.3:ValueProcessor)
             +-(language::inner_expression_list:InnerListToVectorProcessor)
             |   +-(language::integer:2:ValueProcessor)
             |   +-(language::integer:3:ValueProcessor)
             |   `-(language::integer:2:ValueProcessor)
             +-(language::inner_expression_list:InnerListToVectorProcessor)
             |   +-(language::name:i1:NameProcessor)
             |   `-(language::name:i2:NameProcessor)
             `-(language::inner_expression_list:InnerListToVectorProcessor)
                 +-(language::real:2.2:ValueProcessor)
                 `-(language::real:1.4:ValueProcessor)
    )";
    
            CHECK_AST(data, result);
          }
    
          SECTION("tuple of string")
          {
            std::string_view data = R"(
    let b:(B), b = (true, false);
    let n:(N), n = (2, 3, 2);
    let z:(Z), z = (1, 3, 4);
    let r:(R), r = (1.2, 3.3, 2.4);
    let s:(string), s = ("foo", "bar");
    let i1:N, i1 = 3;
    let i2:N, i2 = 3;
    let (s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13):
           (string)*(string)*(string)*(string)*(string)*(string)*(string)*(string)*(string)*(string)*(string)*(string)*(string),
        (s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13)
           = (b, n, z, r, s, 2, i1, 2.3, "foobar", (2, 3, 2), (i1, i2), (2.2, 1.4), ("hello", "world"));
    
    let v1:(R^1), v1 = (2, [3], [5]);
    let v2:(R^2), v2 = ([2,3], [3,5]);
    let v3:(R^3), v3 = ([2,2,3], 0, [1,3,5]);
    let A1:(R^1x1), A1 = (2, [[3]]);
    let A2:(R^2x2), A2 = ([[2,3], [3,5]],0);
    let A3:(R^3x3), A3 = ([[2,2,3], [1,2,7], [1,3,5]], [[1,3,2], [6,3,5], [3,2,-1]]);
    let (t1,t2,t3,t4,t5,t6,t7,t8,t9,t10):
           (string)*(string)*(string)*(string)*(string)*(string)*(string)*(string)*(string)*(string),
        (t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
          = (v1, v2, v3, A1, A2, A3, [[0]], [2,3], [[1,2],[3,4]], ([1,2,3], [2,3,1]));
    
    let (u1,u2,u3,u4): (string)*(string)*(string)*(string),
        (u1,u2,u3,u4) = (true, [1], [1,2,3], [[1,2,3],[4,5,6],[7,8,9]]);
    )";
    
            std::string result = R"(
    (root:ASTNodeListProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<bool>)
     |   +-(language::name:b:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::true_kw:ValueProcessor)
     |       `-(language::false_kw:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<unsigned long>)
     |   +-(language::name:n:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::integer:2:ValueProcessor)
     |       +-(language::integer:3:ValueProcessor)
     |       `-(language::integer:2:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<long>)
     |   +-(language::name:z:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::integer:1:ValueProcessor)
     |       +-(language::integer:3:ValueProcessor)
     |       `-(language::integer:4:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<double>)
     |   +-(language::name:r:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::real:1.2:ValueProcessor)
     |       +-(language::real:3.3:ValueProcessor)
     |       `-(language::real:2.4:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<)" +
                                 demangled_stdstring + R"( >)
     |   +-(language::name:s:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::literal:"foo":ValueProcessor)
     |       `-(language::literal:"bar":ValueProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
     |   +-(language::name:i1:NameProcessor)
     |   `-(language::integer:3:ValueProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
     |   +-(language::name:i2:NameProcessor)
     |   `-(language::integer:3:ValueProcessor)
     +-(language::eq_op:ListAffectationProcessor<language::eq_op>)
     |   +-(language::name_list:FakeProcessor)
     |   |   +-(language::name:s1:NameProcessor)
     |   |   +-(language::name:s2:NameProcessor)
     |   |   +-(language::name:s3:NameProcessor)
     |   |   +-(language::name:s4:NameProcessor)
     |   |   +-(language::name:s5:NameProcessor)
     |   |   +-(language::name:s6:NameProcessor)
     |   |   +-(language::name:s7:NameProcessor)
     |   |   +-(language::name:s8:NameProcessor)
     |   |   +-(language::name:s9:NameProcessor)
     |   |   +-(language::name:s10:NameProcessor)
     |   |   +-(language::name:s11:NameProcessor)
     |   |   +-(language::name:s12:NameProcessor)
     |   |   `-(language::name:s13:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::name:b:NameProcessor)
     |       +-(language::name:n:NameProcessor)
     |       +-(language::name:z:NameProcessor)
     |       +-(language::name:r:NameProcessor)
     |       +-(language::name:s:NameProcessor)
     |       +-(language::integer:2:ValueProcessor)
     |       +-(language::name:i1:NameProcessor)
     |       +-(language::real:2.3:ValueProcessor)
     |       +-(language::literal:"foobar":ValueProcessor)
     |       +-(language::inner_expression_list:InnerListToVectorProcessor)
     |       |   +-(language::integer:2:ValueProcessor)
     |       |   +-(language::integer:3:ValueProcessor)
     |       |   `-(language::integer:2:ValueProcessor)
     |       +-(language::inner_expression_list:InnerListToVectorProcessor)
     |       |   +-(language::name:i1:NameProcessor)
     |       |   `-(language::name:i2:NameProcessor)
     |       +-(language::inner_expression_list:InnerListToVectorProcessor)
     |       |   +-(language::real:2.2:ValueProcessor)
     |       |   `-(language::real:1.4:ValueProcessor)
     |       `-(language::inner_expression_list:InnerListToVectorProcessor)
     |           +-(language::literal:"hello":ValueProcessor)
     |           `-(language::literal:"world":ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<TinyVector<1ul, double> >)
     |   +-(language::name:v1:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::integer:2:ValueProcessor)
     |       +-(language::vector_expression:TinyVectorExpressionProcessor<1ul>)
     |       |   `-(language::integer:3:ValueProcessor)
     |       `-(language::vector_expression:TinyVectorExpressionProcessor<1ul>)
     |           `-(language::integer:5:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<TinyVector<2ul, double> >)
     |   +-(language::name:v2:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::vector_expression:TinyVectorExpressionProcessor<2ul>)
     |       |   +-(language::integer:2:ValueProcessor)
     |       |   `-(language::integer:3:ValueProcessor)
     |       `-(language::vector_expression:TinyVectorExpressionProcessor<2ul>)
     |           +-(language::integer:3:ValueProcessor)
     |           `-(language::integer:5:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<TinyVector<3ul, double> >)
     |   +-(language::name:v3:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::vector_expression:TinyVectorExpressionProcessor<3ul>)
     |       |   +-(language::integer:2:ValueProcessor)
     |       |   +-(language::integer:2:ValueProcessor)
     |       |   `-(language::integer:3:ValueProcessor)
     |       +-(language::integer:0:ValueProcessor)
     |       `-(language::vector_expression:TinyVectorExpressionProcessor<3ul>)
     |           +-(language::integer:1:ValueProcessor)
     |           +-(language::integer:3:ValueProcessor)
     |           `-(language::integer:5:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<TinyMatrix<1ul, 1ul, double> >)
     |   +-(language::name:A1:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::integer:2:ValueProcessor)
     |       `-(language::matrix_expression:TinyMatrixExpressionProcessor<1ul, 1ul>)
     |           `-(language::row_expression:FakeProcessor)
     |               `-(language::integer:3:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<TinyMatrix<2ul, 2ul, double> >)
     |   +-(language::name:A2:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::matrix_expression:TinyMatrixExpressionProcessor<2ul, 2ul>)
     |       |   +-(language::row_expression:FakeProcessor)
     |       |   |   +-(language::integer:2:ValueProcessor)
     |       |   |   `-(language::integer:3:ValueProcessor)
     |       |   `-(language::row_expression:FakeProcessor)
     |       |       +-(language::integer:3:ValueProcessor)
     |       |       `-(language::integer:5:ValueProcessor)
     |       `-(language::integer:0:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<TinyMatrix<3ul, 3ul, double> >)
     |   +-(language::name:A3:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::matrix_expression:TinyMatrixExpressionProcessor<3ul, 3ul>)
     |       |   +-(language::row_expression:FakeProcessor)
     |       |   |   +-(language::integer:2:ValueProcessor)
     |       |   |   +-(language::integer:2:ValueProcessor)
     |       |   |   `-(language::integer:3:ValueProcessor)
     |       |   +-(language::row_expression:FakeProcessor)
     |       |   |   +-(language::integer:1:ValueProcessor)
     |       |   |   +-(language::integer:2:ValueProcessor)
     |       |   |   `-(language::integer:7:ValueProcessor)
     |       |   `-(language::row_expression:FakeProcessor)
     |       |       +-(language::integer:1:ValueProcessor)
     |       |       +-(language::integer:3:ValueProcessor)
     |       |       `-(language::integer:5:ValueProcessor)
     |       `-(language::matrix_expression:TinyMatrixExpressionProcessor<3ul, 3ul>)
     |           +-(language::row_expression:FakeProcessor)
     |           |   +-(language::integer:1:ValueProcessor)
     |           |   +-(language::integer:3:ValueProcessor)
     |           |   `-(language::integer:2:ValueProcessor)
     |           +-(language::row_expression:FakeProcessor)
     |           |   +-(language::integer:6:ValueProcessor)
     |           |   +-(language::integer:3:ValueProcessor)
     |           |   `-(language::integer:5:ValueProcessor)
     |           `-(language::row_expression:FakeProcessor)
     |               +-(language::integer:3:ValueProcessor)
     |               +-(language::integer:2:ValueProcessor)
     |               `-(language::unary_minus:UnaryExpressionProcessor<language::unary_minus, long, long>)
     |                   `-(language::integer:1:ValueProcessor)
     +-(language::eq_op:ListAffectationProcessor<language::eq_op>)
     |   +-(language::name_list:FakeProcessor)
     |   |   +-(language::name:t1:NameProcessor)
     |   |   +-(language::name:t2:NameProcessor)
     |   |   +-(language::name:t3:NameProcessor)
     |   |   +-(language::name:t4:NameProcessor)
     |   |   +-(language::name:t5:NameProcessor)
     |   |   +-(language::name:t6:NameProcessor)
     |   |   +-(language::name:t7:NameProcessor)
     |   |   +-(language::name:t8:NameProcessor)
     |   |   +-(language::name:t9:NameProcessor)
     |   |   `-(language::name:t10:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::name:v1:NameProcessor)
     |       +-(language::name:v2:NameProcessor)
     |       +-(language::name:v3:NameProcessor)
     |       +-(language::name:A1:NameProcessor)
     |       +-(language::name:A2:NameProcessor)
     |       +-(language::name:A3:NameProcessor)
     |       +-(language::matrix_expression:TinyMatrixExpressionProcessor<1ul, 1ul>)
     |       |   `-(language::row_expression:FakeProcessor)
     |       |       `-(language::integer:0:ValueProcessor)
     |       +-(language::vector_expression:TinyVectorExpressionProcessor<2ul>)
     |       |   +-(language::integer:2:ValueProcessor)
     |       |   `-(language::integer:3:ValueProcessor)
     |       +-(language::matrix_expression:TinyMatrixExpressionProcessor<2ul, 2ul>)
     |       |   +-(language::row_expression:FakeProcessor)
     |       |   |   +-(language::integer:1:ValueProcessor)
     |       |   |   `-(language::integer:2:ValueProcessor)
     |       |   `-(language::row_expression:FakeProcessor)
     |       |       +-(language::integer:3:ValueProcessor)
     |       |       `-(language::integer:4:ValueProcessor)
     |       `-(language::inner_expression_list:InnerListToVectorProcessor)
     |           +-(language::vector_expression:TinyVectorExpressionProcessor<3ul>)
     |           |   +-(language::integer:1:ValueProcessor)
     |           |   +-(language::integer:2:ValueProcessor)
     |           |   `-(language::integer:3:ValueProcessor)
     |           `-(language::vector_expression:TinyVectorExpressionProcessor<3ul>)
     |               +-(language::integer:2:ValueProcessor)
     |               +-(language::integer:3:ValueProcessor)
     |               `-(language::integer:1:ValueProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:u1:NameProcessor)
         |   +-(language::name:u2:NameProcessor)
         |   +-(language::name:u3:NameProcessor)
         |   `-(language::name:u4:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::true_kw:ValueProcessor)
             +-(language::vector_expression:TinyVectorExpressionProcessor<1ul>)
             |   `-(language::integer:1:ValueProcessor)
             +-(language::vector_expression:TinyVectorExpressionProcessor<3ul>)
             |   +-(language::integer:1:ValueProcessor)
             |   +-(language::integer:2:ValueProcessor)
             |   `-(language::integer:3:ValueProcessor)
             `-(language::matrix_expression:TinyMatrixExpressionProcessor<3ul, 3ul>)
                 +-(language::row_expression:FakeProcessor)
                 |   +-(language::integer:1:ValueProcessor)
                 |   +-(language::integer:2:ValueProcessor)
                 |   `-(language::integer:3:ValueProcessor)
                 +-(language::row_expression:FakeProcessor)
                 |   +-(language::integer:4:ValueProcessor)
                 |   +-(language::integer:5:ValueProcessor)
                 |   `-(language::integer:6:ValueProcessor)
                 `-(language::row_expression:FakeProcessor)
                     +-(language::integer:7:ValueProcessor)
                     +-(language::integer:8:ValueProcessor)
                     `-(language::integer:9:ValueProcessor)
    )";
    
            CHECK_AST(data, result);
          }
    
          SECTION("tuple of R^1")
          {
            std::string_view data = R"(
    let b:(B), b = (true, false);
    let n:(N), n = (2, 3, 2);
    let z:(Z), z = (1, 3, 4);
    let r:(R), r = (1.2, 3.3, 2.4);
    let X:(R^1), X = (1.2, [3.3], 2.4);
    let i1:N, i1 = 3;
    let i2:N, i2 = 3;
    let (X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,X13,X14) : (R^1)*(R^1)*(R^1)*(R^1)*(R^1)*(R^1)*(R^1)*(R^1)*(R^1)*(R^1)*(R^1)*(R^1)*(R^1)*(R^1),
        (X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,X13,X14) = (b, n, z, r, true, 2, i1, 2.3, [1.2], X, (2, 3, 2), (i1, i2), (2.2, 1.4), ([1], [2]));
    )";
    
            std::string_view result = R"(
    (root:ASTNodeListProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<bool>)
     |   +-(language::name:b:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::true_kw:ValueProcessor)
     |       `-(language::false_kw:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<unsigned long>)
     |   +-(language::name:n:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::integer:2:ValueProcessor)
     |       +-(language::integer:3:ValueProcessor)
     |       `-(language::integer:2:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<long>)
     |   +-(language::name:z:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::integer:1:ValueProcessor)
     |       +-(language::integer:3:ValueProcessor)
     |       `-(language::integer:4:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<double>)
     |   +-(language::name:r:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::real:1.2:ValueProcessor)
     |       +-(language::real:3.3:ValueProcessor)
     |       `-(language::real:2.4:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<TinyVector<1ul, double> >)
     |   +-(language::name:X:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::real:1.2:ValueProcessor)
     |       +-(language::vector_expression:TinyVectorExpressionProcessor<1ul>)
     |       |   `-(language::real:3.3:ValueProcessor)
     |       `-(language::real:2.4:ValueProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
     |   +-(language::name:i1:NameProcessor)
     |   `-(language::integer:3:ValueProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
     |   +-(language::name:i2:NameProcessor)
     |   `-(language::integer:3:ValueProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:X1:NameProcessor)
         |   +-(language::name:X2:NameProcessor)
         |   +-(language::name:X3:NameProcessor)
         |   +-(language::name:X4:NameProcessor)
         |   +-(language::name:X5:NameProcessor)
         |   +-(language::name:X6:NameProcessor)
         |   +-(language::name:X7:NameProcessor)
         |   +-(language::name:X8:NameProcessor)
         |   +-(language::name:X9:NameProcessor)
         |   +-(language::name:X10:NameProcessor)
         |   +-(language::name:X11:NameProcessor)
         |   +-(language::name:X12:NameProcessor)
         |   +-(language::name:X13:NameProcessor)
         |   `-(language::name:X14:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::name:b:NameProcessor)
             +-(language::name:n:NameProcessor)
             +-(language::name:z:NameProcessor)
             +-(language::name:r:NameProcessor)
             +-(language::true_kw:ValueProcessor)
             +-(language::integer:2:ValueProcessor)
             +-(language::name:i1:NameProcessor)
             +-(language::real:2.3:ValueProcessor)
             +-(language::vector_expression:TinyVectorExpressionProcessor<1ul>)
             |   `-(language::real:1.2:ValueProcessor)
             +-(language::name:X:NameProcessor)
             +-(language::inner_expression_list:InnerListToVectorProcessor)
             |   +-(language::integer:2:ValueProcessor)
             |   +-(language::integer:3:ValueProcessor)
             |   `-(language::integer:2:ValueProcessor)
             +-(language::inner_expression_list:InnerListToVectorProcessor)
             |   +-(language::name:i1:NameProcessor)
             |   `-(language::name:i2:NameProcessor)
             +-(language::inner_expression_list:InnerListToVectorProcessor)
             |   +-(language::real:2.2:ValueProcessor)
             |   `-(language::real:1.4:ValueProcessor)
             `-(language::inner_expression_list:InnerListToVectorProcessor)
                 +-(language::vector_expression:TinyVectorExpressionProcessor<1ul>)
                 |   `-(language::integer:1:ValueProcessor)
                 `-(language::vector_expression:TinyVectorExpressionProcessor<1ul>)
                     `-(language::integer:2:ValueProcessor)
    )";
    
            CHECK_AST(data, result);
          }
    
          SECTION("tuple of R^2")
          {
            std::string_view data = R"(
    let X:(R^2), X = ([1.2,2], 0, [2.4, 2]);
    let (X1,X2,X3) : (R^2)*(R^2)*(R^2), (X1,X2,X3) = (X, [1,2], ([0,2], [1,0]));
    )";
    
            std::string_view result = R"(
    (root:ASTNodeListProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<TinyVector<2ul, double> >)
     |   +-(language::name:X:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::vector_expression:TinyVectorExpressionProcessor<2ul>)
     |       |   +-(language::real:1.2:ValueProcessor)
     |       |   `-(language::integer:2:ValueProcessor)
     |       +-(language::integer:0:ValueProcessor)
     |       `-(language::vector_expression:TinyVectorExpressionProcessor<2ul>)
     |           +-(language::real:2.4:ValueProcessor)
     |           `-(language::integer:2:ValueProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:X1:NameProcessor)
         |   +-(language::name:X2:NameProcessor)
         |   `-(language::name:X3:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::name:X:NameProcessor)
             +-(language::vector_expression:TinyVectorExpressionProcessor<2ul>)
             |   +-(language::integer:1:ValueProcessor)
             |   `-(language::integer:2:ValueProcessor)
             `-(language::inner_expression_list:InnerListToVectorProcessor)
                 +-(language::vector_expression:TinyVectorExpressionProcessor<2ul>)
                 |   +-(language::integer:0:ValueProcessor)
                 |   `-(language::integer:2:ValueProcessor)
                 `-(language::vector_expression:TinyVectorExpressionProcessor<2ul>)
                     +-(language::integer:1:ValueProcessor)
                     `-(language::integer:0:ValueProcessor)
    )";
    
            CHECK_AST(data, result);
          }
    
          SECTION("tuple of R^3")
          {
            std::string_view data = R"(
    let X:(R^3), X = ([1.2,2,4.2], 0, [2.4, 1, 2]);
    let (X1,X2,X3) : (R^3)*(R^3)*(R^3), (X1,X2,X3) = (X, [2,1,4], ([0,2,1.2], [1,2.1,3.1]));
    )";
    
            std::string_view result = R"(
    (root:ASTNodeListProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<TinyVector<3ul, double> >)
     |   +-(language::name:X:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::vector_expression:TinyVectorExpressionProcessor<3ul>)
     |       |   +-(language::real:1.2:ValueProcessor)
     |       |   +-(language::integer:2:ValueProcessor)
     |       |   `-(language::real:4.2:ValueProcessor)
     |       +-(language::integer:0:ValueProcessor)
     |       `-(language::vector_expression:TinyVectorExpressionProcessor<3ul>)
     |           +-(language::real:2.4:ValueProcessor)
     |           +-(language::integer:1:ValueProcessor)
     |           `-(language::integer:2:ValueProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:X1:NameProcessor)
         |   +-(language::name:X2:NameProcessor)
         |   `-(language::name:X3:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::name:X:NameProcessor)
             +-(language::vector_expression:TinyVectorExpressionProcessor<3ul>)
             |   +-(language::integer:2:ValueProcessor)
             |   +-(language::integer:1:ValueProcessor)
             |   `-(language::integer:4:ValueProcessor)
             `-(language::inner_expression_list:InnerListToVectorProcessor)
                 +-(language::vector_expression:TinyVectorExpressionProcessor<3ul>)
                 |   +-(language::integer:0:ValueProcessor)
                 |   +-(language::integer:2:ValueProcessor)
                 |   `-(language::real:1.2:ValueProcessor)
                 `-(language::vector_expression:TinyVectorExpressionProcessor<3ul>)
                     +-(language::integer:1:ValueProcessor)
                     +-(language::real:2.1:ValueProcessor)
                     `-(language::real:3.1:ValueProcessor)
    )";
    
            CHECK_AST(data, result);
          }
    
          SECTION("tuple of R^1x1")
          {
            std::string_view data = R"(
    let b:(B), b = (true, false);
    let n:(N), n = (2, 3, 2);
    let z:(Z), z = (1, 3, 4);
    let r:(R), r = (1.2, 3.3, 2.4);
    let A:(R^1x1), A = (1.2, [[3.3]], 2.4);
    let i1:N, i1 = 3;
    let i2:N, i2 = 3;
    let (A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14) : (R^1x1)*(R^1x1)*(R^1x1)*(R^1x1)*(R^1x1)*(R^1x1)*(R^1x1)*(R^1x1)*(R^1x1)*(R^1x1)*(R^1x1)*(R^1x1)*(R^1x1)*(R^1x1),
        (A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14) = (b, n, z, r, true, 2, i1, 2.3, [[1.2]], A, (2, 3, 2), (i1, i2), (2.2, 1.4), ([[1]], [[2]]));
    )";
    
            std::string_view result = R"(
    (root:ASTNodeListProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<bool>)
     |   +-(language::name:b:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::true_kw:ValueProcessor)
     |       `-(language::false_kw:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<unsigned long>)
     |   +-(language::name:n:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::integer:2:ValueProcessor)
     |       +-(language::integer:3:ValueProcessor)
     |       `-(language::integer:2:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<long>)
     |   +-(language::name:z:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::integer:1:ValueProcessor)
     |       +-(language::integer:3:ValueProcessor)
     |       `-(language::integer:4:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<double>)
     |   +-(language::name:r:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::real:1.2:ValueProcessor)
     |       +-(language::real:3.3:ValueProcessor)
     |       `-(language::real:2.4:ValueProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<TinyMatrix<1ul, 1ul, double> >)
     |   +-(language::name:A:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::real:1.2:ValueProcessor)
     |       +-(language::matrix_expression:TinyMatrixExpressionProcessor<1ul, 1ul>)
     |       |   `-(language::row_expression:FakeProcessor)
     |       |       `-(language::real:3.3:ValueProcessor)
     |       `-(language::real:2.4:ValueProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
     |   +-(language::name:i1:NameProcessor)
     |   `-(language::integer:3:ValueProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
     |   +-(language::name:i2:NameProcessor)
     |   `-(language::integer:3:ValueProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:A1:NameProcessor)
         |   +-(language::name:A2:NameProcessor)
         |   +-(language::name:A3:NameProcessor)
         |   +-(language::name:A4:NameProcessor)
         |   +-(language::name:A5:NameProcessor)
         |   +-(language::name:A6:NameProcessor)
         |   +-(language::name:A7:NameProcessor)
         |   +-(language::name:A8:NameProcessor)
         |   +-(language::name:A9:NameProcessor)
         |   +-(language::name:A10:NameProcessor)
         |   +-(language::name:A11:NameProcessor)
         |   +-(language::name:A12:NameProcessor)
         |   +-(language::name:A13:NameProcessor)
         |   `-(language::name:A14:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::name:b:NameProcessor)
             +-(language::name:n:NameProcessor)
             +-(language::name:z:NameProcessor)
             +-(language::name:r:NameProcessor)
             +-(language::true_kw:ValueProcessor)
             +-(language::integer:2:ValueProcessor)
             +-(language::name:i1:NameProcessor)
             +-(language::real:2.3:ValueProcessor)
             +-(language::matrix_expression:TinyMatrixExpressionProcessor<1ul, 1ul>)
             |   `-(language::row_expression:FakeProcessor)
             |       `-(language::real:1.2:ValueProcessor)
             +-(language::name:A:NameProcessor)
             +-(language::inner_expression_list:InnerListToVectorProcessor)
             |   +-(language::integer:2:ValueProcessor)
             |   +-(language::integer:3:ValueProcessor)
             |   `-(language::integer:2:ValueProcessor)
             +-(language::inner_expression_list:InnerListToVectorProcessor)
             |   +-(language::name:i1:NameProcessor)
             |   `-(language::name:i2:NameProcessor)
             +-(language::inner_expression_list:InnerListToVectorProcessor)
             |   +-(language::real:2.2:ValueProcessor)
             |   `-(language::real:1.4:ValueProcessor)
             `-(language::inner_expression_list:InnerListToVectorProcessor)
                 +-(language::matrix_expression:TinyMatrixExpressionProcessor<1ul, 1ul>)
                 |   `-(language::row_expression:FakeProcessor)
                 |       `-(language::integer:1:ValueProcessor)
                 `-(language::matrix_expression:TinyMatrixExpressionProcessor<1ul, 1ul>)
                     `-(language::row_expression:FakeProcessor)
                         `-(language::integer:2:ValueProcessor)
    )";
    
            CHECK_AST(data, result);
          }
    
          SECTION("tuple of embedded data")
          {
            std::string_view data = R"(
    let b: builtin_t, b = b;
    let tb: (builtin_t), tb = (b,b);
    let (tb1,tb2,tb3): (builtin_t)*(builtin_t)*(builtin_t), (tb1,tb2,tb3) = (b,tb, (b,b,b));
    )";
    
            std::string_view result = R"(
    (root:ASTNodeListProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, EmbeddedData, EmbeddedData>)
     |   +-(language::name:b:NameProcessor)
     |   `-(language::name:b:NameProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<EmbeddedData>)
     |   +-(language::name:tb:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::name:b:NameProcessor)
     |       `-(language::name:b:NameProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:tb1:NameProcessor)
         |   +-(language::name:tb2:NameProcessor)
         |   `-(language::name:tb3:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::name:b:NameProcessor)
             +-(language::name:tb:NameProcessor)
             `-(language::inner_expression_list:InnerListToVectorProcessor)
                 +-(language::name:b:NameProcessor)
                 +-(language::name:b:NameProcessor)
                 `-(language::name:b:NameProcessor)
    )";
    
            CHECK_AST(data, result);
          }
        }
    
        SECTION("tuple of R^2x2")
        {
          std::string_view data = R"(
    let A:(R^2x2), A = ([[1.2,2],[2.1,1]], 0, [[1.4, 2],[2.4, 2]]);
    let (A1,A2,A3) : (R^2x2)*(R^2x2)*(R^2x2), (A1,A2,A3) = (A, [[1,2],[4,1]], ([[0,2], [1,0]], [[1.3,2], [3,1]]));
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<TinyMatrix<2ul, 2ul, double> >)
     |   +-(language::name:A:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::matrix_expression:TinyMatrixExpressionProcessor<2ul, 2ul>)
     |       |   +-(language::row_expression:FakeProcessor)
     |       |   |   +-(language::real:1.2:ValueProcessor)
     |       |   |   `-(language::integer:2:ValueProcessor)
     |       |   `-(language::row_expression:FakeProcessor)
     |       |       +-(language::real:2.1:ValueProcessor)
     |       |       `-(language::integer:1:ValueProcessor)
     |       +-(language::integer:0:ValueProcessor)
     |       `-(language::matrix_expression:TinyMatrixExpressionProcessor<2ul, 2ul>)
     |           +-(language::row_expression:FakeProcessor)
     |           |   +-(language::real:1.4:ValueProcessor)
     |           |   `-(language::integer:2:ValueProcessor)
     |           `-(language::row_expression:FakeProcessor)
     |               +-(language::real:2.4:ValueProcessor)
     |               `-(language::integer:2:ValueProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:A1:NameProcessor)
         |   +-(language::name:A2:NameProcessor)
         |   `-(language::name:A3:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::name:A:NameProcessor)
             +-(language::matrix_expression:TinyMatrixExpressionProcessor<2ul, 2ul>)
             |   +-(language::row_expression:FakeProcessor)
             |   |   +-(language::integer:1:ValueProcessor)
             |   |   `-(language::integer:2:ValueProcessor)
             |   `-(language::row_expression:FakeProcessor)
             |       +-(language::integer:4:ValueProcessor)
             |       `-(language::integer:1:ValueProcessor)
             `-(language::inner_expression_list:InnerListToVectorProcessor)
                 +-(language::matrix_expression:TinyMatrixExpressionProcessor<2ul, 2ul>)
                 |   +-(language::row_expression:FakeProcessor)
                 |   |   +-(language::integer:0:ValueProcessor)
                 |   |   `-(language::integer:2:ValueProcessor)
                 |   `-(language::row_expression:FakeProcessor)
                 |       +-(language::integer:1:ValueProcessor)
                 |       `-(language::integer:0:ValueProcessor)
                 `-(language::matrix_expression:TinyMatrixExpressionProcessor<2ul, 2ul>)
                     +-(language::row_expression:FakeProcessor)
                     |   +-(language::real:1.3:ValueProcessor)
                     |   `-(language::integer:2:ValueProcessor)
                     `-(language::row_expression:FakeProcessor)
                         +-(language::integer:3:ValueProcessor)
                         `-(language::integer:1:ValueProcessor)
    )";
    
          CHECK_AST(data, result);
        }
    
        SECTION("tuple of R^3x3")
        {
          std::string_view data = R"(
    let A:(R^3x3), A = ([[1.2,2,1],[2.1,1,3],[1.2,1.2,3.2]], 0, [[1.4, 2, 1],[2.4, 0, 2],[2.1, 0.1, 3.2]]);
    let (A1,A2,A3) : (R^3x3)*(R^3x3)*(R^3x3), (A1,A2,A3) = (A, [[1,2,3],[1.2,3.1,1.8],[2,4,1]], ([[0,2,1], [2,1,0], [0.2,1,3]], [[1.3,2,1], [0.3,3,1], [0.1,2,4.3]]));
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     +-(language::eq_op:AffectationToTupleFromListProcessor<TinyMatrix<3ul, 3ul, double> >)
     |   +-(language::name:A:NameProcessor)
     |   `-(language::expression_list:ASTNodeExpressionListProcessor)
     |       +-(language::matrix_expression:TinyMatrixExpressionProcessor<3ul, 3ul>)
     |       |   +-(language::row_expression:FakeProcessor)
     |       |   |   +-(language::real:1.2:ValueProcessor)
     |       |   |   +-(language::integer:2:ValueProcessor)
     |       |   |   `-(language::integer:1:ValueProcessor)
     |       |   +-(language::row_expression:FakeProcessor)
     |       |   |   +-(language::real:2.1:ValueProcessor)
     |       |   |   +-(language::integer:1:ValueProcessor)
     |       |   |   `-(language::integer:3:ValueProcessor)
     |       |   `-(language::row_expression:FakeProcessor)
     |       |       +-(language::real:1.2:ValueProcessor)
     |       |       +-(language::real:1.2:ValueProcessor)
     |       |       `-(language::real:3.2:ValueProcessor)
     |       +-(language::integer:0:ValueProcessor)
     |       `-(language::matrix_expression:TinyMatrixExpressionProcessor<3ul, 3ul>)
     |           +-(language::row_expression:FakeProcessor)
     |           |   +-(language::real:1.4:ValueProcessor)
     |           |   +-(language::integer:2:ValueProcessor)
     |           |   `-(language::integer:1:ValueProcessor)
     |           +-(language::row_expression:FakeProcessor)
     |           |   +-(language::real:2.4:ValueProcessor)
     |           |   +-(language::integer:0:ValueProcessor)
     |           |   `-(language::integer:2:ValueProcessor)
     |           `-(language::row_expression:FakeProcessor)
     |               +-(language::real:2.1:ValueProcessor)
     |               +-(language::real:0.1:ValueProcessor)
     |               `-(language::real:3.2:ValueProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:A1:NameProcessor)
         |   +-(language::name:A2:NameProcessor)
         |   `-(language::name:A3:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::name:A:NameProcessor)
             +-(language::matrix_expression:TinyMatrixExpressionProcessor<3ul, 3ul>)
             |   +-(language::row_expression:FakeProcessor)
             |   |   +-(language::integer:1:ValueProcessor)
             |   |   +-(language::integer:2:ValueProcessor)
             |   |   `-(language::integer:3:ValueProcessor)
             |   +-(language::row_expression:FakeProcessor)
             |   |   +-(language::real:1.2:ValueProcessor)
             |   |   +-(language::real:3.1:ValueProcessor)
             |   |   `-(language::real:1.8:ValueProcessor)
             |   `-(language::row_expression:FakeProcessor)
             |       +-(language::integer:2:ValueProcessor)
             |       +-(language::integer:4:ValueProcessor)
             |       `-(language::integer:1:ValueProcessor)
             `-(language::inner_expression_list:InnerListToVectorProcessor)
                 +-(language::matrix_expression:TinyMatrixExpressionProcessor<3ul, 3ul>)
                 |   +-(language::row_expression:FakeProcessor)
                 |   |   +-(language::integer:0:ValueProcessor)
                 |   |   +-(language::integer:2:ValueProcessor)
                 |   |   `-(language::integer:1:ValueProcessor)
                 |   +-(language::row_expression:FakeProcessor)
                 |   |   +-(language::integer:2:ValueProcessor)
                 |   |   +-(language::integer:1:ValueProcessor)
                 |   |   `-(language::integer:0:ValueProcessor)
                 |   `-(language::row_expression:FakeProcessor)
                 |       +-(language::real:0.2:ValueProcessor)
                 |       +-(language::integer:1:ValueProcessor)
                 |       `-(language::integer:3:ValueProcessor)
                 `-(language::matrix_expression:TinyMatrixExpressionProcessor<3ul, 3ul>)
                     +-(language::row_expression:FakeProcessor)
                     |   +-(language::real:1.3:ValueProcessor)
                     |   +-(language::integer:2:ValueProcessor)
                     |   `-(language::integer:1:ValueProcessor)
                     +-(language::row_expression:FakeProcessor)
                     |   +-(language::real:0.3:ValueProcessor)
                     |   +-(language::integer:3:ValueProcessor)
                     |   `-(language::integer:1:ValueProcessor)
                     `-(language::row_expression:FakeProcessor)
                         +-(language::real:0.1:ValueProcessor)
                         +-(language::integer:2:ValueProcessor)
                         `-(language::real:4.3:ValueProcessor)
    )";
    
          CHECK_AST(data, result);
        }
    
        SECTION("from function")
        {
          std::string_view data = R"(
    let f: R -> R*R, x -> (x*x, x+1);
    let  (x,y): R*R, (x,y) = f(2);
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:x:NameProcessor)
         |   `-(language::name:y:NameProcessor)
         `-(language::function_evaluation:FunctionProcessor)
             +-(language::name:f:NameProcessor)
             `-(language::integer:2:ValueProcessor)
    )";
    
          CHECK_AST(data, result);
        }
    
        SECTION("string without conversion")
        {
          std::string_view data = R"(
    let  (s,r): string*string, (s,r) = ("foo","bar");
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:s:NameProcessor)
         |   `-(language::name:r:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::literal:"foo":ValueProcessor)
             `-(language::literal:"bar":ValueProcessor)
    )";
    
          CHECK_AST(data, result);
        }
    
        SECTION("string with scalar conversions")
        {
          std::string_view data = R"(
    let n:N, n = 2;
    let  (r,s,t,u) : string*string*string*string,
         (r,s,t,u) = (3.2, -2, true, n);
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
     |   +-(language::name:n:NameProcessor)
     |   `-(language::integer:2:ValueProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:r:NameProcessor)
         |   +-(language::name:s:NameProcessor)
         |   +-(language::name:t:NameProcessor)
         |   `-(language::name:u:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::real:3.2:ValueProcessor)
             +-(language::unary_minus:UnaryExpressionProcessor<language::unary_minus, long, long>)
             |   `-(language::integer:2:ValueProcessor)
             +-(language::true_kw:ValueProcessor)
             `-(language::name:n:NameProcessor)
    )";
    
          CHECK_AST(data, result);
        }
    
        SECTION("string with vector conversions")
        {
          std::string_view data = R"(
    let  (r,s,t) : string*string*string,
         (r,s,t) = ([3.2], [-2, 3], [1,3,2]);
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:r:NameProcessor)
         |   +-(language::name:s:NameProcessor)
         |   `-(language::name:t:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::vector_expression:TinyVectorExpressionProcessor<1ul>)
             |   `-(language::real:3.2:ValueProcessor)
             +-(language::vector_expression:TinyVectorExpressionProcessor<2ul>)
             |   +-(language::unary_minus:UnaryExpressionProcessor<language::unary_minus, long, long>)
             |   |   `-(language::integer:2:ValueProcessor)
             |   `-(language::integer:3:ValueProcessor)
             `-(language::vector_expression:TinyVectorExpressionProcessor<3ul>)
                 +-(language::integer:1:ValueProcessor)
                 +-(language::integer:3:ValueProcessor)
                 `-(language::integer:2:ValueProcessor)
    )";
    
          CHECK_AST(data, result);
        }
    
        SECTION("string with matrix conversions")
        {
          std::string_view data = R"(
    let  (r,s,t) : string*string*string,
         (r,s,t) = ([[3.2]], [[1, 2],[-2, 3]], [[1,3,2],[2,1,3],[4,1,2]]);
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:r:NameProcessor)
         |   +-(language::name:s:NameProcessor)
         |   `-(language::name:t:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::matrix_expression:TinyMatrixExpressionProcessor<1ul, 1ul>)
             |   `-(language::row_expression:FakeProcessor)
             |       `-(language::real:3.2:ValueProcessor)
             +-(language::matrix_expression:TinyMatrixExpressionProcessor<2ul, 2ul>)
             |   +-(language::row_expression:FakeProcessor)
             |   |   +-(language::integer:1:ValueProcessor)
             |   |   `-(language::integer:2:ValueProcessor)
             |   `-(language::row_expression:FakeProcessor)
             |       +-(language::unary_minus:UnaryExpressionProcessor<language::unary_minus, long, long>)
             |       |   `-(language::integer:2:ValueProcessor)
             |       `-(language::integer:3:ValueProcessor)
             `-(language::matrix_expression:TinyMatrixExpressionProcessor<3ul, 3ul>)
                 +-(language::row_expression:FakeProcessor)
                 |   +-(language::integer:1:ValueProcessor)
                 |   +-(language::integer:3:ValueProcessor)
                 |   `-(language::integer:2:ValueProcessor)
                 +-(language::row_expression:FakeProcessor)
                 |   +-(language::integer:2:ValueProcessor)
                 |   +-(language::integer:1:ValueProcessor)
                 |   `-(language::integer:3:ValueProcessor)
                 `-(language::row_expression:FakeProcessor)
                     +-(language::integer:4:ValueProcessor)
                     +-(language::integer:1:ValueProcessor)
                     `-(language::integer:2:ValueProcessor)
    )";
    
          CHECK_AST(data, result);
        }
    
        SECTION("embedded data")
        {
          std::string_view data = R"(
    let (b0,b1): builtin_t*builtin_t, (b0,b1) = (b0,b1);
    )";
    
          std::string_view result = R"(
    (root:ASTNodeListProcessor)
     `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
         +-(language::name_list:FakeProcessor)
         |   +-(language::name:b0:NameProcessor)
         |   `-(language::name:b1:NameProcessor)
         `-(language::expression_list:ASTNodeExpressionListProcessor)
             +-(language::name:b0:NameProcessor)
             `-(language::name:b1:NameProcessor)
    )";
    
          CHECK_AST(data, result);
        }
      }
    
      SECTION("Errors")
      {
        SECTION("invalid affectation rhs")
        {
          std::string_view data = R"(
    let x:R;
    let i:R;
    (x,i) = 3;
    )";
    
          CHECK_AST_THROWS_WITH(data, std::string{"invalid right hand side in list affectation"});
        }
    
        SECTION("incompatible list sizes")
        {
          std::string_view data = R"(
    let (x,y) : R*R, (x,y) = (3, 3, 2);
    )";
    
          CHECK_AST_THROWS_WITH(data, std::string{"incompatible list sizes in affectation"});
        }
    
        SECTION("incompatible list sizes 2")
        {
          std::string_view data = R"(
    let (x,y,z):R*R*R, (x,y,z) = (1, 2);
    )";
    
          CHECK_AST_THROWS_WITH(data, std::string{"incompatible list sizes in affectation"});
        }
    
        SECTION("incompatible list sizes from function evaluation")
        {
          std::string_view data = R"(
    let f: R -> R, x -> x*x;
    let(x,y) : R*R, (x,y) = f(3);
    )";
    
          CHECK_AST_THROWS_WITH(data, std::string{"incompatible list sizes in affectation"});
        }
    
        SECTION("incompatible list sizes from function evaluation")
        {
          std::string_view data = R"(
    let(x,y):R*R,(x,y)=(2,3);
    (x,y) += (1,4);
    )";
    
          CHECK_AST_THROWS_WITH(data, std::string{"undefined affectation operator for lists"});
        }
    
        SECTION("invalid operand type for affectation")
        {
          std::string_view data = R"(
    let f: R -> R, x -> x+1;
    let  (x,y) : R*R, (x,y) = (f,2);
    )";
    
          CHECK_AST_THROWS_WITH(data, std::string{"invalid implicit conversion: function -> R"});
        }
    
        SECTION("invalid operand type for string affectation")
        {
          std::string_view data = R"(
    let f: R -> R, x -> x+1;
    let (s,n):string*N, (s,n) = (f,2);
    )";
    
          CHECK_AST_THROWS_WITH(data, std::string{"invalid implicit conversion: function -> string"});
        }
    
        SECTION("invalid value type for affectation")
        {
          std::string_view data = R"(
    let f: R -> R, x -> x+1;
    let x:R;
    
    (f,x) = (3,2);
    )";
    
          CHECK_AST_THROWS_WITH(data, std::string{"invalid implicit conversion: Z -> function"});
        }
    
        SECTION("invalid R^n -> R^m conversion")
        {
          std::string_view data = R"(
    let x:R^2, x = [1,2];
    let y:R^3, y = x;
    )";
    
          CHECK_AST_THROWS_WITH(data, std::string{"undefined affectation type: R^3 = R^2"});
        }
    
        SECTION("invalid Z -> R^d conversion (non-zero)")
        {
          std::string_view data = R"(
    let x:R^2, x = 1;
    )";
    
          CHECK_AST_THROWS_WITH(data, std::string{"invalid integral value (0 is the solely valid value)"});
        }
      }
    }