Select Git revision
test_main.cpp
test_ASTNodeFunctionExpressionBuilder.cpp 33.07 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/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 <utils/Demangle.hpp>
#include <pegtl/string_input.hpp>
#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}; \
ASTNodeTypeCleaner<language::import_instruction>{*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(data) \
{ \
static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>); \
\
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}; \
\
ASTNodeTypeCleaner<language::var_declaration>{*ast}; \
ASTNodeTypeCleaner<language::fct_declaration>{*ast}; \
REQUIRE_THROWS_AS(ASTNodeExpressionBuilder{*ast}, ParseError); \
}
#define CHECK_TYPE_BUILDER_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}; \
REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast}, error); \
}
#define CHECK_EXPRESSION_BUILDER_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}; \
\
ASTNodeTypeCleaner<language::var_declaration>{*ast}; \
ASTNodeTypeCleaner<language::fct_declaration>{*ast}; \
REQUIRE_THROWS_WITH(ASTNodeExpressionBuilder{*ast}, error); \
}
// clazy:excludeall=non-pod-global-static
TEST_CASE("ASTNodeFunctionExpressionBuilder", "[language]")
{
SECTION("return a B")
{
SECTION("B argument")
{
SECTION("B parameter")
{
std::string_view data = R"(
let not_v : B -> B, a -> not a;
not_v(true);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:not_v:NameProcessor)
`-(language::true_kw:ValueProcessor)
)";
CHECK_AST(data, result);
}
}
SECTION("N argument")
{
std::string_view data = R"(
let test : N -> B, n -> n<10;
test(2);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:test:NameProcessor)
`-(language::integer:2:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Z argument")
{
std::string_view data = R"(
let test : Z -> B, z -> z>3;
test(2);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:test:NameProcessor)
`-(language::integer:2:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("R argument")
{
std::string_view data = R"(
let test : R -> B, x -> x>2.3;
test(2.1);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:test:NameProcessor)
`-(language::real:2.1:ValueProcessor)
)";
CHECK_AST(data, result);
}
}
SECTION("return a N")
{
SECTION("N argument")
{
std::string_view data = R"(
let test : N -> N, n -> n+2;
test(2);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:test:NameProcessor)
`-(language::integer:2:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Z argument")
{
std::string_view data = R"(
let absolute : Z -> N, z -> (z>0)*z -(z<=0)*z;
absolute(-2);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:absolute:NameProcessor)
`-(language::unary_minus:UnaryExpressionProcessor<language::unary_minus, long, long>)
`-(language::integer:2:ValueProcessor)
)";
CHECK_AST(data, result);
}
}
SECTION("return a Z")
{
SECTION("N argument")
{
std::string_view data = R"(
let minus : N -> Z, n -> -n;
minus(true);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:minus:NameProcessor)
`-(language::true_kw:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Z argument")
{
std::string_view data = R"(
let times_2 : Z -> Z, z -> z*2;
times_2(-2);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:times_2:NameProcessor)
`-(language::unary_minus:UnaryExpressionProcessor<language::unary_minus, long, long>)
`-(language::integer:2:ValueProcessor)
)";
CHECK_AST(data, result);
}
}
SECTION("return a string")
{
SECTION("string argument")
{
std::string_view data = R"(
let cat : string*string -> string, (s1,s2) -> s1+s2;
cat("foo", "bar");
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:cat:NameProcessor)
`-(language::function_argument_list:ASTNodeExpressionListProcessor)
+-(language::literal:"foo":ValueProcessor)
`-(language::literal:"bar":ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("B argument conversion")
{
std::string_view data = R"(
let cat : string*string -> string, (s1,s2) -> s1+s2;
cat("foo", true);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:cat:NameProcessor)
`-(language::function_argument_list:ASTNodeExpressionListProcessor)
+-(language::literal:"foo":ValueProcessor)
`-(language::true_kw:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("N argument conversion")
{
std::string_view data = R"(
let cat : string*string -> string, (s1,s2) -> s1+s2;
let n : N, n = 2;
cat("foo", n);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:cat:NameProcessor)
`-(language::function_argument_list:ASTNodeExpressionListProcessor)
+-(language::literal:"foo":ValueProcessor)
`-(language::name:n:NameProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Z argument conversion")
{
std::string_view data = R"(
let cat : string*string -> string, (s1,s2) -> s1+s2;
cat("foo", -1);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:cat:NameProcessor)
`-(language::function_argument_list:ASTNodeExpressionListProcessor)
+-(language::literal:"foo":ValueProcessor)
`-(language::unary_minus:UnaryExpressionProcessor<language::unary_minus, long, long>)
`-(language::integer:1:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("R argument conversion")
{
std::string_view data = R"(
let cat : string*string -> string, (s1,s2) -> s1+s2;
cat("foo", 2.5e-3);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:cat:NameProcessor)
`-(language::function_argument_list:ASTNodeExpressionListProcessor)
+-(language::literal:"foo":ValueProcessor)
`-(language::real:2.5e-3:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return R^1 -> R^1")
{
std::string_view data = R"(
let f : R^1 -> R^1, x -> x+x;
let x : R^1, x = 1;
f(x);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::name:x:NameProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return R^2 -> R^2")
{
std::string_view data = R"(
let f : R^2 -> R^2, x -> x+x;
let x : R^2, x = (1,2);
f(x);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::name:x:NameProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return R^3 -> R^3")
{
std::string_view data = R"(
let f : R^3 -> R^3, x -> x+x;
let x : R^3, x = (1,2,3);
f(x);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::name:x:NameProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return R^1x1 -> R^1x1")
{
std::string_view data = R"(
let f : R^1x1 -> R^1x1, x -> x+x;
let x : R^1x1, x = 1;
f(x);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::name:x:NameProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return R^2x2 -> R^2x2")
{
std::string_view data = R"(
let f : R^2x2 -> R^2x2, x -> x+x;
let x : R^2x2, x = (1,2,3,4);
f(x);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::name:x:NameProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return R^3x3 -> R^3x3")
{
std::string_view data = R"(
let f : R^3x3 -> R^3x3, x -> x+x;
let x : R^3x3, x = (1,2,3,4,5,6,7,8,9);
f(x);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::name:x:NameProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return scalar -> R^1")
{
std::string_view data = R"(
let f : R -> R^1, x -> x+1;
f(1);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::integer:1:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return tuple -> R^2")
{
std::string_view data = R"(
let f : R*R -> R^2, (x,y) -> (x,y);
f(1,2);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:TupleToTinyVectorProcessor<FunctionProcessor, 2ul>)
+-(language::name:f:NameProcessor)
`-(language::function_argument_list:ASTNodeExpressionListProcessor)
+-(language::integer:1:ValueProcessor)
`-(language::integer:2:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return tuple -> R^3")
{
std::string_view data = R"(
let f : R*R*R -> R^3, (x,y,z) -> (x,y,z);
f(1,2,3);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:TupleToTinyVectorProcessor<FunctionProcessor, 3ul>)
+-(language::name:f:NameProcessor)
`-(language::function_argument_list:ASTNodeExpressionListProcessor)
+-(language::integer:1:ValueProcessor)
+-(language::integer:2:ValueProcessor)
`-(language::integer:3:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return scalar -> R^1x1")
{
std::string_view data = R"(
let f : R -> R^1x1, x -> x+1;
f(1);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::integer:1:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return tuple -> R^2x2")
{
std::string_view data = R"(
let f : R*R*R*R -> R^2x2, (x,y,z,t) -> (x,y,z,t);
f(1,2,3,4);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:TupleToTinyMatrixProcessor<FunctionProcessor, 2ul>)
+-(language::name:f:NameProcessor)
`-(language::function_argument_list:ASTNodeExpressionListProcessor)
+-(language::integer:1:ValueProcessor)
+-(language::integer:2:ValueProcessor)
+-(language::integer:3:ValueProcessor)
`-(language::integer:4:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return tuple -> R^3x3")
{
std::string_view data = R"(
let f : R^3*R^3*R^3 -> R^3x3, (x,y,z) -> (x[0],x[1],x[2],y[0],y[1],y[2],z[0],z[1],z[2]);
f((1,2,3),(4,5,6),(7,8,9));
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:TupleToTinyMatrixProcessor<FunctionProcessor, 3ul>)
+-(language::name:f: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:4:ValueProcessor)
| +-(language::integer:5:ValueProcessor)
| `-(language::integer:6:ValueProcessor)
`-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>)
+-(language::integer:7:ValueProcessor)
+-(language::integer:8:ValueProcessor)
`-(language::integer:9:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return '0' -> R^1")
{
std::string_view data = R"(
let f : R -> R^1, x -> 0;
f(1);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionExpressionProcessor<TinyVector<1ul, double>, ZeroType>)
+-(language::name:f:NameProcessor)
`-(language::integer:1:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return '0' -> R^2")
{
std::string_view data = R"(
let f : R -> R^2, x -> 0;
f(1);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionExpressionProcessor<TinyVector<2ul, double>, ZeroType>)
+-(language::name:f:NameProcessor)
`-(language::integer:1:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return '0' -> R^3")
{
std::string_view data = R"(
let f : R -> R^3, x -> 0;
f(1);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionExpressionProcessor<TinyVector<3ul, double>, ZeroType>)
+-(language::name:f:NameProcessor)
`-(language::integer:1:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return '0' -> R^1x1")
{
std::string_view data = R"(
let f : R -> R^1x1, x -> 0;
f(1);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionExpressionProcessor<TinyMatrix<1ul, double>, ZeroType>)
+-(language::name:f:NameProcessor)
`-(language::integer:1:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return '0' -> R^2x2")
{
std::string_view data = R"(
let f : R -> R^2x2, x -> 0;
f(1);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionExpressionProcessor<TinyMatrix<2ul, double>, ZeroType>)
+-(language::name:f:NameProcessor)
`-(language::integer:1:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return '0' -> R^3x3")
{
std::string_view data = R"(
let f : R -> R^3x3, x -> 0;
f(1);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionExpressionProcessor<TinyMatrix<3ul, double>, ZeroType>)
+-(language::name:f:NameProcessor)
`-(language::integer:1:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return embedded R^d compound")
{
std::string_view data = R"(
let f : R*R*R*R -> R*R^1*R^2*R^3, (x,y,z,t) -> (t, (x), (x,y), (x,y,z));
f(1,2,3,4);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::function_argument_list:ASTNodeExpressionListProcessor)
+-(language::integer:1:ValueProcessor)
+-(language::integer:2:ValueProcessor)
+-(language::integer:3:ValueProcessor)
`-(language::integer:4:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return embedded R^dxd compound")
{
std::string_view data = R"(
let f : R*R*R*R -> R*R^1x1*R^2x2*R^3x3, (x,y,z,t) -> (t, (x), (x,y,z,t), (x,y,z, x,x,x, t,t,t));
f(1,2,3,4);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::function_argument_list:ASTNodeExpressionListProcessor)
+-(language::integer:1:ValueProcessor)
+-(language::integer:2:ValueProcessor)
+-(language::integer:3:ValueProcessor)
`-(language::integer:4:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return embedded R^d compound with '0'")
{
std::string_view data = R"(
let f : R*R*R*R -> R*R^1*R^2*R^3, (x,y,z,t) -> (t, 0, 0, (x,y,z));
f(1,2,3,4);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::function_argument_list:ASTNodeExpressionListProcessor)
+-(language::integer:1:ValueProcessor)
+-(language::integer:2:ValueProcessor)
+-(language::integer:3:ValueProcessor)
`-(language::integer:4:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Return embedded R^dxd compound with '0'")
{
std::string_view data = R"(
let f : R*R*R*R -> R*R^1x1*R^2x2*R^3x3, (x,y,z,t) -> (t, 0, 0, (x, y, z, t, x, y, z, t, x));
f(1,2,3,4);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::function_argument_list:ASTNodeExpressionListProcessor)
+-(language::integer:1:ValueProcessor)
+-(language::integer:2:ValueProcessor)
+-(language::integer:3:ValueProcessor)
`-(language::integer:4:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Arguments '0' -> R^1")
{
std::string_view data = R"(
let f : R^1 -> R^1, x -> x;
f(0);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::integer:0:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Arguments '0' -> R^2")
{
std::string_view data = R"(
let f : R^2 -> R^2, x -> x;
f(0);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::integer:0:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Arguments '0' -> R^3")
{
std::string_view data = R"(
let f : R^3 -> R^3, x -> x;
f(0);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::integer:0:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Arguments '0' -> R^1x1")
{
std::string_view data = R"(
let f : R^1x1 -> R^1x1, x -> x;
f(0);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::integer:0:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Arguments '0' -> R^2x2")
{
std::string_view data = R"(
let f : R^2x2 -> R^2x2, x -> x;
f(0);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::integer:0:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Arguments '0' -> R^3x3")
{
std::string_view data = R"(
let f : R^3x3 -> R^3x3, x -> x;
f(0);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::integer:0:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Arguments tuple -> R^d")
{
std::string_view data = R"(
let f: R^3 -> R, x -> x[0]+x[1]+x[2];
f((1,2,3));
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>)
+-(language::integer:1:ValueProcessor)
+-(language::integer:2:ValueProcessor)
`-(language::integer:3:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("Arguments tuple -> R^dxd")
{
std::string_view data = R"(
let f: R^3x3 -> R, x -> x[0,0]+x[0,1]+x[0,2];
f((1,2,3,4,5,6,7,8,9));
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(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("Arguments compound with tuple")
{
std::string_view data = R"(
let f: R*R^3*R^2x2->R, (t,x,y) -> t*(x[0]+x[1]+x[2])*y[0,0]+y[1,1];
f(2,(1,2,3),(2,3,-1,1.3));
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::function_argument_list:ASTNodeExpressionListProcessor)
+-(language::integer:2:ValueProcessor)
+-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>)
| +-(language::integer:1:ValueProcessor)
| +-(language::integer:2:ValueProcessor)
| `-(language::integer:3:ValueProcessor)
`-(language::tuple_expression:TupleToVectorProcessor<ASTNodeExpressionListProcessor>)
+-(language::integer:2:ValueProcessor)
+-(language::integer:3:ValueProcessor)
+-(language::unary_minus:UnaryExpressionProcessor<language::unary_minus, long, long>)
| `-(language::integer:1:ValueProcessor)
`-(language::real:1.3:ValueProcessor)
)";
CHECK_AST(data, result);
}
}
SECTION("errors")
{
SECTION("wrong argument number")
{
std::string_view data = R"(
let Id : Z -> Z, z -> z;
Id(2,3);
)";
CHECK_AST_THROWS(data);
}
SECTION("wrong argument number 2")
{
std::string_view data = R"(
let sum : R*R -> R, (x,y) -> x+y;
sum(2);
)";
CHECK_AST_THROWS(data);
}
SECTION("invalid return implicit conversion")
{
SECTION("string -> R")
{
std::string_view data = R"(
let bad_conv : string -> R, s -> s;
)";
CHECK_TYPE_BUILDER_THROWS_WITH(data, std::string{"invalid implicit conversion: string -> R"});
}
SECTION("R -> B")
{
std::string_view data = R"(
let bad_B : R -> B, x -> x;
)";
CHECK_TYPE_BUILDER_THROWS_WITH(data, std::string{"invalid implicit conversion: R -> B"});
}
SECTION("R -> N")
{
std::string_view data = R"(
let next : R -> N, x -> x;
)";
CHECK_TYPE_BUILDER_THROWS_WITH(data, std::string{"invalid implicit conversion: R -> N"});
}
SECTION("R -> Z")
{
std::string_view data = R"(
let prev : R -> Z, x -> x;
)";
CHECK_TYPE_BUILDER_THROWS_WITH(data, std::string{"invalid implicit conversion: R -> Z"});
}
SECTION("N -> B")
{
std::string_view data = R"(
let bad_B : N -> B, n -> n;
)";
CHECK_TYPE_BUILDER_THROWS_WITH(data, std::string{"invalid implicit conversion: N -> B"});
}
SECTION("Z -> B")
{
std::string_view data = R"(
let bad_B : Z -> B, n -> n;
)";
CHECK_TYPE_BUILDER_THROWS_WITH(data, std::string{"invalid implicit conversion: Z -> B"});
}
}
SECTION("invalid argument implicit conversion")
{
SECTION("N -> B")
{
std::string_view data = R"(
let negate : B -> B, b -> not b;
let n : N, n = 2;
negate(n);
)";
CHECK_EXPRESSION_BUILDER_THROWS_WITH(data, std::string{"invalid implicit conversion: N -> B"});
}
SECTION("Z -> B")
{
std::string_view data = R"(
let negate : B -> B, b -> not b;
negate(3-4);
)";
CHECK_EXPRESSION_BUILDER_THROWS_WITH(data, std::string{"invalid implicit conversion: Z -> B"});
}
SECTION("R -> B")
{
std::string_view data = R"(
let negate : B -> B, b -> not b;
negate(3.24);
)";
CHECK_EXPRESSION_BUILDER_THROWS_WITH(data, std::string{"invalid implicit conversion: R -> B"});
}
SECTION("R -> N")
{
std::string_view data = R"(
let next : N -> N, n -> n+1;
next(3.24);
)";
CHECK_EXPRESSION_BUILDER_THROWS_WITH(data, std::string{"invalid implicit conversion: R -> N"});
}
SECTION("R -> Z")
{
std::string_view data = R"(
let prev : Z -> Z, z -> z-1;
prev(3 + .24);
)";
CHECK_EXPRESSION_BUILDER_THROWS_WITH(data, std::string{"invalid implicit conversion: R -> Z"});
}
}
SECTION("arguments invalid tuple -> R^d conversion")
{
SECTION("tuple[3] -> R^2")
{
std::string_view data = R"(
let f : R^2 -> R, x->x[0];
f((1,2,3));
)";
CHECK_EXPRESSION_BUILDER_THROWS_WITH(data,
std::string{
"incompatible dimensions in affectation: expecting 2, but provided 3"});
}
SECTION("tuple[2] -> R^3")
{
std::string_view data = R"(
let f : R^3 -> R, x->x[0];
f((1,2));
)";
CHECK_EXPRESSION_BUILDER_THROWS_WITH(data,
std::string{
"incompatible dimensions in affectation: expecting 3, but provided 2"});
}
SECTION("compound tuple[3] -> R^2")
{
std::string_view data = R"(
let f : R*R^2 -> R, (t,x)->x[0];
f(1,(1,2,3));
)";
CHECK_EXPRESSION_BUILDER_THROWS_WITH(data,
std::string{
"incompatible dimensions in affectation: expecting 2, but provided 3"});
}
SECTION("compound tuple[2] -> R^3")
{
std::string_view data = R"(
let f : R^3*R^2 -> R, (x,y)->x[0]*y[1];
f((1,2),(3,4));
)";
CHECK_EXPRESSION_BUILDER_THROWS_WITH(data,
std::string{
"incompatible dimensions in affectation: expecting 3, but provided 2"});
}
SECTION("list instead of tuple -> R^3")
{
std::string_view data = R"(
let f : R^3 -> R, x -> x[0]*x[1];
f(1,2,3);
)";
CHECK_EXPRESSION_BUILDER_THROWS_WITH(data, std::string{"bad number of arguments: expecting 1, provided 3"});
}
SECTION("list instead of tuple -> R^3*R^2")
{
std::string_view data = R"(
let f : R^3*R^2 -> R, (x,y) -> x[0]*x[1]-y[0];
f((1,2,3),2,3);
)";
CHECK_EXPRESSION_BUILDER_THROWS_WITH(data, std::string{"bad number of arguments: expecting 2, provided 3"});
}
}
}
}