diff --git a/tests/test_ASTBuilder.cpp b/tests/test_ASTBuilder.cpp index 11c2afc9497c2362437c28c9f9fbb9fb4e3616e5..dfbeeaefc9fded484af12c9054d826419c360b40 100644 --- a/tests/test_ASTBuilder.cpp +++ b/tests/test_ASTBuilder.cpp @@ -4,46 +4,314 @@ #include <ASTPrinter.hpp> #include <sstream> -TEST_CASE("ASTBuilder", "[language]") +void +build_ast(const std::string_view& data) { using namespace language; + string_input input{data, "test.pgs"}; + buildAST(input); +} - SECTION("checking AST simplifications"){} - { - std::stringstream ss{R"( -Z a = -3; -Z b = - - + - 2; -Z d; +void +check_ast(const std::string_view& data, const std::string_view& expected_output) { - Z c=3; - d = (0 - -c)/3; + using namespace language; + + string_input input{data, "test.pgs"}; + auto ast = buildAST(input); + + std::stringstream ast_output; + ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::none}}; + + REQUIRE(ast_output.str() == expected_output); } -Z e = 0 + +3; -Z f = 0 + -3; - -B g = not not true; -R h = 0; -R i = h++; -i--; -)"}; - - istream_input input{ss, ss.str().size(), "test.pgs"}; - auto ast = buildAST(input); - std::stringstream ast_output; - ast_output << ASTPrinter{*ast, ASTPrinter::Format::raw}; - REQUIRE(true); - } - REQUIRE(true); +TEST_CASE("ASTBuilder", "[language]") +{ + rang::setControlMode(rang::control::Off); + SECTION("AST parsing") + { + SECTION("declarations with init") + { + std::string_view data = R"( +N n = 2; +Z z = 3; +R r = 2.3e-5; +B b = false; +string s = "foo"; +)"; - SECTION("checking for copies") {} + std::string_view result = R"( +(root) + +-(language::declaration) + | +-(language::N_set) + | +-(language::name:n) + | `-(language::integer:2) + +-(language::declaration) + | +-(language::Z_set) + | +-(language::name:z) + | `-(language::integer:3) + +-(language::declaration) + | +-(language::R_set) + | +-(language::name:r) + | `-(language::real:2.3e-5) + +-(language::declaration) + | +-(language::B_set) + | +-(language::name:b) + | `-(language::false_kw) + `-(language::declaration) + +-(language::string_type) + +-(language::name:s) + `-(language::literal:"foo") +)"; + check_ast(data, result); + } - SECTION("checking for fill") {} + SECTION("affectations") + { + std::string_view data = R"( +N n; n = 2; +Z z; z = 3; +R r; r = 2.3e-5; +B b; b = false; +string s; s = "foo"; +)"; - SECTION("checking for affectations (shallow copy)") {} + std::string_view result = R"( +(root) + +-(language::declaration) + | +-(language::N_set) + | `-(language::name:n) + +-(language::eq_op) + | +-(language::name:n) + | `-(language::integer:2) + +-(language::declaration) + | +-(language::Z_set) + | `-(language::name:z) + +-(language::eq_op) + | +-(language::name:z) + | `-(language::integer:3) + +-(language::declaration) + | +-(language::R_set) + | `-(language::name:r) + +-(language::eq_op) + | +-(language::name:r) + | `-(language::real:2.3e-5) + +-(language::declaration) + | +-(language::B_set) + | `-(language::name:b) + +-(language::eq_op) + | +-(language::name:b) + | `-(language::false_kw) + +-(language::declaration) + | +-(language::string_type) + | `-(language::name:s) + `-(language::eq_op) + +-(language::name:s) + `-(language::literal:"foo") +)"; + check_ast(data, result); + } - SECTION("checking for bounds violation") + SECTION("empty blocs simplification") + { + std::string_view data = R"( +{ + /* nothing but a bloc */ { - // REQUIRE_THROWS_AS(a[10], AssertError); + ; // nothing + } +} +)"; + + std::string_view result = R"( +(root) +)"; + check_ast(data, result); + } + + SECTION("operators precedence") + { + SECTION("basic operations") + { + std::string_view data = R"( +2+3.2*6 - 3.2/4; +)"; + + std::string_view result = R"( +(root) + `-(language::minus_op) + +-(language::plus_op) + | +-(language::integer:2) + | `-(language::multiply_op) + | +-(language::real:3.2) + | `-(language::integer:6) + `-(language::divide_op) + +-(language::real:3.2) + `-(language::integer:4) +)"; + check_ast(data, result); + } + + SECTION("parented expression") + { + std::string_view data = R"( +(2+3)*6; +)"; + + std::string_view result = R"( +(root) + `-(language::multiply_op) + +-(language::plus_op) + | +-(language::integer:2) + | `-(language::integer:3) + `-(language::integer:6) +)"; + check_ast(data, result); + } + + SECTION("all operators mix") + { + std::string_view data = R"( +1+2 and 3<= 2 * 4 - 1 == 2 or 2>=1 / 5 ^ 6 & 7 && 2 || 1 | 2 <3 >7 xor -2 bitand 2 bitor + true - not false; +)"; + + std::string_view result = R"( +(root) + `-(language::minus_op) + +-(language::bitor_op) + | +-(language::bitand_op) + | | +-(language::xor_op) + | | | +-(language::greater_op) + | | | | +-(language::lesser_op) + | | | | | +-(language::bitor_op) + | | | | | | +-(language::or_op) + | | | | | | | +-(language::and_op) + | | | | | | | | +-(language::bitand_op) + | | | | | | | | | +-(language::xor_op) + | | | | | | | | | | +-(language::greater_or_eq_op) + | | | | | | | | | | | +-(language::or_op) + | | | | | | | | | | | | +-(language::eqeq_op) + | | | | | | | | | | | | | +-(language::minus_op) + | | | | | | | | | | | | | | +-(language::lesser_or_eq_op) + | | | | | | | | | | | | | | | +-(language::and_op) + | | | | | | | | | | | | | | | | +-(language::plus_op) + | | | | | | | | | | | | | | | | | +-(language::integer:1) + | | | | | | | | | | | | | | | | | `-(language::integer:2) + | | | | | | | | | | | | | | | | `-(language::integer:3) + | | | | | | | | | | | | | | | `-(language::multiply_op) + | | | | | | | | | | | | | | | +-(language::integer:2) + | | | | | | | | | | | | | | | `-(language::integer:4) + | | | | | | | | | | | | | | `-(language::integer:1) + | | | | | | | | | | | | | `-(language::integer:2) + | | | | | | | | | | | | `-(language::integer:2) + | | | | | | | | | | | `-(language::divide_op) + | | | | | | | | | | | +-(language::integer:1) + | | | | | | | | | | | `-(language::integer:5) + | | | | | | | | | | `-(language::integer:6) + | | | | | | | | | `-(language::integer:7) + | | | | | | | | `-(language::integer:2) + | | | | | | | `-(language::integer:1) + | | | | | | `-(language::integer:2) + | | | | | `-(language::integer:3) + | | | | `-(language::integer:7) + | | | `-(language::unary_minus) + | | | `-(language::integer:2) + | | `-(language::integer:2) + | `-(language::true_kw) + `-(language::unary_not) + `-(language::false_kw) +)"; + check_ast(data, result); + } + } + + SECTION("unary operator simplification") + { + SECTION("multiple not") + { + std::string_view data = R"( +not not not not true; +not not not false; +)"; + + std::string_view result = R"( +(root) + +-(language::true_kw) + `-(language::unary_not) + `-(language::false_kw) +)"; + check_ast(data, result); + } + + SECTION("multiple unary plus") + { + std::string_view data = R"( ++ + + 3; +)"; + + std::string_view result = R"( +(root) + `-(language::integer:3) +)"; + check_ast(data, result); + } + + SECTION("multiple unary minus") + { + std::string_view data = R"( +- - + - - 3; +- + - - 2; +)"; + + std::string_view result = R"( +(root) + +-(language::integer:3) + `-(language::unary_minus) + `-(language::integer:2) +)"; + check_ast(data, result); + } + + SECTION("sums and unary plus/minus") + { + std::string_view data = R"( +1 - - 3; +1 + - 2; +4 - + 3; +)"; + + std::string_view result = R"( +(root) + +-(language::plus_op) + | +-(language::integer:1) + | `-(language::integer:3) + +-(language::minus_op) + | +-(language::integer:1) + | `-(language::integer:2) + `-(language::minus_op) + +-(language::integer:4) + `-(language::integer:3) +)"; + check_ast(data, result); + } + } + + SECTION("post incr/decr rearrangements") + { + std::string_view data = R"( +1++; +2--; +)"; + + std::string_view result = R"( +(root) + +-(language::post_plusplus) + | `-(language::integer:1) + `-(language::post_minusminus) + `-(language::integer:2) +)"; + check_ast(data, result); + } } }