From 29318a294cc4105e0d96302a950938f096356aec Mon Sep 17 00:00:00 2001 From: Nora Abi Akar <nora.abiakar@gmail.com> Date: Wed, 13 Oct 2021 10:38:02 +0200 Subject: [PATCH] Swap && and || operator precedence in modcc (#1710) --- modcc/lexer.cpp | 6 +++--- modcc/parser.cpp | 2 +- test/unit-modcc/test_parser.cpp | 23 +++++++++++++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/modcc/lexer.cpp b/modcc/lexer.cpp index 4ada753b..f89c3d32 100644 --- a/modcc/lexer.cpp +++ b/modcc/lexer.cpp @@ -435,10 +435,10 @@ void Lexer::binop_prec_init() { return; // I have taken the operator precedence from C++ - // Note that only infix operators require precidence. + // Note that only infix operators require precedence. binop_prec_[tok::eq] = 1; - binop_prec_[tok::land] = 2; - binop_prec_[tok::lor] = 3; + binop_prec_[tok::lor] = 2; + binop_prec_[tok::land] = 3; binop_prec_[tok::equality] = 4; binop_prec_[tok::ne] = 4; binop_prec_[tok::lt] = 5; diff --git a/modcc/parser.cpp b/modcc/parser.cpp index e54c9830..4b80992c 100644 --- a/modcc/parser.cpp +++ b/modcc/parser.cpp @@ -1333,7 +1333,7 @@ expression_ptr Parser::parse_expression(int prec, tok stop_token) { auto p_op = binop_precedence(op.type); // Note: all tokens that are not infix binary operators have - // precidence of -1, so expressions like function calls will short + // precedence of -1, so expressions like function calls will short // circuit this loop here. if (p_op <= prec) return lhs; diff --git a/test/unit-modcc/test_parser.cpp b/test/unit-modcc/test_parser.cpp index ba8cc363..5916704c 100644 --- a/test/unit-modcc/test_parser.cpp +++ b/test/unit-modcc/test_parser.cpp @@ -602,6 +602,13 @@ double eval(Expression* e) { case tok::minus: return lhs - rhs; case tok::times: return lhs * rhs; case tok::divide: return lhs / rhs; + case tok::lt: return lhs < rhs; + case tok::lte: return lhs <= rhs; + case tok::gt: return lhs > rhs; + case tok::gte: return lhs >= rhs; + case tok::lnot: return lhs != rhs; + case tok::land: return lhs && rhs; + case tok::lor: return lhs || rhs; case tok::pow: return std::pow(lhs, rhs); case tok::min: return std::min(lhs, rhs); case tok::max: return std::max(lhs, rhs); @@ -665,6 +672,22 @@ TEST(Parser, parse_binop) { EXPECT_TRUE(check_parse(e, &Parser::parse_expression, test_case.first)); EXPECT_NEAR(eval(e.get()), test_case.second, 1e-10); } + + std::pair<const char*, bool> bool_tests[] = { + {"0 && 0 || 1", true}, + {"(0 && 0) || 1", true}, + {"0 && (0 || 1)", false}, + {"3<2 && 1 || 4>1", true}, + {"(3<2 && 1) || 4>1", true}, + {"3<2 && (1 || 4>1)", false}, + {"(3<2) && (1 || (4>1))", false}, + }; + + for (const auto& test_case: bool_tests) { + std::unique_ptr<Expression> e; + EXPECT_TRUE(check_parse(e, &Parser::parse_expression, test_case.first)); + EXPECT_EQ(eval(e.get()), test_case.second); + } } TEST(Parser, parse_state_block) { -- GitLab