added extensive testing for operator precedence

This commit is contained in:
Karma Riuk
2025-07-11 11:39:55 +02:00
parent a1192204b1
commit c9ffeafd5f

View File

@@ -98,4 +98,111 @@ TEST_SUITE("Parser: expression") {
CASE("Infix: '!='", "15 != 5;", 15, "!=", 5); CASE("Infix: '!='", "15 != 5;", 15, "!=", 5);
#undef CASE #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<ast::expression_stmt>(program->statements[0]);
ast::infix_expr* infix_expr =
cast<ast::infix_expr>(expression_stmt->expression);
test_integer_literal(infix_expr->left, 5);
CHECK(infix_expr->op == "-");
ast::prefix_expr* prefix_expr =
cast<ast::prefix_expr>(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<ast::expression_stmt>(program->statements[0]);
ast::infix_expr* infix_expr =
cast<ast::infix_expr>(expression_stmt->expression);
test_integer_literal(infix_expr->left, 5);
CHECK(infix_expr->op == "-");
ast::infix_expr* second_infix_expr =
cast<ast::infix_expr>(infix_expr->right);
CHECK(second_infix_expr->op == "*");
ast::prefix_expr* prefix_expr =
cast<ast::prefix_expr>(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<ast::expression_stmt>(program->statements[0]);
ast::infix_expr* infix_expr =
cast<ast::infix_expr>(expression_stmt->expression);
ast::infix_expr* second_infix_expr =
cast<ast::infix_expr>(infix_expr->left);
CHECK(second_infix_expr->op == "*");
test_integer_literal(second_infix_expr->left, 5);
ast::prefix_expr* prefix_expr =
cast<ast::prefix_expr>(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);
}
}
} }