From 2db5c4d0c4357bc015bc578680b479439f436b23 Mon Sep 17 00:00:00 2001 From: Lino Le Van <11367844+lino-levan@users.noreply.github.com> Date: Fri, 9 Feb 2024 01:49:35 +0100 Subject: [PATCH] fix: associativity in the parser (#24) * fix: associativity in the parser * chore: address dave comments part 1 --- crates/ast/operators.rs | 1 + crates/parser/parse_expr.rs | 53 +++++++--------------------- examples/basics/associativity.blight | 6 ++++ 3 files changed, 19 insertions(+), 41 deletions(-) create mode 100644 examples/basics/associativity.blight diff --git a/crates/ast/operators.rs b/crates/ast/operators.rs index 9f6efc404a82baca560d40d7531ee4a499cc93b7..27cf0b1a837d2f1f40b45af57026cc4700ed50e2 100644 --- a/crates/ast/operators.rs +++ b/crates/ast/operators.rs @@ -244,6 +244,7 @@ pub enum OperatorLevel { Comma, // , } +#[derive(PartialEq)] pub enum Associativity { LeftToRight, RightToLeft, diff --git a/crates/parser/parse_expr.rs b/crates/parser/parse_expr.rs index f1429fb898767e14792874af6559dbb9e6c0f1f6..f0a1ed29ef2aa43e331f7e227ab984fd39a3701b 100644 --- a/crates/parser/parse_expr.rs +++ b/crates/parser/parse_expr.rs @@ -1,5 +1,4 @@ -use ast::Associativity::*; -use ast::{BinaryOperator, Expr, ExprData, OperatorLevel}; +use ast::{Associativity, BinaryOperator, Expr, ExprData, OperatorLevel}; use log::Range; use miette::Result; @@ -19,25 +18,8 @@ pub fn parse_expr(p: &mut Parser) -> Result { if let Some(token) = p.peek() { if let Some(level) = BinaryOperator::from_token(&token).map(|o| o.level()) { _ = p.next(); - match level.associativity() { - RightToLeft => { - expr = parse_expr_binary( - p, - BinaryOperator::from_token(&token).unwrap(), - expr, - level, - )?; - } - LeftToRight => { - // TODO(@paperdave): TODO - expr = parse_expr_binary( - p, - BinaryOperator::from_token(&token).unwrap(), - expr, - level, - )?; - } - } + expr = + parse_expr_binary(p, BinaryOperator::from_token(&token).unwrap(), expr, level)?; continue; } } @@ -60,27 +42,16 @@ fn parse_expr_binary( loop { if let Some(token) = p.peek() { if let Some(new_level) = BinaryOperator::from_token(&token).map(|o| o.level()) { - if new_level <= level { + if (level.associativity() == Associativity::LeftToRight && new_level < level) + || (level.associativity() == Associativity::RightToLeft && new_level <= level) + { _ = p.next(); - match new_level.associativity() { - RightToLeft => { - right = parse_expr_binary( - p, - BinaryOperator::from_token(&token).unwrap(), - right, - new_level, - )?; - } - LeftToRight => { - // TODO(@paperdave): TODO - right = parse_expr_binary( - p, - BinaryOperator::from_token(&token).unwrap(), - right, - new_level, - )?; - } - } + right = parse_expr_binary( + p, + BinaryOperator::from_token(&token).unwrap(), + right, + new_level, + )?; continue; } } diff --git a/examples/basics/associativity.blight b/examples/basics/associativity.blight new file mode 100644 index 0000000000000000000000000000000000000000..5bc76df04a89298c5be31f3f45f6b38c383ac986 --- /dev/null +++ b/examples/basics/associativity.blight @@ -0,0 +1,6 @@ +let print = @raw("console.log"); +print(1 * 2 * 3); +print(1 * 2 / 3); +print(1 + 2 ** 3); +print(1 ** 2 ** 3); +print(1 * 2 + 3); -- 2.54.0