From 5afeeae56256a863e9c6baafef91648c4dc4ae61 Mon Sep 17 00:00:00 2001 From: Hydrostic Date: Thu, 14 May 2026 19:55:08 +0800 Subject: [PATCH] fix(parser): Logic expression (and/or) priority --- src/frontend/parser.rs | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/frontend/parser.rs b/src/frontend/parser.rs index fda17d4..ec959db 100644 --- a/src/frontend/parser.rs +++ b/src/frontend/parser.rs @@ -877,12 +877,11 @@ impl Parser { } Ok(left) } - fn parse_logical(&mut self) -> Result { + fn parse_logical_and(&mut self) -> Result { assert!(self.peek().is_some()); let mut left = self.parse_relational()?; while let Some(t) = self.peek() { let op = match t.value { - TokenValue::Or => BinaryOp::Or, TokenValue::And => BinaryOp::And, _ => break, }; @@ -907,6 +906,35 @@ impl Parser { } Ok(left) } + fn parse_logical_or(&mut self) -> Result { + assert!(self.peek().is_some()); + let mut left = self.parse_logical_and()?; + while let Some(t) = self.peek() { + let op = match t.value { + TokenValue::Or => BinaryOp::Or, + _ => break, + }; + self.advance(1); + let right = match self.peek() { + Some(_) => self.parse_logical_and()?, + None => { + self.diagnostics + .add_from_frontend_error(ParseError::ExpectButEof("expression"), left.span); + return Err(ParseProcessError::ErrorInMatch); + } + }; + let span = Span::from_two(left.span, right.span); + left = Expr { + value: ExprValue::BinaryOp { + lhs: Box::new(left), + op, + rhs: Box::new(right), + }, + span, + }; + } + Ok(left) + } fn parse_assign(&mut self) -> Result { assert!(self.peek().is_some()); let is_assign = matches!( @@ -923,7 +951,7 @@ impl Parser { ) ); if !is_assign { - return self.parse_logical(); + return self.parse_logical_or(); } let lvalue_token = self.next().unwrap().clone();