#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/ASTNodeExpressionBuilder.hpp> #include <language/ast/ASTNodeFunctionEvaluationExpressionBuilder.hpp> #include <language/ast/ASTNodeFunctionExpressionBuilder.hpp> #include <language/ast/ASTNodeTypeCleaner.hpp> #include <language/ast/ASTSymbolTableBuilder.hpp> #include <language/utils/ASTPrinter.hpp> #include <stdexcept> #include <utils/Demangle.hpp> #include <test_BuiltinFunctionRegister.hpp> #include <pegtl/string_input.hpp> #include <memory> #include <unordered_map> #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); \ \ test_only::test_BuiltinFunctionRegister{*ast}; \ \ ASTSymbolTableBuilder{*ast}; \ ASTNodeDataTypeBuilder{*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, expected_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(expected_error)>, std::string_view>) or \ (std::is_same_v<std::decay_t<decltype(expected_error)>, std::string>)); \ \ TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"}; \ auto ast = ASTBuilder::build(input); \ \ test_only::test_BuiltinFunctionRegister{*ast}; \ \ ASTSymbolTableBuilder{*ast}; \ ASTNodeDataTypeBuilder{*ast}; \ \ ASTNodeTypeCleaner<language::var_declaration>{*ast}; \ ASTNodeTypeCleaner<language::fct_declaration>{*ast}; \ REQUIRE_THROWS_WITH(ASTNodeExpressionBuilder{*ast}, expected_error); \ } #define CHECK_AST_THROWS_AT_BUILD_WITH(data, expected_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(expected_error)>, std::string_view>) or \ (std::is_same_v<std::decay_t<decltype(expected_error)>, std::string>)); \ \ TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"}; \ auto ast = ASTBuilder::build(input); \ \ test_only::test_BuiltinFunctionRegister{*ast}; \ \ ASTSymbolTableBuilder{*ast}; \ REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast}, expected_error); \ } // clazy:excludeall=non-pod-global-static TEST_CASE("ASTNodeBuiltinFunctionExpressionBuilder", "[language]") { SECTION("R -> R") { SECTION("from R") { std::string_view data = R"( RtoR(1.); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:RtoR:FakeProcessor) `-(language::real:1.:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from Z") { std::string_view data = R"( RtoR(1); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:RtoR:FakeProcessor) `-(language::integer:1:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from N") { std::string_view data = R"( let n : N, n = 1; RtoR(n); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:RtoR:FakeProcessor) `-(language::name:n:NameProcessor) )"; CHECK_AST(data, result); } SECTION("from B") { std::string_view data = R"( RtoR(true); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:RtoR:FakeProcessor) `-(language::true_kw:ValueProcessor) )"; CHECK_AST(data, result); } } SECTION("R -> R^1") { SECTION("from R") { std::string_view data = R"( RtoR1(1.); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:RtoR1:FakeProcessor) `-(language::real:1.:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from Z") { std::string_view data = R"( RtoR1(1); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:RtoR1:FakeProcessor) `-(language::integer:1:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from N") { std::string_view data = R"( let n : N, n = 1; RtoR1(n); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:RtoR1:FakeProcessor) `-(language::name:n:NameProcessor) )"; CHECK_AST(data, result); } SECTION("from B") { std::string_view data = R"( RtoR1(true); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:RtoR1:FakeProcessor) `-(language::true_kw:ValueProcessor) )"; CHECK_AST(data, result); } } SECTION("R -> R^1x1") { SECTION("from R") { std::string_view data = R"( RtoR11(1.); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:RtoR11:FakeProcessor) `-(language::real:1.:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from Z") { std::string_view data = R"( RtoR11(1); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:RtoR11:FakeProcessor) `-(language::integer:1:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from N") { std::string_view data = R"( let n : N, n = 1; RtoR11(n); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:RtoR11:FakeProcessor) `-(language::name:n:NameProcessor) )"; CHECK_AST(data, result); } SECTION("from B") { std::string_view data = R"( RtoR11(true); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:RtoR11:FakeProcessor) `-(language::true_kw:ValueProcessor) )"; CHECK_AST(data, result); } } SECTION("R^1 -> R") { SECTION("from R^1") { std::string_view data = R"( let x : R^1, x = 2; R1toR(x); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R1toR:FakeProcessor) `-(language::name:x:NameProcessor) )"; CHECK_AST(data, result); } SECTION("from R") { std::string_view data = R"( R1toR(1.); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R1toR:FakeProcessor) `-(language::real:1.:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from Z") { std::string_view data = R"( R1toR(1); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R1toR:FakeProcessor) `-(language::integer:1:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from N") { std::string_view data = R"( let n : N, n = 1; R1toR(n); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R1toR:FakeProcessor) `-(language::name:n:NameProcessor) )"; CHECK_AST(data, result); } SECTION("from B") { std::string_view data = R"( R1toR(true); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R1toR:FakeProcessor) `-(language::true_kw:ValueProcessor) )"; CHECK_AST(data, result); } } SECTION("R^1x1 -> R") { SECTION("from R^1x1") { std::string_view data = R"( let x : R^1x1, x = 2; R11toR(x); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R11toR:FakeProcessor) `-(language::name:x:NameProcessor) )"; CHECK_AST(data, result); } SECTION("from R") { std::string_view data = R"( R11toR(1.); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R11toR:FakeProcessor) `-(language::real:1.:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from Z") { std::string_view data = R"( R11toR(1); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R11toR:FakeProcessor) `-(language::integer:1:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from N") { std::string_view data = R"( let n : N, n = 1; R11toR(n); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R11toR:FakeProcessor) `-(language::name:n:NameProcessor) )"; CHECK_AST(data, result); } SECTION("from B") { std::string_view data = R"( R11toR(true); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R11toR:FakeProcessor) `-(language::true_kw:ValueProcessor) )"; CHECK_AST(data, result); } } SECTION("R^2 -> R") { SECTION("from 0") { std::string_view data = R"( R2toR(0); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R2toR:FakeProcessor) `-(language::integer:0:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from R^2") { std::string_view data = R"( let x:R^2, x = (1,2); R2toR(x); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R2toR:FakeProcessor) `-(language::name:x:NameProcessor) )"; CHECK_AST(data, result); } SECTION("from list") { std::string_view data = R"( R2toR((1,2)); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R2toR:FakeProcessor) `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) +-(language::integer:1:ValueProcessor) `-(language::integer:2:ValueProcessor) )"; CHECK_AST(data, result); } } SECTION("R^2x2 -> R") { SECTION("from 0") { std::string_view data = R"( R22toR(0); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R22toR:FakeProcessor) `-(language::integer:0:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from R^2x2") { std::string_view data = R"( let x:R^2x2, x = (1,2,3,4); R22toR(x); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R22toR:FakeProcessor) `-(language::name:x:NameProcessor) )"; CHECK_AST(data, result); } SECTION("from list") { std::string_view data = R"( R22toR((1,2,3,4)); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R22toR:FakeProcessor) `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) +-(language::integer:1:ValueProcessor) +-(language::integer:2:ValueProcessor) +-(language::integer:3:ValueProcessor) `-(language::integer:4:ValueProcessor) )"; CHECK_AST(data, result); } } SECTION("R^3 -> R") { SECTION("from 0") { std::string_view data = R"( R3toR(0); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R3toR:FakeProcessor) `-(language::integer:0:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from R^3") { std::string_view data = R"( let x:R^3, x = (1,2,4); R3toR(x); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R3toR:FakeProcessor) `-(language::name:x:NameProcessor) )"; CHECK_AST(data, result); } SECTION("from list") { std::string_view data = R"( R3toR((1,2,3)); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R3toR:FakeProcessor) `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) +-(language::integer:1:ValueProcessor) +-(language::integer:2:ValueProcessor) `-(language::integer:3:ValueProcessor) )"; CHECK_AST(data, result); } } SECTION("R^3x3 -> R") { SECTION("from 0") { std::string_view data = R"( R33toR(0); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R33toR:FakeProcessor) `-(language::integer:0:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from R^3x3") { std::string_view data = R"( let x:R^3x3, x = (1,2,3,4,5,6,7,8,9); R33toR(x); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R33toR:FakeProcessor) `-(language::name:x:NameProcessor) )"; CHECK_AST(data, result); } SECTION("from list") { std::string_view data = R"( R33toR((1,2,3,4,5,6,7,8,9)); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R33toR:FakeProcessor) `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) +-(language::integer:1:ValueProcessor) +-(language::integer:2:ValueProcessor) +-(language::integer:3:ValueProcessor) +-(language::integer:4:ValueProcessor) +-(language::integer:5:ValueProcessor) +-(language::integer:6:ValueProcessor) +-(language::integer:7:ValueProcessor) +-(language::integer:8:ValueProcessor) `-(language::integer:9:ValueProcessor) )"; CHECK_AST(data, result); } } SECTION("Z -> R") { SECTION("from Z") { std::string_view data = R"( ZtoR(1); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:ZtoR:FakeProcessor) `-(language::integer:1:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from N") { std::string_view data = R"( let n : N, n = 1; ZtoR(n); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:ZtoR:FakeProcessor) `-(language::name:n:NameProcessor) )"; CHECK_AST(data, result); } SECTION("from B") { std::string_view data = R"( ZtoR(true); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:ZtoR:FakeProcessor) `-(language::true_kw:ValueProcessor) )"; CHECK_AST(data, result); } } SECTION("N -> R") { SECTION("from Z") { std::string_view data = R"( NtoR(1); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:NtoR:FakeProcessor) `-(language::integer:1:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from N") { std::string_view data = R"( let n : N, n = 1; NtoR(n); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:NtoR:FakeProcessor) `-(language::name:n:NameProcessor) )"; CHECK_AST(data, result); } SECTION("from B") { std::string_view data = R"( NtoR(true); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:NtoR:FakeProcessor) `-(language::true_kw:ValueProcessor) )"; CHECK_AST(data, result); } } SECTION("B -> R") { SECTION("from B") { std::string_view data = R"( BtoR(true); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:BtoR:FakeProcessor) `-(language::true_kw:ValueProcessor) )"; CHECK_AST(data, result); } } SECTION("R*R -> B") { std::string_view data = R"( RRtoB(1., 0.); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:RRtoB:FakeProcessor) `-(language::function_argument_list:ASTNodeExpressionListProcessor) +-(language::real:1.:ValueProcessor) `-(language::real:0.:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("R^3*R^2 -> R") { SECTION("from R^3*R^2") { std::string_view data = R"( let x : R^3, x = (1,2,3); let y : R^2, y = (2,3); R3R2toR(x,y); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R3R2toR:FakeProcessor) `-(language::function_argument_list:ASTNodeExpressionListProcessor) +-(language::name:x:NameProcessor) `-(language::name:y:NameProcessor) )"; CHECK_AST(data, result); } SECTION("from (R,R,R)*(R,R)") { std::string_view data = R"( R3R2toR((1,2,3),(3,4)); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R3R2toR:FakeProcessor) `-(language::function_argument_list:ASTNodeExpressionListProcessor) +-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) | +-(language::integer:1:ValueProcessor) | +-(language::integer:2:ValueProcessor) | `-(language::integer:3:ValueProcessor) `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) +-(language::integer:3:ValueProcessor) `-(language::integer:4:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from (R,R,R)*(0)") { std::string_view data = R"( R3R2toR((1,2,3),0); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R3R2toR:FakeProcessor) `-(language::function_argument_list:ASTNodeExpressionListProcessor) +-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) | +-(language::integer:1:ValueProcessor) | +-(language::integer:2:ValueProcessor) | `-(language::integer:3:ValueProcessor) `-(language::integer:0:ValueProcessor) )"; CHECK_AST(data, result); } } SECTION("R^3x3*R^2x2 -> R") { SECTION("from R^3x3*R^2x2") { std::string_view data = R"( let x : R^3x3, x = (1,2,3,4,5,6,7,8,9); let y : R^2x2, y = (1,2,3,4); R33R22toR(x,y); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R33R22toR:FakeProcessor) `-(language::function_argument_list:ASTNodeExpressionListProcessor) +-(language::name:x:NameProcessor) `-(language::name:y:NameProcessor) )"; CHECK_AST(data, result); } SECTION("from (R,R,R,R,R,R,R,R,R)*(R,R,R,R)") { std::string_view data = R"( R33R22toR((1,2,3,4,5,6,7,8,9),(1,2,3,4)); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R33R22toR:FakeProcessor) `-(language::function_argument_list:ASTNodeExpressionListProcessor) +-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) | +-(language::integer:1:ValueProcessor) | +-(language::integer:2:ValueProcessor) | +-(language::integer:3:ValueProcessor) | +-(language::integer:4:ValueProcessor) | +-(language::integer:5:ValueProcessor) | +-(language::integer:6:ValueProcessor) | +-(language::integer:7:ValueProcessor) | +-(language::integer:8:ValueProcessor) | `-(language::integer:9:ValueProcessor) `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) +-(language::integer:1:ValueProcessor) +-(language::integer:2:ValueProcessor) +-(language::integer:3:ValueProcessor) `-(language::integer:4:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("from (R,R,R,R,R,R,R,R,R)*(0)") { std::string_view data = R"( R33R22toR((1,2,3,4,5,6,7,8,9),0); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:R33R22toR:FakeProcessor) `-(language::function_argument_list:ASTNodeExpressionListProcessor) +-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) | +-(language::integer:1:ValueProcessor) | +-(language::integer:2:ValueProcessor) | +-(language::integer:3:ValueProcessor) | +-(language::integer:4:ValueProcessor) | +-(language::integer:5:ValueProcessor) | +-(language::integer:6:ValueProcessor) | +-(language::integer:7:ValueProcessor) | +-(language::integer:8:ValueProcessor) | `-(language::integer:9:ValueProcessor) `-(language::integer:0:ValueProcessor) )"; CHECK_AST(data, result); } } SECTION("string -> B") { std::string_view data = R"( StoB("foo"); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:StoB:FakeProcessor) `-(language::literal:"foo":ValueProcessor) )"; CHECK_AST(data, result); } SECTION("builtin_t -> builtin_t") { std::string_view data = R"( builtinToBuiltin(a); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:builtinToBuiltin:FakeProcessor) `-(language::name:a:NameProcessor) )"; CHECK_AST(data, result); } SECTION("-> tuple") { SECTION("B -> tuple(Z)") { std::string_view data = R"( tuple_ZtoR(true); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_ZtoR:FakeProcessor) `-(language::true_kw:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("tuple(B) -> tuple(Z)") { std::string_view data = R"( let t:(B), t =(true, false); tuple_ZtoR(t); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_ZtoR:FakeProcessor) `-(language::name:t:NameProcessor) )"; CHECK_AST(data, result); } SECTION("N -> tuple(Z)") { std::string_view data = R"( let n:N, n=1; tuple_ZtoR(n); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_ZtoR:FakeProcessor) `-(language::name:n:NameProcessor) )"; CHECK_AST(data, result); } SECTION("tuple(B) -> tuple(B)") { std::string_view data = R"( let t:(B), t=(true,false); tuple_BtoR(t); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_BtoR:FakeProcessor) `-(language::name:t:NameProcessor) )"; CHECK_AST(data, result); } SECTION("tuple(N) -> tuple(N)") { std::string_view data = R"( let t:(N), t=(1,3,7); tuple_NtoR(t); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_NtoR:FakeProcessor) `-(language::name:t:NameProcessor) )"; CHECK_AST(data, result); } SECTION("tuple(N) -> tuple(Z)") { std::string_view data = R"( let t:(N), t=(1,3,7); tuple_ZtoR(t); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_ZtoR:FakeProcessor) `-(language::name:t:NameProcessor) )"; CHECK_AST(data, result); } SECTION("Z -> tuple(Z)") { std::string_view data = R"( tuple_ZtoR(1); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_ZtoR:FakeProcessor) `-(language::integer:1:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("tuple(Z) -> tuple(Z)") { std::string_view data = R"( let t:(Z), t=(1,3,7); tuple_ZtoR(t); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_ZtoR:FakeProcessor) `-(language::name:t:NameProcessor) )"; CHECK_AST(data, result); } SECTION("Z -> tuple(R)") { std::string_view data = R"( tuple_RtoB(1); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_RtoB:FakeProcessor) `-(language::integer:1:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("tuple(Z) -> tuple(R)") { std::string_view data = R"( let t:(Z), t = (1,2,4,6); tuple_RtoB(t); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_RtoB:FakeProcessor) `-(language::name:t:NameProcessor) )"; CHECK_AST(data, result); } SECTION("R -> tuple(R)") { std::string_view data = R"( tuple_RtoB(1.2); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_RtoB:FakeProcessor) `-(language::real:1.2:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("tuple(R) -> tuple(R)") { std::string_view data = R"( let t:(R), t = (1,2,4,6); tuple_RtoB(t); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_RtoB:FakeProcessor) `-(language::name:t:NameProcessor) )"; CHECK_AST(data, result); } SECTION("list -> tuple(R)") { std::string_view data = R"( let n:N, n = 3; tuple_RtoB((1.2, 2, true, n)); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_RtoB:FakeProcessor) `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) +-(language::real:1.2:ValueProcessor) +-(language::integer:2:ValueProcessor) +-(language::true_kw:ValueProcessor) `-(language::name:n:NameProcessor) )"; CHECK_AST(data, result); } SECTION("R -> tuple(string)") { std::string_view data = R"( tuple_stringtoB(1.2); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_stringtoB:FakeProcessor) `-(language::real:1.2:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("string -> tuple(string)") { std::string_view data = R"( let s:string, s = "foo"; tuple_stringtoB(s); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_stringtoB:FakeProcessor) `-(language::name:s:NameProcessor) )"; CHECK_AST(data, result); } SECTION("tuple(R) -> tuple(string)") { std::string_view data = R"( let t:(R), t = (1,2,4,6); tuple_stringtoB(t); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_stringtoB:FakeProcessor) `-(language::name:t:NameProcessor) )"; CHECK_AST(data, result); } SECTION("tuple(string) -> tuple(string)") { std::string_view data = R"( let t:(string), t = ("foo", "bar", "foobar"); tuple_stringtoB(t); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_stringtoB:FakeProcessor) `-(language::name:t:NameProcessor) )"; CHECK_AST(data, result); } SECTION("literal -> tuple(string)") { std::string_view data = R"( tuple_stringtoB("foo"); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_stringtoB:FakeProcessor) `-(language::literal:"foo":ValueProcessor) )"; CHECK_AST(data, result); } SECTION("list -> tuple(string)") { std::string_view data = R"( tuple_stringtoB(("foo",2,"bar")); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_stringtoB:FakeProcessor) `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) +-(language::literal:"foo":ValueProcessor) +-(language::integer:2:ValueProcessor) `-(language::literal:"bar":ValueProcessor) )"; CHECK_AST(data, result); } SECTION("builtin -> tuple(builtin)") { std::string_view data = R"( tuple_builtinToB(a); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_builtinToB:FakeProcessor) `-(language::name:a:NameProcessor) )"; CHECK_AST(data, result); } SECTION("list -> tuple(builtin)") { std::string_view data = R"( tuple_builtinToB((a,b,a)); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_builtinToB:FakeProcessor) `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) +-(language::name:a:NameProcessor) +-(language::name:b:NameProcessor) `-(language::name:a:NameProcessor) )"; CHECK_AST(data, result); } SECTION("tuple(builtin) -> tuple(builtin)") { std::string_view data = R"( let t:(builtin_t), t = (a,b,a); tuple_builtinToB(t); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_builtinToB:FakeProcessor) `-(language::name:t:NameProcessor) )"; CHECK_AST(data, result); } SECTION("Z -> tuple(R^1)") { std::string_view data = R"( tuple_R1ToR(1); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_R1ToR:FakeProcessor) `-(language::integer:1:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("R -> tuple(R^1)") { std::string_view data = R"( tuple_R1ToR(1.2); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_R1ToR:FakeProcessor) `-(language::real:1.2:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("R^1 -> tuple(R^1)") { std::string_view data = R"( let r:R^1, r = 3; tuple_R1ToR(r); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_R1ToR:FakeProcessor) `-(language::name:r:NameProcessor) )"; CHECK_AST(data, result); } SECTION("Z -> tuple(R^1x1)") { std::string_view data = R"( tuple_R11ToR(1); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_R11ToR:FakeProcessor) `-(language::integer:1:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("R -> tuple(R^1x1)") { std::string_view data = R"( tuple_R11ToR(1.2); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_R11ToR:FakeProcessor) `-(language::real:1.2:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("R^1x1 -> tuple(R^1x1)") { std::string_view data = R"( let r:R^1x1, r = 3; tuple_R11ToR(r); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_R11ToR:FakeProcessor) `-(language::name:r:NameProcessor) )"; CHECK_AST(data, result); } SECTION("0 -> tuple(R^2)") { std::string_view data = R"( tuple_R2ToR(0); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_R2ToR:FakeProcessor) `-(language::integer:0:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("R^2 -> tuple(R^2)") { std::string_view data = R"( let r:R^2, r = (1,2); tuple_R2ToR(r); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_R2ToR:FakeProcessor) `-(language::name:r:NameProcessor) )"; CHECK_AST(data, result); } SECTION("compound_list -> tuple(R^2)") { std::string_view data = R"( let r:R^2, r = (1,2); tuple_R2ToR((r,r)); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_R2ToR:FakeProcessor) `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) +-(language::name:r:NameProcessor) `-(language::name:r:NameProcessor) )"; CHECK_AST(data, result); } SECTION("0 -> tuple(R^2x2)") { std::string_view data = R"( tuple_R22ToR(0); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_R22ToR:FakeProcessor) `-(language::integer:0:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("R^2x2 -> tuple(R^2x2)") { std::string_view data = R"( let r:R^2x2, r = (1,2,3,4); tuple_R22ToR(r); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_R22ToR:FakeProcessor) `-(language::name:r:NameProcessor) )"; CHECK_AST(data, result); } SECTION("compound_list -> tuple(R^2x2)") { std::string_view data = R"( let r:R^2x2, r = (1,2,3,4); tuple_R22ToR((r,r)); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_R22ToR:FakeProcessor) `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) +-(language::name:r:NameProcessor) `-(language::name:r:NameProcessor) )"; CHECK_AST(data, result); } SECTION("0 -> tuple(R^3)") { std::string_view data = R"( tuple_R3ToR(0); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_R3ToR:FakeProcessor) `-(language::integer:0:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("R^3 -> tuple(R^3)") { std::string_view data = R"( let r:R^3, r = (1,2,3); tuple_R3ToR(r); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_R3ToR:FakeProcessor) `-(language::name:r:NameProcessor) )"; CHECK_AST(data, result); } SECTION("0 -> tuple(R^3x3)") { std::string_view data = R"( tuple_R33ToR(0); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_R33ToR:FakeProcessor) `-(language::integer:0:ValueProcessor) )"; CHECK_AST(data, result); } SECTION("R^3x3 -> tuple(R^3x3)") { std::string_view data = R"( let r:R^3x3, r = (1,2,3,4,5,6,7,8,9); tuple_R33ToR(r); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:tuple_R33ToR:FakeProcessor) `-(language::name:r:NameProcessor) )"; CHECK_AST(data, result); } SECTION("FunctionSymbolId -> R") { std::string_view data = R"( let f : R^3 -> R, x -> 0; fidToR(f); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:fidToR:FakeProcessor) `-(language::name:f:NameProcessor) )"; CHECK_AST(data, result); } SECTION("tuple(FunctionSymbolId) -> R") { std::string_view data = R"( let f : R^3 -> R, x -> 0; fidTupleToR((f,f)); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:fidTupleToR:FakeProcessor) `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) +-(language::name:f:NameProcessor) `-(language::name:f:NameProcessor) )"; CHECK_AST(data, result); } SECTION("tuple(FunctionSymbolId) -> R [with single value tuple]") { std::string_view data = R"( let f : R^3 -> R, x -> 0; fidTupleToR(f); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) +-(language::name:fidTupleToR:FakeProcessor) `-(language::name:f:NameProcessor) )"; CHECK_AST(data, result); } } SECTION("errors") { SECTION("bad number of arguments") { std::string_view data = R"( BtoR(true, false); )"; const std::string error_msg = "no matching function to call BtoR: B*B\n" "note: candidates are\n" " BtoR: B -> R"; CHECK_AST_THROWS_AT_BUILD_WITH(data, error_msg); } SECTION("bad number of arguments 2") { std::string_view data = R"( RRtoB(3); )"; const std::string error_msg = "no matching function to call RRtoB: Z\n" "note: candidates are\n" " RRtoB: R*R -> B"; CHECK_AST_THROWS_AT_BUILD_WITH(data, error_msg); } SECTION("invalid argument type") { std::string_view data = R"( RtoR("foo"); )"; const std::string error_msg = "no matching function to call RtoR: string\n" "note: candidates are\n" " RtoR: R -> R"; CHECK_AST_THROWS_AT_BUILD_WITH(data, error_msg); } } }