From f024334da5105198ab7cd82cac7540ce6f26f082 Mon Sep 17 00:00:00 2001 From: erick-alcachofa Date: Sun, 28 Dec 2025 00:44:02 -0600 Subject: [PATCH] fix(parser): resolve expression ambiguity in switch/match cases Signed-off-by: erick-alcachofa Implement precedence capping in `parseExpression` for switch cases to prevent the parser from misinterpreting the case arrow (`->`) as a pointer member access operator. Additionally, increased the binding power of `ModuleAccess` (::) to ensure namespaced identifiers are correctly resolved within case patterns before hitting the precedence limit. - Use `PointerMemberAccess.right` as the precedence floor for cases. - Update `ModuleAccess` binding power to {23, 24}. --- lib/src/Parser/Pratt.cpp | 2 +- lib/src/Parser/Statements.cpp | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/src/Parser/Pratt.cpp b/lib/src/Parser/Pratt.cpp index 2c43b02..b71bcf7 100644 --- a/lib/src/Parser/Pratt.cpp +++ b/lib/src/Parser/Pratt.cpp @@ -40,7 +40,7 @@ namespace arti::lang::pratt { BindingPower infixBindingPower(ast::InfixOperator op) { switch (op) { // Member Access (Highest) - case ast::InfixOperator::ModuleAccess: + case ast::InfixOperator::ModuleAccess: return { 23, 24 }; case ast::InfixOperator::MemberAccess: case ast::InfixOperator::PointerMemberAccess: return { 21, 22 }; diff --git a/lib/src/Parser/Statements.cpp b/lib/src/Parser/Statements.cpp index eab6553..b1405e2 100644 --- a/lib/src/Parser/Statements.cpp +++ b/lib/src/Parser/Statements.cpp @@ -21,6 +21,7 @@ //============================================================================// #include +#include #include @@ -884,6 +885,9 @@ namespace arti::lang { return Unexpected<>{ std::move(lSquirly).error() }; } + uint16_t limit = + pratt::infixBindingPower(ast::InfixOperator::PointerMemberAccess).right; + bool keepParsing = true; while (keepParsing) { @@ -912,7 +916,7 @@ namespace arti::lang { else { auto curCase = ast::MakeNode(); - if (auto expr = parseExpression(); ! expr) { + if (auto expr = parseExpression(limit); ! expr) { return Unexpected<>{ std::move(expr).error() }; } else {