diff --git a/src/language/ast/ASTNodeBuiltinFunctionExpressionBuilder.cpp b/src/language/ast/ASTNodeBuiltinFunctionExpressionBuilder.cpp index 77abdcf0305a0f9482837ca664a90a3a9d661841..9d914d7ee4799c9908253ffaa2958180a9d67bd3 100644 --- a/src/language/ast/ASTNodeBuiltinFunctionExpressionBuilder.cpp +++ b/src/language/ast/ASTNodeBuiltinFunctionExpressionBuilder.cpp @@ -152,29 +152,11 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData case ASTNodeDataType::double_t: { return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, double>>(argument_number); } - case ASTNodeDataType::string_t: { - return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, std::string>>(argument_number); - } - case ASTNodeDataType::vector_t: { - switch (tuple_content_type.dimension()) { - case 1: { - return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, TinyVector<1>>>(argument_number); - } - case 2: { - return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, TinyVector<2>>>(argument_number); - } - case 3: { - return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, TinyVector<3>>>(argument_number); - } - default: { - throw UnexpectedError(dataTypeName(tuple_content_type) + - " unexpected content of argument, invalid dimension of vector"); - } - } - } + // LCOV_EXCL_START default: { throw UnexpectedError(dataTypeName(tuple_content_type) + " unexpected tuple content type of argument "); } + // LCOV_EXCL_STOP } } case ASTNodeDataType::list_t: { @@ -195,9 +177,6 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData case ASTNodeDataType::double_t: { return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, double>>(argument_number); } - case ASTNodeDataType::string_t: { - return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, std::string>>(argument_number); - } case ASTNodeDataType::vector_t: { switch (arg_data_type.dimension()) { case 1: { @@ -209,14 +188,18 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData case 3: { return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, TinyVector<3>>>(argument_number); } + // LCOV_EXCL_START default: { throw UnexpectedError(dataTypeName(arg_data_type) + " unexpected dimension of vector"); } + // LCOV_EXCL_STOP } } + // LCOV_EXCL_START default: { throw UnexpectedError(dataTypeName(arg_data_type) + " argument to tuple "); } + // LCOV_EXCL_STOP } }; @@ -284,6 +267,9 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData case ASTNodeDataType::type_id_t: { return get_function_argument_to_tuple_converter(EmbeddedData{}); } + case ASTNodeDataType::bool_t: { + return get_function_argument_to_tuple_converter(bool{}); + } case ASTNodeDataType::unsigned_int_t: { return get_function_argument_to_tuple_converter(uint64_t{}); } @@ -298,15 +284,10 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData case 1: { return get_function_argument_to_tuple_converter(TinyVector<1>{}); } - case 2: { - return get_function_argument_to_tuple_converter(TinyVector<2>{}); - } - case 3: { - return get_function_argument_to_tuple_converter(TinyVector<3>{}); - } - // LCOV_EXCL_START + // LCOV_EXCL_START default: { - throw parse_error("unexpected error: unexpected tuple content for function", + throw parse_error("unexpected error: unexpected tuple content for function: '" + + dataTypeName(parameter_type) + "'", std::vector{argument_node_sub_data_type.m_parent_node.begin()}); } // LCOV_EXCL_STOP @@ -315,10 +296,12 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData case ASTNodeDataType::string_t: { return get_function_argument_to_string_converter(); } + // LCOV_EXCL_START default: { throw parse_error("unexpected error: unexpected tuple content type for function", std::vector{argument_node_sub_data_type.m_parent_node.begin()}); } + // LCOV_EXCL_STOP } } // LCOV_EXCL_START @@ -331,7 +314,9 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData }; if (parameter_type == ASTNodeDataType::vector_t and parameter_type.dimension() == 1) { - ASTNodeNaturalConversionChecker{argument_node_sub_data_type, ASTNodeDataType::double_t}; + if (not isNaturalConversion(argument_node_sub_data_type.m_data_type, parameter_type)) { + ASTNodeNaturalConversionChecker{argument_node_sub_data_type, ASTNodeDataType::double_t}; + } } else { ASTNodeNaturalConversionChecker{argument_node_sub_data_type, parameter_type}; } diff --git a/tests/test_ASTNodeBuiltinFunctionExpressionBuilder.cpp b/tests/test_ASTNodeBuiltinFunctionExpressionBuilder.cpp index 668a77696363a23b01c01663cf9229fa3281fd45..9795ded186f5f7fee9236ec7473bd7c5f32d528b 100644 --- a/tests/test_ASTNodeBuiltinFunctionExpressionBuilder.cpp +++ b/tests/test_ASTNodeBuiltinFunctionExpressionBuilder.cpp @@ -8,8 +8,10 @@ #include <language/ast/ASTNodeFunctionExpressionBuilder.hpp> #include <language/ast/ASTNodeTypeCleaner.hpp> #include <language/ast/ASTSymbolTableBuilder.hpp> +#include <language/utils/ASTNodeDataTypeTraits.hpp> #include <language/utils/ASTPrinter.hpp> #include <language/utils/BuiltinFunctionEmbedder.hpp> +#include <language/utils/TypeDescriptor.hpp> #include <utils/Demangle.hpp> #include <pegtl/string_input.hpp> @@ -17,6 +19,11 @@ #include <memory> #include <unordered_map> +template <> +inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const double>> = {ASTNodeDataType::type_id_t, + "builtin_t"}; +const auto builtin_data_type = ast_node_data_type_from<std::shared_ptr<const double>>; + namespace test_only { class BuiltinFunctionRegister @@ -42,12 +49,110 @@ class BuiltinFunctionRegister [](bool b) -> double { return b; }))); m_name_builtin_function_map.insert( - std::make_pair("R2toB", std::make_shared<BuiltinFunctionEmbedder<bool(double, double)>>( + std::make_pair("RRtoB", std::make_shared<BuiltinFunctionEmbedder<bool(double, double)>>( [](double x, double y) -> bool { return x > y; }))); m_name_builtin_function_map.insert( std::make_pair("StoB", std::make_shared<BuiltinFunctionEmbedder<bool(std::string)>>( [](const std::string& s) -> bool { return s.size() > 0; }))); + + m_name_builtin_function_map.insert( + std::make_pair("RtoR1", std::make_shared<BuiltinFunctionEmbedder<TinyVector<1>(double)>>( + [](double r) -> TinyVector<1> { return {r}; }))); + + m_name_builtin_function_map.insert( + std::make_pair("R1toR", std::make_shared<BuiltinFunctionEmbedder<double(TinyVector<1>)>>( + [](TinyVector<1> x) -> double { return x[0]; }))); + + m_name_builtin_function_map.insert( + std::make_pair("R2toR", std::make_shared<BuiltinFunctionEmbedder<double(TinyVector<2>)>>( + [](TinyVector<2> x) -> double { return x[0] + x[1]; }))); + + m_name_builtin_function_map.insert( + std::make_pair("R3toR", std::make_shared<BuiltinFunctionEmbedder<double(const TinyVector<3>&)>>( + [](const TinyVector<3>& x) -> double { return x[0] + x[1] + x[2]; }))); + + m_name_builtin_function_map.insert( + std::make_pair("R3R2toR", + std::make_shared<BuiltinFunctionEmbedder<double(TinyVector<3>, TinyVector<2>)>>( + [](TinyVector<3> x, TinyVector<2> y) -> double { return x[0] * y[1] + (y[0] - x[2]) * x[1]; }))); + + m_name_builtin_function_map.insert( + std::make_pair("fidToR", std::make_shared<BuiltinFunctionEmbedder<double(const FunctionSymbolId&)>>( + [](const FunctionSymbolId&) -> double { return 0; }))); + + m_name_builtin_function_map.insert( + std::make_pair("builtinToBuiltin", + std::make_shared< + BuiltinFunctionEmbedder<std::shared_ptr<const double>(std::shared_ptr<const double>)>>( + [](std::shared_ptr<const double> x) -> std::shared_ptr<const double> { return x; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_BtoR", std::make_shared<BuiltinFunctionEmbedder<double(std::vector<bool>)>>( + [](const std::vector<bool>&) -> double { return 0.5; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_NtoR", std::make_shared<BuiltinFunctionEmbedder<double(std::vector<uint64_t>)>>( + [](const std::vector<uint64_t>&) -> double { return 0.5; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_ZtoR", std::make_shared<BuiltinFunctionEmbedder<double(std::vector<int64_t>)>>( + [](const std::vector<int64_t>&) -> double { return 0.5; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_RtoB", std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<double>)>>( + [](const std::vector<double>&) -> bool { return false; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_stringtoB", std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<std::string>)>>( + [](const std::vector<std::string>&) -> bool { return true; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_builtinToB", + std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<std::shared_ptr<const double>>)>>( + [](const std::vector<std::shared_ptr<const double>>&) -> bool { return true; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_R1ToR", + std::make_shared<BuiltinFunctionEmbedder<double(const std::vector<TinyVector<1>>&)>>( + [](const std::vector<TinyVector<1>>&) -> double { return 1; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_R2ToR", + std::make_shared<BuiltinFunctionEmbedder<double(const std::vector<TinyVector<2>>&)>>( + [](const std::vector<TinyVector<2>>&) -> double { return 1; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_R3ToR", std::make_shared<BuiltinFunctionEmbedder<double(const std::vector<TinyVector<3>>)>>( + [](const std::vector<TinyVector<3>>&) -> double { return 0; }))); + } + + void + _addBuiltinTypeAndVariables(ASTNode& 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::type_name_id_t); + i_symbol->attributes().setIsInitialized(); + i_symbol->attributes().value() = symbol_table.typeEmbedderTable().size(); + symbol_table.typeEmbedderTable().add(std::make_shared<TypeDescriptor>(builtin_data_type.nameOfTypeId())); + + auto [i_symbol_a, success_a] = symbol_table.add("a", ast.begin()); + if (not success_a) { + throw UnexpectedError("cannot add 'a' of type builtin_t for testing"); + } + i_symbol_a->attributes().setDataType(ast_node_data_type_from<std::shared_ptr<const double>>); + i_symbol_a->attributes().setIsInitialized(); + auto [i_symbol_b, success_b] = symbol_table.add("b", ast.begin()); + if (not success_b) { + throw UnexpectedError("cannot add 'b' of type builtin_t for testing"); + } + i_symbol_b->attributes().setDataType(ast_node_data_type_from<std::shared_ptr<const double>>); + i_symbol_b->attributes().setIsInitialized(); } public: @@ -58,6 +163,7 @@ class BuiltinFunctionRegister auto& builtin_function_embedder_table = symbol_table.builtinFunctionEmbedderTable(); this->_populateNameBuiltinFunctionMap(); + this->_addBuiltinTypeAndVariables(root_node); for (const auto& [symbol_name, builtin_function] : m_name_builtin_function_map) { auto [i_symbol, success] = symbol_table.add(symbol_name, root_node.begin()); @@ -93,6 +199,7 @@ class BuiltinFunctionRegister ASTNodeDataTypeBuilder{*ast}; \ \ ASTNodeTypeCleaner<language::var_declaration>{*ast}; \ + ASTNodeTypeCleaner<language::fct_declaration>{*ast}; \ ASTNodeExpressionBuilder{*ast}; \ \ std::stringstream ast_output; \ @@ -191,6 +298,268 @@ RtoR(true); } } + SECTION("R -> R1") + { + SECTION("from R") + { + std::string_view data = R"( +RtoR1(1.); +)"; + + std::string_view result = R"( +(root:ASTNodeListProcessor) + `-(language::function_evaluation:BuiltinFunctionProcessor) + +-(language::name:RtoR1:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(language::true_kw:ValueProcessor) +)"; + + CHECK_AST(data, result); + } + } + + SECTION("R1 -> R") + { + SECTION("from R1") + { + 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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(language::true_kw:ValueProcessor) +)"; + + CHECK_AST(data, result); + } + } + + SECTION("R2 -> 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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) + +-(language::integer:1:ValueProcessor) + `-(language::integer:2:ValueProcessor) +)"; + + CHECK_AST(data, result); + } + } + + SECTION("R3 -> 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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) + +-(language::integer:1:ValueProcessor) + +-(language::integer:2:ValueProcessor) + `-(language::integer:3:ValueProcessor) +)"; + + CHECK_AST(data, result); + } + } + SECTION("Z -> R") { SECTION("from Z") @@ -314,16 +683,16 @@ BtoR(true); } } - SECTION("R2 -> B") + SECTION("R*R -> B") { std::string_view data = R"( -R2toB(1., 0.); +RRtoB(1., 0.); )"; std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) - +-(language::name:R2toB:NameProcessor) + +-(language::name:RRtoB:NameProcessor) `-(language::function_argument_list:ASTNodeExpressionListProcessor) +-(language::real:1.:ValueProcessor) `-(language::real:0.:ValueProcessor) @@ -332,22 +701,634 @@ R2toB(1., 0.); CHECK_AST(data, result); } - SECTION("string -> B") + SECTION("R^3*R^2 -> R") { - std::string_view data = R"( -StoB("foo"); + 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"( + std::string_view result = R"( (root:ASTNodeListProcessor) `-(language::function_evaluation:BuiltinFunctionProcessor) - +-(language::name:StoB:NameProcessor) + +-(language::name:R3R2toR:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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("string -> B") + { + std::string_view data = R"( +StoB("foo"); +)"; + + std::string_view result = R"( +(root:ASTNodeListProcessor) + `-(language::function_evaluation:BuiltinFunctionProcessor) + +-(language::name:StoB:NameProcessor) `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(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:NameProcessor) + `-(language::name:t:NameProcessor) +)"; + + CHECK_AST(data, result); + } + + SECTION("Z -> tuple(R1)") + { + std::string_view data = R"( +tuple_R1ToR(1); +)"; + + std::string_view result = R"( +(root:ASTNodeListProcessor) + `-(language::function_evaluation:BuiltinFunctionProcessor) + +-(language::name:tuple_R1ToR:NameProcessor) + `-(language::integer:1:ValueProcessor) +)"; + + CHECK_AST(data, result); + } + + SECTION("R -> tuple(R1)") + { + std::string_view data = R"( +tuple_R1ToR(1.2); +)"; + + std::string_view result = R"( +(root:ASTNodeListProcessor) + `-(language::function_evaluation:BuiltinFunctionProcessor) + +-(language::name:tuple_R1ToR:NameProcessor) + `-(language::real:1.2:ValueProcessor) +)"; + + CHECK_AST(data, result); + } + + SECTION("R1 -> tuple(R1)") + { + 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:NameProcessor) + `-(language::name:r:NameProcessor) +)"; + + CHECK_AST(data, result); + } + + SECTION("0 -> tuple(R2)") + { + std::string_view data = R"( +tuple_R2ToR(0); +)"; + + std::string_view result = R"( +(root:ASTNodeListProcessor) + `-(language::function_evaluation:BuiltinFunctionProcessor) + +-(language::name:tuple_R2ToR:NameProcessor) + `-(language::integer:0:ValueProcessor) +)"; + + CHECK_AST(data, result); + } + + SECTION("R2 -> tuple(R2)") + { + 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:NameProcessor) + `-(language::name:r:NameProcessor) +)"; + + CHECK_AST(data, result); + } + + SECTION("compound_list -> tuple(R2)") + { + 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:NameProcessor) + `-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>) + +-(language::name:r:NameProcessor) + `-(language::name:r:NameProcessor) +)"; + + CHECK_AST(data, result); + } + + SECTION("0 -> tuple(R3)") + { + std::string_view data = R"( +tuple_R3ToR(0); +)"; + + std::string_view result = R"( +(root:ASTNodeListProcessor) + `-(language::function_evaluation:BuiltinFunctionProcessor) + +-(language::name:tuple_R3ToR:NameProcessor) + `-(language::integer:0:ValueProcessor) +)"; + + CHECK_AST(data, result); + } + + SECTION("R3 -> tuple(R3)") + { + 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:NameProcessor) + `-(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:NameProcessor) + `-(language::name:f:NameProcessor) +)"; + + CHECK_AST(data, result); + } + } + SECTION("errors") { SECTION("bad number of arguments") @@ -361,7 +1342,7 @@ BtoR(true, false); SECTION("bad number of arguments 2") { std::string_view data = R"( -R2toB(3); +RRtoB(3); )"; CHECK_AST_THROWS_WITH(data, std::string{"bad number of arguments:"}); }