diff --git a/src/parser.rs b/src/parser.rs index e42452b..72d26c6 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -20,6 +20,7 @@ mod expr; mod func_defs; mod lit; mod prefix; +mod program; mod suffix; mod table_constr; mod table_destr; @@ -27,11 +28,11 @@ mod var; use chumsky::prelude::*; -use crate::ast::Expr; +use crate::ast::Program; use self::basic::Error; -pub fn parser() -> impl Parser { +pub fn parser() -> impl Parser { let space = basic::space(); let ident = basic::ident(); let local = basic::local(space.clone()); @@ -66,11 +67,15 @@ pub fn parser() -> impl Parser { func_def, expr.clone(), ); - let suffixed = suffix::suffixed(space.clone(), ident, table_constr, atom, expr); + let suffixed = suffix::suffixed(space.clone(), ident.clone(), table_constr, atom, expr); let prefixed = prefix::prefixed(space.clone(), suffixed); - expr::expr(space, prefixed) - }); + expr::expr(space.clone(), prefixed) + }) + .boxed(); - expr.padded().then_ignore(end()) + let table_lit_elem = lit::table_lit_elem(space.clone(), ident, expr.clone()); + let program = program::program(space, table_lit_elem, expr); + + program.then_ignore(end()) } diff --git a/src/parser/program.rs b/src/parser/program.rs new file mode 100644 index 0000000..26e12fd --- /dev/null +++ b/src/parser/program.rs @@ -0,0 +1,38 @@ +//! Corresponds to `ast::program`. + +use chumsky::prelude::*; + +use crate::ast::{Expr, Program, Space, TableLitElem}; + +use super::basic::EParser; + +pub fn program( + space: EParser, + table_lit_elem: EParser, + expr: EParser, +) -> EParser { + let lit = space + .clone() + .then(expr) + .then(space.clone()) + .map_with_span(|((s0, expr), s1), span| Program::Expr { s0, expr, s1, span }); + + let elem = space + .clone() + .then(table_lit_elem) + .then(space.clone()) + .map(|((s0, elem), s1)| (s0, elem, s1)); + let trailing_comma = just(',').ignore_then(space.clone()).or_not(); + let module = space + .then_ignore(text::keyword("module")) + .then(elem.separated_by(just(','))) + .then(trailing_comma) + .map_with_span(|((s0, elems), trailing_comma), span| Program::Module { + s0, + elems, + trailing_comma, + span, + }); + + module.or(lit).boxed() +}