diff --git a/test/parser/expression.cpp b/test/parser/expression.cpp index f7ba230..de29f9e 100644 --- a/test/parser/expression.cpp +++ b/test/parser/expression.cpp @@ -98,4 +98,111 @@ TEST_SUITE("Parser: expression") { CASE("Infix: '!='", "15 != 5;", 15, "!=", 5); #undef CASE } + + + TEST_CASE_FIXTURE(ParserFixture, "Slightly more complex infix expression") { + setup("5 - -15;"); + + REQUIRE(program->statements.size() == 1); + ast::expression_stmt* expression_stmt = + cast(program->statements[0]); + + ast::infix_expr* infix_expr = + cast(expression_stmt->expression); + + test_integer_literal(infix_expr->left, 5); + CHECK(infix_expr->op == "-"); + + ast::prefix_expr* prefix_expr = + cast(infix_expr->right); + + CHECK(prefix_expr->op == "-"); + test_integer_literal(prefix_expr->right, 15); + } + + TEST_CASE_FIXTURE( + ParserFixture, + "Slightly even more complex infix expression" + ) { + setup("5 - -15 * 3;"); + + REQUIRE(program->statements.size() == 1); + ast::expression_stmt* expression_stmt = + cast(program->statements[0]); + + ast::infix_expr* infix_expr = + cast(expression_stmt->expression); + + test_integer_literal(infix_expr->left, 5); + CHECK(infix_expr->op == "-"); + + ast::infix_expr* second_infix_expr = + cast(infix_expr->right); + CHECK(second_infix_expr->op == "*"); + + ast::prefix_expr* prefix_expr = + cast(second_infix_expr->left); + + CHECK(prefix_expr->op == "-"); + test_integer_literal(prefix_expr->right, 15); + + test_integer_literal(second_infix_expr->right, 3); + } + + TEST_CASE_FIXTURE( + ParserFixture, + "Checking operator precedence with simple example" + ) { + setup("5 * -15 - 3;"); + + REQUIRE(program->statements.size() == 1); + ast::expression_stmt* expression_stmt = + cast(program->statements[0]); + + ast::infix_expr* infix_expr = + cast(expression_stmt->expression); + + + ast::infix_expr* second_infix_expr = + cast(infix_expr->left); + CHECK(second_infix_expr->op == "*"); + test_integer_literal(second_infix_expr->left, 5); + + ast::prefix_expr* prefix_expr = + cast(second_infix_expr->right); + + CHECK(prefix_expr->op == "-"); + test_integer_literal(prefix_expr->right, 15); + + CHECK(infix_expr->op == "-"); + test_integer_literal(infix_expr->right, 3); + } + + TEST_CASE_FIXTURE(ParserFixture, "Full Operator Precedence test") { + struct test { + std::string input; + std::string expected; + }; + + struct test tests[]{ + {"-a * b", "((-a) * b)"}, + {"!-a", "(!(-a))"}, + {"a + b + c", "((a + b) + c)"}, + {"a + b - c", "((a + b) - c)"}, + {"a * b * c", "((a * b) * c)"}, + {"a * b / c", "((a * b) / c)"}, + {"a + b / c", "(a + (b / c))"}, + {"a + b * c + d / e - f", "(((a + (b * c)) + (d / e)) - f)"}, + {"3 + 4; -5 * 5", "(3 + 4)((-5) * 5)"}, + {"5 > 4 == 3 < 4", "((5 > 4) == (3 < 4))"}, + {"5 < 4 != 3 > 4", "((5 < 4) != (3 > 4))"}, + {"3 + 4 * 5 == 3 * 1 + 4 * 5", + "((3 + (4 * 5)) == ((3 * 1) + (4 * 5)))"}, + }; + + for (auto& t : tests) { + setup(t.input); + CHECK(program->str() == t.expected); + } + } }