From be4ce7ae61b3a1eaa3c714fd1789f28652201ea0 Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Tue, 30 Jul 2019 15:15:11 +0200 Subject: [PATCH] Add tests for ASTNodeExpressionBuilder Also performed slight cosmetic changes in ASTNodeExpressionBuilder::_buildExpression --- src/language/ASTNodeExpressionBuilder.cpp | 8 +- tests/test_ASTNodeExpressionBuilder.cpp | 743 +++++++++++++++++++++- 2 files changed, 723 insertions(+), 28 deletions(-) diff --git a/src/language/ASTNodeExpressionBuilder.cpp b/src/language/ASTNodeExpressionBuilder.cpp index c1a1fb8ac..756d40245 100644 --- a/src/language/ASTNodeExpressionBuilder.cpp +++ b/src/language/ASTNodeExpressionBuilder.cpp @@ -336,6 +336,10 @@ ASTNodeExpressionBuilder::_buildExpression(ASTNode& n) n.m_node_processor = std::make_unique<NoProcess>(); } else if (n.is<language::literal>()) { n.m_node_processor = std::make_unique<NoProcess>(); + } else if (n.is<language::true_kw>()) { + n.m_node_processor = std::make_unique<NoProcess>(); + } else if (n.is<language::false_kw>()) { + n.m_node_processor = std::make_unique<NoProcess>(); } else if (n.is<language::name>()) { n.m_node_processor = std::make_unique<NameExpression>(n); @@ -382,10 +386,6 @@ ASTNodeExpressionBuilder::_buildExpression(ASTNode& n) n.m_node_processor = std::make_unique<BreakExpression>(); } else if (n.is<language::continue_kw>()) { n.m_node_processor = std::make_unique<ContinueExpression>(); - } else if (n.is<language::true_kw>()) { - n.m_node_processor = std::make_unique<NoProcess>(); - } else if (n.is<language::false_kw>()) { - n.m_node_processor = std::make_unique<NoProcess>(); } else { std::ostringstream error_message; error_message << "undefined node type '" << rang::fgB::red << n.name() << rang::fg::reset << "'"; diff --git a/tests/test_ASTNodeExpressionBuilder.cpp b/tests/test_ASTNodeExpressionBuilder.cpp index b7a6c82a1..f1ca3f8ab 100644 --- a/tests/test_ASTNodeExpressionBuilder.cpp +++ b/tests/test_ASTNodeExpressionBuilder.cpp @@ -14,6 +14,8 @@ #include <ASTPrinter.hpp> +#include <PEGGrammar.hpp> + #include <Demangle.hpp> #define CHECK_AST(data, expected_output) \ @@ -41,7 +43,7 @@ TEST_CASE("ASTNodeExpressionBuilder", "[language]") { - SECTION("nothing to convert") + SECTION("empty file") { std::string_view data = R"( )"; @@ -53,71 +55,764 @@ TEST_CASE("ASTNodeExpressionBuilder", "[language]") CHECK_AST(data, result); } - SECTION("string affectation") + SECTION("values") { - SECTION("from bool") + SECTION("integer") { std::string_view data = R"( -string s = true; +3; )"; std::string result = R"( (root:ASTNodeList) - `-(language::eq_op:AffectationToStringProcessor<language::eq_op, bool>) - +-(language::name:s:NameExpression) - `-(language::true_kw:NoProcess) + `-(language::integer:3:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("real") + { + std::string_view data = R"( +2.3e-5; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::real:2.3e-5:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("literal") + { + std::string_view data = R"( +"foo"; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::literal:"foo":NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("true") + { + std::string_view data = R"( +true; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::true_kw:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("false") + { + std::string_view data = R"( +false; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::false_kw:NoProcess) +)"; + + CHECK_AST(data, result); + } + } + + SECTION("bloc") + { + std::string_view data = R"( +{ + 1; +} +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::bloc:ASTNodeList) + `-(language::integer:1:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("name") + { + std::string_view data = R"( +N i; +i; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::name:i:NameExpression) +)"; + + CHECK_AST(data, result); + } + + SECTION("affectations") + { + SECTION("operator=") + { + std::string_view data = R"( +N i = 1; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>) + +-(language::name:i:NameExpression) + `-(language::integer:1:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("operator*=") + { + std::string_view data = R"( +N i = 1; +i *= 3; +)"; + + std::string result = R"( +(root:ASTNodeList) + +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>) + | +-(language::name:i:NameExpression) + | `-(language::integer:1:NoProcess) + `-(language::multiplyeq_op:AffectationProcessor<language::multiplyeq_op, unsigned long, long>) + +-(language::name:i:NameExpression) + `-(language::integer:3:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("operator/=") + { + std::string_view data = R"( +R x = 1; +x /= 2; +)"; + + std::string result = R"( +(root:ASTNodeList) + +-(language::eq_op:AffectationProcessor<language::eq_op, double, long>) + | +-(language::name:x:NameExpression) + | `-(language::integer:1:NoProcess) + `-(language::divideeq_op:AffectationProcessor<language::divideeq_op, double, long>) + +-(language::name:x:NameExpression) + `-(language::integer:2:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("operator+=") + { + std::string_view data = R"( +N i = 1; +i += 3.; +)"; + + std::string result = R"( +(root:ASTNodeList) + +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>) + | +-(language::name:i:NameExpression) + | `-(language::integer:1:NoProcess) + `-(language::pluseq_op:AffectationProcessor<language::pluseq_op, unsigned long, double>) + +-(language::name:i:NameExpression) + `-(language::real:3.:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("operator-=") + { + std::string_view data = R"( +Z z = 1; +z -= 2; +)"; + + std::string result = R"( +(root:ASTNodeList) + +-(language::eq_op:AffectationProcessor<language::eq_op, long, long>) + | +-(language::name:z:NameExpression) + | `-(language::integer:1:NoProcess) + `-(language::minuseq_op:AffectationProcessor<language::minuseq_op, long, long>) + +-(language::name:z:NameExpression) + `-(language::integer:2:NoProcess) +)"; + + CHECK_AST(data, result); + } + } + + SECTION("unary operators") + { + SECTION("unary minus") + { + std::string_view data = R"( +-1; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::unary_minus:UnaryExpressionProcessor<language::unary_minus, long, long>) + `-(language::integer:1:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("unary not") + { + std::string_view data = R"( +not 1; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::unary_not:UnaryExpressionProcessor<language::unary_not, bool, long>) + `-(language::integer:1:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("pre-increment operator") + { + std::string_view data = R"( +Z a=1; +++a; +)"; + + std::string result = R"( +(root:ASTNodeList) + +-(language::eq_op:AffectationProcessor<language::eq_op, long, long>) + | +-(language::name:a:NameExpression) + | `-(language::integer:1:NoProcess) + `-(language::unary_plusplus:IncDecExpressionProcessor<language::unary_plusplus, long, long>) + `-(language::name:a:NameExpression) +)"; + + CHECK_AST(data, result); + } + + SECTION("pre-decrement operator") + { + std::string_view data = R"( +Z a=1; +--a; +)"; + + std::string result = R"( +(root:ASTNodeList) + +-(language::eq_op:AffectationProcessor<language::eq_op, long, long>) + | +-(language::name:a:NameExpression) + | `-(language::integer:1:NoProcess) + `-(language::unary_minusminus:IncDecExpressionProcessor<language::unary_minusminus, long, long>) + `-(language::name:a:NameExpression) +)"; + + CHECK_AST(data, result); + } + + SECTION("post-increment operator") + { + std::string_view data = R"( +Z a=1; +a++; +)"; + + std::string result = R"( +(root:ASTNodeList) + +-(language::eq_op:AffectationProcessor<language::eq_op, long, long>) + | +-(language::name:a:NameExpression) + | `-(language::integer:1:NoProcess) + `-(language::post_plusplus:IncDecExpressionProcessor<language::post_plusplus, long, long>) + `-(language::name:a:NameExpression) +)"; + + CHECK_AST(data, result); + } + + SECTION("post-decrement operator") + { + std::string_view data = R"( +Z a=1; +a--; +)"; + + std::string result = R"( +(root:ASTNodeList) + +-(language::eq_op:AffectationProcessor<language::eq_op, long, long>) + | +-(language::name:a:NameExpression) + | `-(language::integer:1:NoProcess) + `-(language::post_minusminus:IncDecExpressionProcessor<language::post_minusminus, long, long>) + `-(language::name:a:NameExpression) +)"; + + CHECK_AST(data, result); + } + } + + SECTION("binary operators") + { + SECTION("multiply") + { + std::string_view data = R"( +1*2; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::multiply_op:BinaryExpressionProcessor<language::multiply_op, long, long>) + +-(language::integer:1:NoProcess) + `-(language::integer:2:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("divide") + { + std::string_view data = R"( +1/2; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::divide_op:BinaryExpressionProcessor<language::divide_op, long, long>) + +-(language::integer:1:NoProcess) + `-(language::integer:2:NoProcess) )"; CHECK_AST(data, result); } - SECTION("from int") + SECTION("plus") { std::string_view data = R"( -string s = 0; +1+2; )"; std::string result = R"( (root:ASTNodeList) - `-(language::eq_op:AffectationToStringProcessor<language::eq_op, long>) - +-(language::name:s:NameExpression) - `-(language::integer:0:NoProcess) + `-(language::plus_op:BinaryExpressionProcessor<language::plus_op, long, long>) + +-(language::integer:1:NoProcess) + `-(language::integer:2:NoProcess) )"; + + CHECK_AST(data, result); + } + + SECTION("minus") + { + std::string_view data = R"( +1-2; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::minus_op:BinaryExpressionProcessor<language::minus_op, long, long>) + +-(language::integer:1:NoProcess) + `-(language::integer:2:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("or") + { + std::string_view data = R"( +1 or 2; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::or_op:BinaryExpressionProcessor<language::or_op, long, long>) + +-(language::integer:1:NoProcess) + `-(language::integer:2:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("and") + { + std::string_view data = R"( +1 and 2; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::and_op:BinaryExpressionProcessor<language::and_op, long, long>) + +-(language::integer:1:NoProcess) + `-(language::integer:2:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("xor") + { + std::string_view data = R"( +1 xor 2; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::xor_op:BinaryExpressionProcessor<language::xor_op, long, long>) + +-(language::integer:1:NoProcess) + `-(language::integer:2:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("lesser") + { + std::string_view data = R"( +1 < 2; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, long, long>) + +-(language::integer:1:NoProcess) + `-(language::integer:2:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("lesser or equal") + { + std::string_view data = R"( +1 <= 2; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::lesser_or_eq_op:BinaryExpressionProcessor<language::lesser_or_eq_op, long, long>) + +-(language::integer:1:NoProcess) + `-(language::integer:2:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("greater") + { + std::string_view data = R"( +1 > 2; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::greater_op:BinaryExpressionProcessor<language::greater_op, long, long>) + +-(language::integer:1:NoProcess) + `-(language::integer:2:NoProcess) +)"; + CHECK_AST(data, result); } - SECTION("from unsigned") + SECTION("greater or equal") { std::string_view data = R"( -N n = 0; -string s = n; +1 >= 2; )"; std::string result = R"( +(root:ASTNodeList) + `-(language::greater_or_eq_op:BinaryExpressionProcessor<language::greater_or_eq_op, long, long>) + +-(language::integer:1:NoProcess) + `-(language::integer:2:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("equal") + { + std::string_view data = R"( +1 == 2; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::eqeq_op:BinaryExpressionProcessor<language::eqeq_op, long, long>) + +-(language::integer:1:NoProcess) + `-(language::integer:2:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("different") + { + std::string_view data = R"( +1 != 2; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::not_eq_op:BinaryExpressionProcessor<language::not_eq_op, long, long>) + +-(language::integer:1:NoProcess) + `-(language::integer:2:NoProcess) +)"; + + CHECK_AST(data, result); + } + } + + SECTION("ostream objects") + { + SECTION("cout") + { + std::string_view data = R"( +cout; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::cout_kw:OStreamObject) +)"; + + CHECK_AST(data, result); + } + + SECTION("cerr") + { + std::string_view data = R"( +cerr; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::cerr_kw:OStreamObject) +)"; + + CHECK_AST(data, result); + } + + SECTION("clog") + { + std::string_view data = R"( +clog; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::clog_kw:OStreamObject) +)"; + + CHECK_AST(data, result); + } + } + + SECTION("statements") + { + SECTION("if") + { + std::string_view data = R"( +if(true); +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::if_statement:IfStatement) + +-(language::true_kw:NoProcess) + `-(language::statement_bloc:ASTNodeList) +)"; + + CHECK_AST(data, result); + } + + SECTION("do while") + { + std::string_view data = R"( +do; while(true); +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::do_while_statement:DoWhileStatement) + +-(language::statement_bloc:ASTNodeList) + `-(language::true_kw:NoProcess) +)"; + + CHECK_AST(data, result); + } + + SECTION("while") + { + std::string_view data = R"( +while(true); +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::while_statement:WhileStatement) + +-(language::true_kw:NoProcess) + `-(language::statement_bloc:ASTNodeList) +)"; + + CHECK_AST(data, result); + } + + SECTION("for") + { + SECTION("for_statement") + { + std::string_view data = R"( +for(N i=0; i<10; ++i); +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::for_statement:ForStatement) + +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>) + | +-(language::name:i:NameExpression) + | `-(language::integer:0:NoProcess) + +-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, unsigned long, long>) + | +-(language::name:i:NameExpression) + | `-(language::integer:10:NoProcess) + +-(language::unary_plusplus:IncDecExpressionProcessor<language::unary_plusplus, unsigned long, unsigned long>) + | `-(language::name:i:NameExpression) + `-(language::for_statement_bloc:ASTNodeList) +)"; + + CHECK_AST(data, result); + } + + SECTION("no init") + { + std::string_view data = R"( +N i=0; +for(; i<10; ++i); +)"; + + std::string result = R"( (root:ASTNodeList) +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>) - | +-(language::name:n:NameExpression) + | +-(language::name:i:NameExpression) | `-(language::integer:0:NoProcess) - `-(language::eq_op:AffectationToStringProcessor<language::eq_op, unsigned long>) - +-(language::name:s:NameExpression) - `-(language::name:n:NameExpression) + `-(language::for_statement:ForStatement) + +-(language::for_init:NoProcess) + +-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, unsigned long, long>) + | +-(language::name:i:NameExpression) + | `-(language::integer:10:NoProcess) + +-(language::unary_plusplus:IncDecExpressionProcessor<language::unary_plusplus, unsigned long, unsigned long>) + | `-(language::name:i:NameExpression) + `-(language::for_statement_bloc:ASTNodeList) +)"; + + CHECK_AST(data, result); + } + + SECTION("no test") + { + std::string_view data = R"( +for(N i=0; ; ++i); +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::for_statement:ForStatement) + +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>) + | +-(language::name:i:NameExpression) + | `-(language::integer:0:NoProcess) + +-(language::for_test:NoProcess) + +-(language::unary_plusplus:IncDecExpressionProcessor<language::unary_plusplus, unsigned long, unsigned long>) + | `-(language::name:i:NameExpression) + `-(language::for_statement_bloc:ASTNodeList) )"; + + CHECK_AST(data, result); + } + + SECTION("no post instruction") + { + std::string_view data = R"( +for(N i=0; i<10;); +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::for_statement:ForStatement) + +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>) + | +-(language::name:i:NameExpression) + | `-(language::integer:0:NoProcess) + +-(language::lesser_op:BinaryExpressionProcessor<language::lesser_op, unsigned long, long>) + | +-(language::name:i:NameExpression) + | `-(language::integer:10:NoProcess) + +-(language::for_post:NoProcess) + `-(language::for_statement_bloc:ASTNodeList) +)"; + + CHECK_AST(data, result); + } + } + } + + SECTION("jumps instruction") + { + SECTION("break") + { + std::string_view data = R"( +break; +)"; + + std::string result = R"( +(root:ASTNodeList) + `-(language::break_kw:BreakExpression) +)"; + CHECK_AST(data, result); } - SECTION("from real") + SECTION("continue") { std::string_view data = R"( -string s = 0.; +continue; )"; std::string result = R"( (root:ASTNodeList) - `-(language::eq_op:AffectationToStringProcessor<language::eq_op, double>) - +-(language::name:s:NameExpression) - `-(language::real:0.:NoProcess) + `-(language::continue_kw:ContinueExpression) )"; + CHECK_AST(data, result); } } + + SECTION("unexpected node type") + { + std::string_view data = R"( +1; +)"; + + string_input input{data, "test.pgs"}; + auto ast = ASTBuilder::build(input); + ASTNodeDataTypeBuilder{*ast}; + + // One is sure that language::ignored is not treated so its a good candidate + // for this test + ast->children[0]->id = typeid(language::ignored); + REQUIRE_THROWS_AS(ASTNodeExpressionBuilder{*ast}, parse_error); + } } -- GitLab