()
| 32 | } |
| 33 | |
| 34 | pub(crate) fn expr<'a, I>() -> impl Parser<'a, I, Expr, ParserError<'a>> + Clone |
| 35 | where |
| 36 | I: Input<'a, Token = lr::Token, Span = Span> + BorrowInput<'a>, |
| 37 | { |
| 38 | recursive(|expr| { |
| 39 | let literal = select_ref! { lr::Token { kind: TokenKind::Literal(lit), .. } => ExprKind::Literal(lit.clone()) }; |
| 40 | |
| 41 | let ident_kind = ident().map(ExprKind::Ident); |
| 42 | |
| 43 | let internal = keyword("internal") |
| 44 | .ignore_then(ident()) |
| 45 | .map(|x| x.to_string()) |
| 46 | .map(ExprKind::Internal); |
| 47 | |
| 48 | let nested_expr = with_doc_comment( |
| 49 | lambda_func(expr.clone()) |
| 50 | .or(func_call(expr.clone())) |
| 51 | .boxed(), |
| 52 | ); |
| 53 | |
| 54 | let tuple = tuple(nested_expr.clone()); |
| 55 | let array = array(nested_expr.clone()); |
| 56 | let pipeline_expr = { |
| 57 | use chumsky::recovery::{skip_then_retry_until, via_parser}; |
| 58 | |
| 59 | pipeline(nested_expr.clone()) |
| 60 | .padded_by(new_line().repeated()) |
| 61 | .delimited_by( |
| 62 | ctrl('('), |
| 63 | ctrl(')') |
| 64 | .recover_with(via_parser(end())) |
| 65 | .recover_with(skip_then_retry_until( |
| 66 | any_ref().ignored(), |
| 67 | ctrl(')').ignored().or(end()), |
| 68 | )), |
| 69 | ) |
| 70 | }; |
| 71 | let interpolation = interpolation(); |
| 72 | let case = case(expr.clone()); |
| 73 | |
| 74 | let param = select_ref! { lr::Token { kind: TokenKind::Param(id), .. } => ExprKind::Param(id.clone()) }; |
| 75 | |
| 76 | let term = with_doc_comment( |
| 77 | choice(( |
| 78 | literal, |
| 79 | internal, |
| 80 | tuple, |
| 81 | array, |
| 82 | interpolation, |
| 83 | ident_kind, |
| 84 | case, |
| 85 | param, |
| 86 | )) |
| 87 | .map_with(|kind, extra| ExprKind::into_expr(kind, extra.span())) |
| 88 | // No longer used given the TODO in `pipeline`; can remove if we |
| 89 | // don't resolve. |
| 90 | // .or(aliased(expr.clone())) |
| 91 | .or(pipeline_expr), |
no test coverage detected