()
| 37 | } |
| 38 | |
| 39 | fn module_contents<'a, I>() -> impl Parser<'a, I, Vec<Stmt>, ParserError<'a>> + Clone |
| 40 | where |
| 41 | I: Input<'a, Token = lr::Token, Span = Span> + BorrowInput<'a> + chumsky::input::ValueInput<'a>, |
| 42 | { |
| 43 | recursive(|module_contents| { |
| 44 | let module_def = keyword("module") |
| 45 | .ignore_then(ident_part()) |
| 46 | .then( |
| 47 | module_contents |
| 48 | .then_ignore(new_line().repeated().collect::<Vec<_>>()) |
| 49 | .delimited_by(ctrl('{'), ctrl('}')), |
| 50 | ) |
| 51 | .map(|(name, stmts)| StmtKind::ModuleDef(ModuleDef { name, stmts })) |
| 52 | .labelled("module definition"); |
| 53 | |
| 54 | let annotation = new_line() |
| 55 | .repeated() |
| 56 | .at_least(1) |
| 57 | .collect::<Vec<_>>() |
| 58 | .ignore_then( |
| 59 | select_ref! { lr::Token { kind: TokenKind::Annotate, .. } => () } |
| 60 | .ignore_then(expr()) |
| 61 | .map(|expr| Annotation { |
| 62 | expr: Box::new(expr), |
| 63 | }), |
| 64 | ) |
| 65 | .labelled("annotation"); |
| 66 | |
| 67 | // TODO: we want to confirm that we're not allowing things on the same |
| 68 | // line that should't be; e.g. `let foo = 5 let bar = 6`. We can't |
| 69 | // enforce a new line here because then `module two {let houses = |
| 70 | // both.alike}` fails (though we could force a new line after the |
| 71 | // `module` if we wanted to?) |
| 72 | // |
| 73 | // let stmt_kind = new_line().repeated().at_least(1).ignore_then(choice(( |
| 74 | let stmt_kind = new_line() |
| 75 | .repeated() |
| 76 | .collect::<Vec<_>>() |
| 77 | .ignore_then(choice((module_def, type_def(), import_def(), var_def()))); |
| 78 | |
| 79 | // Currently doc comments need to be before the annotation; probably |
| 80 | // should relax this? |
| 81 | with_doc_comment( |
| 82 | annotation |
| 83 | .repeated() |
| 84 | .collect::<Vec<_>>() |
| 85 | .then(stmt_kind) |
| 86 | .map_with(|(annotations, kind), extra| { |
| 87 | into_stmt((annotations, kind), extra.span()) |
| 88 | }), |
| 89 | ) |
| 90 | .repeated() |
| 91 | .collect() |
| 92 | }) |
| 93 | .boxed() |
| 94 | } |
| 95 | |
| 96 | fn query_def<'a, I>() -> impl Parser<'a, I, Stmt, ParserError<'a>> + Clone |
no test coverage detected