From 9c4b84ce33ea6ac7fe0f1b00ee5c67718643a34a Mon Sep 17 00:00:00 2001 From: Jakub Doka Date: Sun, 22 Dec 2024 20:43:49 +0100 Subject: [PATCH] fixing the precedence regarding slice ranges Signed-off-by: Jakub Doka --- lang/src/parser.rs | 69 +++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/lang/src/parser.rs b/lang/src/parser.rs index 5bf4e181..50359391 100644 --- a/lang/src/parser.rs +++ b/lang/src/parser.rs @@ -490,15 +490,6 @@ impl<'a, 'b> Parser<'a, 'b> { }, body: self.ptr_expr()?, }, - T::Range => E::Range { - pos: token.start, - start: None, - end: if matches!(self.token.kind, TokenKind::RBrack) { - None - } else { - Some(self.ptr_expr()?) - }, - }, T::Ctor => self.ctor(pos, None), T::Tupl => self.tupl(pos, None, ListKind::Tuple), T::Arr => self.tupl(pos, None, ListKind::Array), @@ -570,14 +561,7 @@ impl<'a, 'b> Parser<'a, 'b> { let token = self.token; if matches!( token.kind, - T::LParen - | T::Ctor - | T::Dot - | T::Tupl - | T::Arr - | T::LBrack - | T::Colon - | T::Range + T::LParen | T::Ctor | T::Dot | T::Tupl | T::Arr | T::LBrack | T::Colon ) { self.next(); } @@ -593,20 +577,43 @@ impl<'a, 'b> Parser<'a, 'b> { T::Arr => self.tupl(token.start, Some(expr), ListKind::Array), T::LBrack => E::Index { base: self.arena.alloc(expr), - index: { - let index = self.expr()?; - self.expect_advance(T::RBrack)?; - self.arena.alloc(index) - }, - }, - T::Range => E::Range { - pos: token.start, - start: Some(self.arena.alloc(expr)), - end: if matches!(self.token.kind, TokenKind::RBrack) { - None - } else { - Some(self.ptr_expr()?) - }, + index: self.arena.alloc({ + if self.advance_if(T::Range) { + let pos = self.token.start; + if self.advance_if(T::RBrack) { + Expr::Range { pos, start: None, end: None } + } else { + let res = Expr::Range { + pos, + start: None, + end: Some(self.ptr_expr()?), + }; + self.expect_advance(T::RBrack)?; + res + } + } else { + let start = self.expr()?; + + let pos = self.token.start; + if self.advance_if(T::Range) { + let start = self.arena.alloc(start); + if self.advance_if(T::RBrack) { + Expr::Range { pos, start: Some(start), end: None } + } else { + let res = Expr::Range { + pos, + start: Some(start), + end: Some(self.ptr_expr()?), + }; + self.expect_advance(T::RBrack)?; + res + } + } else { + self.expect_advance(T::RBrack)?; + start + } + } + }), }, T::Colon => E::BinOp { left: {