Fix && and || associativity.
Somehow, these have always been right-associative, when the natural thing to expect is left-associativity. It now matters when trying to crawl down binary tree to display them properly.
This commit is contained in:
parent
c9ab1aec98
commit
8ffa68d2f0
|
@ -10,15 +10,14 @@ pub mod pattern;
|
||||||
pub mod token;
|
pub mod token;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
pub use annotation::parser as annotation;
|
|
||||||
pub use definition::parser as definition;
|
|
||||||
pub use expr::parser as expression;
|
|
||||||
pub use pattern::parser as pattern;
|
|
||||||
|
|
||||||
use crate::{ast, line_numbers::LineNumbers};
|
use crate::{ast, line_numbers::LineNumbers};
|
||||||
|
pub use annotation::parser as annotation;
|
||||||
use chumsky::prelude::*;
|
use chumsky::prelude::*;
|
||||||
|
pub use definition::parser as definition;
|
||||||
use error::ParseError;
|
use error::ParseError;
|
||||||
|
pub use expr::parser as expression;
|
||||||
use extra::ModuleExtra;
|
use extra::ModuleExtra;
|
||||||
|
pub use pattern::parser as pattern;
|
||||||
|
|
||||||
pub fn module(
|
pub fn module(
|
||||||
src: &str,
|
src: &str,
|
||||||
|
|
|
@ -20,6 +20,8 @@ mod tuple;
|
||||||
mod var;
|
mod var;
|
||||||
pub mod when;
|
pub mod when;
|
||||||
|
|
||||||
|
use super::{error::ParseError, token::Token};
|
||||||
|
use crate::{ast, expr::UntypedExpr};
|
||||||
pub use and_or_chain::parser as and_or_chain;
|
pub use and_or_chain::parser as and_or_chain;
|
||||||
pub use anonymous_function::parser as anonymous_function;
|
pub use anonymous_function::parser as anonymous_function;
|
||||||
pub use block::parser as block;
|
pub use block::parser as block;
|
||||||
|
@ -37,9 +39,6 @@ pub use tuple::parser as tuple;
|
||||||
pub use var::parser as var;
|
pub use var::parser as var;
|
||||||
pub use when::parser as when;
|
pub use when::parser as when;
|
||||||
|
|
||||||
use super::{error::ParseError, token::Token};
|
|
||||||
use crate::{ast, expr::UntypedExpr};
|
|
||||||
|
|
||||||
pub fn parser(
|
pub fn parser(
|
||||||
sequence: Recursive<'_, Token, UntypedExpr, ParseError>,
|
sequence: Recursive<'_, Token, UntypedExpr, ParseError>,
|
||||||
) -> impl Parser<Token, UntypedExpr, Error = ParseError> + '_ {
|
) -> impl Parser<Token, UntypedExpr, Error = ParseError> + '_ {
|
||||||
|
@ -142,28 +141,62 @@ pub fn pure_expression<'a>(
|
||||||
.boxed();
|
.boxed();
|
||||||
|
|
||||||
// Conjunction
|
// Conjunction
|
||||||
|
//
|
||||||
|
// NOTE: This can be written in a nicer way with `foldl_with` in chumsky =^ 1.0.0.
|
||||||
|
// DO NOT however try to write this as:
|
||||||
|
//
|
||||||
|
// comparison
|
||||||
|
// .clone()
|
||||||
|
// .then(op)
|
||||||
|
// .repeated
|
||||||
|
// .then(comparison)
|
||||||
|
// .foldr(...)
|
||||||
|
//
|
||||||
|
// This has somehow incredibly slow performances in Chumsky. Hence the approach below.
|
||||||
let op = just(Token::AmperAmper).to(ast::BinOp::And);
|
let op = just(Token::AmperAmper).to(ast::BinOp::And);
|
||||||
let conjunction = comparison
|
let conjunction = comparison
|
||||||
|
.clone()
|
||||||
|
.map(|e| vec![e])
|
||||||
.clone()
|
.clone()
|
||||||
.then(op.then(comparison).repeated())
|
.then(op.then(comparison).repeated())
|
||||||
.foldl(|a, (op, b)| UntypedExpr::BinOp {
|
.foldl(|a, (_op, b)| {
|
||||||
location: a.location().union(b.location()),
|
let mut tail = vec![b];
|
||||||
name: op,
|
tail.extend(a);
|
||||||
left: Box::new(a),
|
tail
|
||||||
right: Box::new(b),
|
})
|
||||||
|
.map(|xs| {
|
||||||
|
xs.into_iter()
|
||||||
|
.reduce(|right, left| UntypedExpr::BinOp {
|
||||||
|
location: left.location().union(right.location()),
|
||||||
|
name: ast::BinOp::And,
|
||||||
|
left: Box::new(left),
|
||||||
|
right: Box::new(right),
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
})
|
})
|
||||||
.boxed();
|
.boxed();
|
||||||
|
|
||||||
|
// NOTE: see comment about conjunctions just above.
|
||||||
// Disjunction
|
// Disjunction
|
||||||
let op = just(Token::VbarVbar).to(ast::BinOp::Or);
|
let op = just(Token::VbarVbar).to(ast::BinOp::Or);
|
||||||
let disjunction = conjunction
|
let disjunction = conjunction
|
||||||
.clone()
|
.clone()
|
||||||
|
.map(|e| vec![e])
|
||||||
.then(op.then(conjunction).repeated())
|
.then(op.then(conjunction).repeated())
|
||||||
.foldl(|a, (op, b)| UntypedExpr::BinOp {
|
.foldl(|a, (_op, b)| {
|
||||||
location: a.location().union(b.location()),
|
let mut tail = vec![b];
|
||||||
name: op,
|
tail.extend(a);
|
||||||
left: Box::new(a),
|
tail
|
||||||
right: Box::new(b),
|
})
|
||||||
|
.map(|xs| {
|
||||||
|
xs.into_iter()
|
||||||
|
.reduce(|right, left| UntypedExpr::BinOp {
|
||||||
|
location: left.location().union(right.location()),
|
||||||
|
name: ast::BinOp::Or,
|
||||||
|
left: Box::new(left),
|
||||||
|
right: Box::new(right),
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
})
|
})
|
||||||
.boxed();
|
.boxed();
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,5 @@ fn bar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn baz() {
|
fn baz() {
|
||||||
a || b && c || d
|
a || ( b && c || d )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue