Skip to content
Snippets Groups Projects
Commit 4e2d898f authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Add tests for ASTNodeListAffectationExpressionBuilder

parent 39c4ed0b
No related branches found
No related tags found
1 merge request!37Feature/language
......@@ -95,8 +95,7 @@ ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor(
break;
}
default: {
throw parse_error("unexpected error: undefined value type for tuple affectation",
std::vector{value_node.begin()});
throw parse_error("undefined value type for tuple affectation", std::vector{value_node.begin()});
}
}
};
......@@ -142,7 +141,6 @@ ASTNodeListAffectationExpressionBuilder::ASTNodeListAffectationExpressionBuilder
throw parse_error("undefined affectation operator for tuples", std::vector{node.begin()});
}
} else {
throw parse_error("unexpected error: invalid right hand side in tuple affectation",
std::vector{node.children[1]->begin()});
throw parse_error("invalid right hand side in tuple affectation", std::vector{node.children[1]->begin()});
}
}
......@@ -25,6 +25,7 @@ add_executable (unit_tests
test_ASTNodeFunctionExpressionBuilder.cpp
test_ASTNodeIncDecExpressionBuilder.cpp
test_ASTNodeJumpPlacementChecker.cpp
test_ASTNodeListAffectationExpressionBuilder.cpp
test_ASTNodeListProcessor.cpp
test_ASTNodeTypeCleaner.cpp
test_ASTNodeUnaryOperatorExpressionBuilder.cpp
......
#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"});
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment