diff --git a/crates/lang/src/expr.rs b/crates/lang/src/expr.rs index a6a067f6..2cd2247b 100644 --- a/crates/lang/src/expr.rs +++ b/crates/lang/src/expr.rs @@ -268,3 +268,57 @@ pub enum UntypedExpr { value: Box, }, } + +impl UntypedExpr { + pub fn append_in_sequence(self, next: Self) -> Self { + let location = Span { + start: self.location().start, + end: next.location().end, + ..self.location() + }; + + match self { + Self::Sequence { + mut expressions, .. + } => { + expressions.push(next); + Self::Sequence { + location, + expressions, + } + } + _ => Self::Sequence { + location, + expressions: vec![self, next], + }, + } + } + + pub fn location(&self) -> Span { + match self { + Self::Try { then, .. } => then.location(), + Self::PipeLine { expressions, .. } => expressions.last().location(), + Self::Fn { location, .. } + | Self::Var { location, .. } + | Self::Int { location, .. } + | Self::Todo { location, .. } + | Self::Case { location, .. } + | Self::Call { location, .. } + | Self::List { location, .. } + | Self::Float { location, .. } + | Self::BinOp { location, .. } + | Self::Tuple { location, .. } + | Self::String { location, .. } + | Self::Assignment { location, .. } + | Self::TupleIndex { location, .. } + | Self::FieldAccess { location, .. } + | Self::RecordUpdate { location, .. } + | Self::Negate { location, .. } => *location, + Self::Sequence { + location, + expressions, + .. + } => expressions.last().map(Self::location).unwrap_or(*location), + } + } +} diff --git a/crates/lang/src/parser.rs b/crates/lang/src/parser.rs index 0c976740..448ec3b2 100644 --- a/crates/lang/src/parser.rs +++ b/crates/lang/src/parser.rs @@ -227,26 +227,37 @@ pub fn fn_param_parser() -> impl Parser impl Parser { recursive(|r| { - choice((just(Token::Try) - .ignore_then(pattern_parser()) - .then(just(Token::Colon).ignore_then(type_parser()).or_not()) - .then_ignore(just(Token::Equal)) - .then(expr_parser()) - .then(r) - .map_with_span(|(((pattern, annotation), value), then_), span| { - expr::UntypedExpr::Try { - location: span, - value: Box::new(value), - pattern, - then: Box::new(then_), - annotation, - } - }),)) + choice(( + just(Token::Try) + .ignore_then(pattern_parser()) + .then(just(Token::Colon).ignore_then(type_parser()).or_not()) + .then_ignore(just(Token::Equal)) + .then(expr_parser()) + .then(r.clone()) + .map_with_span(|(((pattern, annotation), value), then_), span| { + expr::UntypedExpr::Try { + location: span, + value: Box::new(value), + pattern, + then: Box::new(then_), + annotation, + } + }), + expr_parser() + .then(r.repeated()) + .map_with_span(|(expr, exprs), span| { + exprs + .into_iter() + .fold(expr, |acc, elem| acc.append_in_sequence(elem)) + }), + )) }) } pub fn expr_parser() -> impl Parser {} +pub fn expr_unit_parser() -> impl Parser {} + pub fn type_parser() -> impl Parser { recursive(|r| { choice((