aiken_lang/parser/expr/
chained.rs

1use super::{
2    and_or_chain, anonymous_binop::parser as anonymous_binop,
3    anonymous_function::parser as anonymous_function, assignment, block::parser as block,
4    bytearray::parser as bytearray, if_else::parser as if_else, int::parser as int,
5    list::parser as list, pair::parser as pair, record::parser as record,
6    record_update::parser as record_update, string::parser as string, tuple::parser as tuple,
7    var::parser as var, when::parser as when,
8};
9use crate::{
10    expr::UntypedExpr,
11    parser::{
12        chain::{Chain, call::parser as call, field_access, tuple_index::parser as tuple_index},
13        error::ParseError,
14        token::Token,
15    },
16};
17use chumsky::prelude::*;
18
19pub fn parser<'a>(
20    sequence: Recursive<'a, Token, UntypedExpr, ParseError>,
21    expression: Recursive<'a, Token, UntypedExpr, ParseError>,
22) -> impl Parser<Token, UntypedExpr, Error = ParseError> + 'a {
23    let chain = choice((
24        tuple_index(),
25        field_access::parser(),
26        call(expression.clone()),
27    ));
28
29    chain_start(sequence, expression)
30        .then(chain.repeated())
31        .foldl(|expr, chain| match chain {
32            Chain::Call(args, span) => expr.call(args, span),
33            Chain::FieldAccess(label, span) => expr.field_access(label, span),
34            Chain::TupleIndex(index, span) => expr.tuple_index(index, span),
35        })
36        .then(just(Token::Question).or_not())
37        .map_with_span(|(value, token), location| match token {
38            Some(_) => UntypedExpr::TraceIfFalse {
39                value: Box::new(value),
40                location,
41            },
42            None => value,
43        })
44}
45
46pub fn chain_start<'a>(
47    sequence: Recursive<'a, Token, UntypedExpr, ParseError>,
48    expression: Recursive<'a, Token, UntypedExpr, ParseError>,
49) -> impl Parser<Token, UntypedExpr, Error = ParseError> + 'a {
50    choice((
51        string(),
52        int(),
53        pair(expression.clone()),
54        record_update(expression.clone()),
55        record(expression.clone()),
56        and_or_chain(expression.clone()),
57        var(),
58        tuple(expression.clone()),
59        bytearray(),
60        list(expression.clone()),
61        anonymous_function(sequence.clone()),
62        anonymous_binop(),
63        block(sequence.clone()),
64        when(expression.clone()),
65        assignment::let_(expression.clone()),
66        assignment::expect(expression.clone()),
67        if_else(sequence, expression.clone()),
68    ))
69}