aiken_lang/parser/expr/
chained.rs1use 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}