Select Git revision
TypeOfItem.hpp
test_ASTNodeListAffectationExpressionBuilder.cpp 11.07 KiB
#include <catch2/catch.hpp>
#include <ASTBuilder.hpp>
#include <ASTNodeDataTypeBuilder.hpp>
#include <ASTNodeDeclarationToAffectationConverter.hpp>
#include <ASTNodeTypeCleaner.hpp>
#include <ASTNodeExpressionBuilder.hpp>
#include <ASTNodeListAffectationExpressionBuilder.hpp>
#include <ASTSymbolTableBuilder.hpp>
#include <ASTPrinter.hpp>
#include <Demangle.hpp>
#include <PEGGrammar.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>); \
\
string_input input{data, "test.pgs"}; \
auto ast = ASTBuilder::build(input); \
\
ASTSymbolTableBuilder{*ast}; \
ASTNodeDataTypeBuilder{*ast}; \
\
ASTNodeDeclarationToAffectationConverter{*ast}; \
ASTNodeTypeCleaner<language::declaration>{*ast}; \
ASTNodeTypeCleaner<language::let_declaration>{*ast}; \
\
ASTNodeExpressionBuilder{*ast}; \
\
std::stringstream ast_output; \
ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::exec_type}}; \
\
REQUIRE(ast_output.str() == expected_output); \
}
#define CHECK_AST_THROWS_WITH(data, error) \
{ \
static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>); \
static_assert(std::is_same_v<std::decay_t<decltype(error)>, std::string>); \
\
string_input input{data, "test.pgs"}; \
auto ast = ASTBuilder::build(input); \
\
ASTSymbolTableBuilder{*ast}; \
ASTNodeDataTypeBuilder{*ast}; \
\
ASTNodeDeclarationToAffectationConverter{*ast}; \
ASTNodeTypeCleaner<language::declaration>{*ast}; \
ASTNodeTypeCleaner<language::let_declaration>{*ast}; \
\
REQUIRE_THROWS_WITH(ASTNodeExpressionBuilder{*ast}, error); \
}
TEST_CASE("ASTNodeListAffectationExpressionBuilder", "[language]")
{
const std::string demangled_stdstring = demangle(typeid(std::string{}).name());
SECTION("Declaration")
{
SECTION("without conversion R*R")
{
std::string_view data = R"(
R*R (x,y) = (2.3, 6.2);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::eq_op:ListAffectationProcessor<language::eq_op>)
+-(language::name_list:FakeProcessor)
| +-(language::name:x:NameProcessor)
| `-(language::name:y:NameProcessor)
`-(language::expression_list:ASTNodeExpressionListProcessor)
+-(language::real:2.3:ValueProcessor)
`-(language::real:6.2:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("without conversion B*Z*N")
{
std::string_view data = R"(
N n = 2;
B*Z*N (b,z,m) = (false, -2, n);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
+-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
| +-(language::name:n:NameProcessor)
| `-(language::integer:2:ValueProcessor)
`-(language::eq_op:ListAffectationProcessor<language::eq_op>)
+-(language::name_list:FakeProcessor)
| +-(language::name:b:NameProcessor)
| +-(language::name:z:NameProcessor)
| `-(language::name:m:NameProcessor)
`-(language::expression_list:ASTNodeExpressionListProcessor)
+-(language::false_kw:ValueProcessor)
+-(language::unary_minus:UnaryExpressionProcessor<language::unary_minus, long, long>)
| `-(language::integer:2:ValueProcessor)
`-(language::name:n:NameProcessor)
)";
CHECK_AST(data, result);
}
SECTION("with conversion R*B*Z*N")
{
std::string_view data = R"(
R*B*Z*N (r,b,z,m) = (3.2, 1, 6, 2);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::eq_op:ListAffectationProcessor<language::eq_op>)
+-(language::name_list:FakeProcessor)
| +-(language::name:r:NameProcessor)
| +-(language::name:b:NameProcessor)
| +-(language::name:z:NameProcessor)
| `-(language::name:m:NameProcessor)
`-(language::expression_list:ASTNodeExpressionListProcessor)
+-(language::real:3.2:ValueProcessor)
+-(language::integer:1:ValueProcessor)
+-(language::integer:6:ValueProcessor)
`-(language::integer:2:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("with conversion R*R*R*R")
{
std::string_view data = R"(
R*R*R*R (r,b,z,m) = (3.2, 1, 6, 2);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::eq_op:ListAffectationProcessor<language::eq_op>)
+-(language::name_list:FakeProcessor)
| +-(language::name:r:NameProcessor)
| +-(language::name:b:NameProcessor)
| +-(language::name:z:NameProcessor)
| `-(language::name:m:NameProcessor)
`-(language::expression_list:ASTNodeExpressionListProcessor)
+-(language::real:3.2:ValueProcessor)
+-(language::integer:1:ValueProcessor)
+-(language::integer:6:ValueProcessor)
`-(language::integer:2:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("from function")
{
std::string_view data = R"(
let f: R -> R*R, x -> (x*x, x+1);
R*R (x,y) = f(2);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::eq_op:ListAffectationProcessor<language::eq_op>)
+-(language::name_list:FakeProcessor)
| +-(language::name:x:NameProcessor)
| `-(language::name:y:NameProcessor)
`-(language::function_evaluation:FunctionProcessor)
+-(language::name:f:NameProcessor)
`-(language::integer:2:ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("string without conversion")
{
std::string_view data = R"(
string*string (s,r) = ("foo","bar");
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
`-(language::eq_op:ListAffectationProcessor<language::eq_op>)
+-(language::name_list:FakeProcessor)
| +-(language::name:s:NameProcessor)
| `-(language::name:r:NameProcessor)
`-(language::expression_list:ASTNodeExpressionListProcessor)
+-(language::literal:"foo":ValueProcessor)
`-(language::literal:"bar":ValueProcessor)
)";
CHECK_AST(data, result);
}
SECTION("string with conversion")
{
std::string_view data = R"(
N n =2;
string*string*string*string (r,s,t,u) = (3.2, -2, true, n);
)";
std::string_view result = R"(
(root:ASTNodeListProcessor)
+-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>)
| +-(language::name:n:NameProcessor)
| `-(language::integer:2:ValueProcessor)
`-(language::eq_op:ListAffectationProcessor<language::eq_op>)
+-(language::name_list:FakeProcessor)
| +-(language::name:r:NameProcessor)
| +-(language::name:s:NameProcessor)
| +-(language::name:t:NameProcessor)
| `-(language::name:u:NameProcessor)
`-(language::expression_list:ASTNodeExpressionListProcessor)
+-(language::real:3.2:ValueProcessor)
+-(language::unary_minus:UnaryExpressionProcessor<language::unary_minus, long, long>)
| `-(language::integer:2:ValueProcessor)
+-(language::true_kw:ValueProcessor)
`-(language::name:n:NameProcessor)
)";
CHECK_AST(data, result);
}
}
SECTION("Errors")
{
SECTION("invalid affectation rhs")
{
std::string_view data = R"(
R x;
R i;
(x,i) = 3;
)";
CHECK_AST_THROWS_WITH(data, std::string{"invalid right hand side in tuple affectation"});
}
SECTION("incompatible list sizes")
{
std::string_view data = R"(
R*R (x,y) = (3, 3, 2);
)";
CHECK_AST_THROWS_WITH(data, std::string{"incompatible list sizes in affectation"});
}
SECTION("incompatible list sizes 2")
{
std::string_view data = R"(
R*R*R (x,y,z) = (1, 2);
)";
CHECK_AST_THROWS_WITH(data, std::string{"incompatible list sizes in affectation"});
}
SECTION("incompatible list sizes from function evaluation")
{
std::string_view data = R"(
let f: R -> R, x -> x*x;
R*R (x,y) = f(3);
)";
CHECK_AST_THROWS_WITH(data, std::string{"incompatible list sizes in affectation"});
}
SECTION("incompatible list sizes from function evaluation")
{
std::string_view data = R"(
R*R (x,y) = (2,3);
(x,y) += (1,4);
)";
CHECK_AST_THROWS_WITH(data, std::string{"undefined affectation operator for tuples"});
}
SECTION("invalid operand type for affectation")
{
std::string_view data = R"(
let f: R -> R, x -> x+1;
R*R (x,y) = (f,2);
)";
CHECK_AST_THROWS_WITH(data, std::string{"invalid operand type for affectation"});
}
SECTION("invalid operand type for string affectation")
{
std::string_view data = R"(
let f: R -> R, x -> x+1;
string*N (s,n) = (f,2);
)";
CHECK_AST_THROWS_WITH(data, std::string{"invalid operand type for string affectation"});
}
SECTION("invalid value type for affectation")
{
std::string_view data = R"(
let f: R -> R, x -> x+1;
R x;
(f,x) = (3,2);
)";
CHECK_AST_THROWS_WITH(data, std::string{"undefined value type for tuple affectation"});
}
}
}