Diffstat (limited to 'src/parser.rs')
| -rw-r--r-- | src/parser.rs | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/src/parser.rs b/src/parser.rs index 8cee0ef..e90f11e 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,15 +1,17 @@ -mod types; +pub mod types; use crate::lexer::{Lexer, Token}; use chumsky::{ input::{SpannedInput, Stream}, prelude::*, Parser, }; -mod fun; -mod util; +pub mod fun; +pub mod util; use types::*; use util::*; +use self::fun::Function; + impl<'s> Value<'s> { pub fn parse() -> parser![Self] { select! { @@ -35,11 +37,11 @@ impl<'s> Expr<'s> { choice((t![ident].map(Expr::Ident), val)).boxed() }); - let λ = Lambda::parse().map(Expr::Lambda); + let λ = Λ::parse(expr.clone()); let decl = t![ident] .then_ignore(t![<-]) - .then(inline_expr.clone().or(λ.clone())) + .then(inline_expr.clone().or(λ.clone().map(Expr::Lambda))) .map(|(name, body)| Expr::Let { name, rhs: Box::new(body), @@ -50,7 +52,7 @@ impl<'s> Expr<'s> { let r#if = t![if] .ignore_then( expr.clone() - .then(t![else].or_not().ignore_then(expr.or_not())) + .then(t![else].or_not().ignore_then(expr.clone().or_not())) .delimited_by(t!['('], t![')']), ) .map(|(a, b)| Expr::If { @@ -59,14 +61,22 @@ impl<'s> Expr<'s> { }) .labelled("🐋") .boxed(); - choice((decl, r#if, inline_expr, λ)) + choice(( + decl, + r#if, + inline_expr, + λ.clone().map(Expr::Lambda), + Function::parse(λ).map(Expr::Function), + )) + .labelled("expr") }) } } #[test] fn parse_expr() { - dbg!(Expr::parse().parse(code("a ← λ ( +- 🍴 )")).unwrap()); + parse_s("a ← λ ( +- 🍴 )", Expr::parse()); + // dbg!(Expr::parse().parse(code("a ← λ ( +- 🍴 )")).unwrap()); } pub fn stream(lexer: Lexer<'_>, len: usize) -> SpannedInput<Token<'_>, Span, Stream<Lexer<'_>>> { @@ -78,6 +88,14 @@ pub fn code<'s>(x: &'s str) -> SpannedInput<Token<'s>, Span, Stream<Lexer<'s>>> stream(crate::lexer::lex(x), x.len()) } +#[cfg(test)] +pub fn parse_s<'s, T: std::fmt::Debug>(x: &'s str, p: parser![T]) -> T { + match crate::ui::display(p.parse(code(x)).into_result(), x) { + Ok(x) => dbg!(x), + Err(()) => panic!(), + } +} + pub fn parse(tokens: Lexer<'_>, len: usize) -> Result<Ast<'_>, Vec<Error<'_>>> { parser().parse(stream(tokens, len)).into_result() } |