authorgravatar for 11367844+lino-levan@users.noreply.github.comLino Le Van <11367844+lino-levan@users.noreply.github.com> 2024-02-09 01:49:35+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-02-08 16:49:35-08:00
log2db5c4d0c4357bc015bc578680b479439f436b23
tree09a23d2d22fa1ff9a082a588395c41a48d2429e2
parentd0e4a653989fb012e7b7c01eebb76c655c3393a1

fix: associativity in the parser (#24)

* fix: associativity in the parser * chore: address dave comments part 1

3 files changed, 19 insertions(+), 41 deletions(-)

crates/ast/operators.rs+1
...@@ -244,6 +244,7 @@ pub enum OperatorLevel {...@@ -244,6 +244,7 @@ pub enum OperatorLevel {
244 Comma, // ,244 Comma, // ,
245}245}
246246
247#[derive(PartialEq)]
247pub enum Associativity {248pub enum Associativity {
248 LeftToRight,249 LeftToRight,
249 RightToLeft,250 RightToLeft,
crates/parser/parse_expr.rs+12-41
...@@ -1,5 +1,4 @@...@@ -1,5 +1,4 @@
1use ast::Associativity::*;1use ast::{Associativity, BinaryOperator, Expr, ExprData, OperatorLevel};
2use ast::{BinaryOperator, Expr, ExprData, OperatorLevel};
3use log::Range;2use log::Range;
4use miette::Result;3use miette::Result;
54
...@@ -19,25 +18,8 @@ pub fn parse_expr(p: &mut Parser) -> Result<Expr> {...@@ -19,25 +18,8 @@ pub fn parse_expr(p: &mut Parser) -> Result<Expr> {
19 if let Some(token) = p.peek() {18 if let Some(token) = p.peek() {
20 if let Some(level) = BinaryOperator::from_token(&token).map(|o| o.level()) {19 if let Some(level) = BinaryOperator::from_token(&token).map(|o| o.level()) {
21 _ = p.next();20 _ = p.next();
22 match level.associativity() {21 expr =
23 RightToLeft => {22 parse_expr_binary(p, BinaryOperator::from_token(&token).unwrap(), expr, level)?;
24 expr = parse_expr_binary(
25 p,
26 BinaryOperator::from_token(&token).unwrap(),
27 expr,
28 level,
29 )?;
30 }
31 LeftToRight => {
32 // TODO(@paperdave): TODO
33 expr = parse_expr_binary(
34 p,
35 BinaryOperator::from_token(&token).unwrap(),
36 expr,
37 level,
38 )?;
39 }
40 }
41 continue;23 continue;
42 }24 }
43 }25 }
...@@ -60,27 +42,16 @@ fn parse_expr_binary(...@@ -60,27 +42,16 @@ fn parse_expr_binary(
60 loop {42 loop {
61 if let Some(token) = p.peek() {43 if let Some(token) = p.peek() {
62 if let Some(new_level) = BinaryOperator::from_token(&token).map(|o| o.level()) {44 if let Some(new_level) = BinaryOperator::from_token(&token).map(|o| o.level()) {
63 if new_level <= level {45 if (level.associativity() == Associativity::LeftToRight && new_level < level)
46 || (level.associativity() == Associativity::RightToLeft && new_level <= level)
47 {
64 _ = p.next();48 _ = p.next();
65 match new_level.associativity() {49 right = parse_expr_binary(
66 RightToLeft => {50 p,
67 right = parse_expr_binary(51 BinaryOperator::from_token(&token).unwrap(),
68 p,52 right,
69 BinaryOperator::from_token(&token).unwrap(),53 new_level,
70 right,54 )?;
71 new_level,
72 )?;
73 }
74 LeftToRight => {
75 // TODO(@paperdave): TODO
76 right = parse_expr_binary(
77 p,
78 BinaryOperator::from_token(&token).unwrap(),
79 right,
80 new_level,
81 )?;
82 }
83 }
84 continue;55 continue;
85 }56 }
86 }57 }
examples/basics/associativity.blight created+6
...@@ -0,0 +1,6 @@
1let print = @raw("console.log");
2print(1 * 2 * 3);
3print(1 * 2 / 3);
4print(1 + 2 ** 3);
5print(1 ** 2 ** 3);
6print(1 * 2 + 3);