Diffstat (limited to 'src/parser/fun.rs')
| -rw-r--r-- | src/parser/fun.rs | 54 |
1 files changed, 29 insertions, 25 deletions
diff --git a/src/parser/fun.rs b/src/parser/fun.rs index 9dfd561..3a4c01c 100644 --- a/src/parser/fun.rs +++ b/src/parser/fun.rs @@ -6,12 +6,12 @@ use chumsky::{prelude::*, Parser}; #[derive(Debug, Clone)] pub enum Function<'s> { Dup, - Both(Lambda<'s>, Lambda<'s>), - Fork(Lambda<'s>, Lambda<'s>), - Gap(Lambda<'s>), - Hold(Lambda<'s>), + Both(Λ<'s>, Λ<'s>), + Fork(Λ<'s>, Λ<'s>), + Gap(Λ<'s>), + Hold(Λ<'s>), Flip, - Duck(Lambda<'s>), + Duck(Λ<'s>), Reverse, Zap, Add, @@ -36,28 +36,28 @@ pub enum Function<'s> { Split, First, Last, - Each(Lambda<'s>), - Reduce(Lambda<'s>), - ReduceStack(Lambda<'s>), + Each(Λ<'s>), + Reduce(Λ<'s>), + ReduceStack(Λ<'s>), Range, Call, } -impl<'s> Lambda<'s> { - pub fn parse() -> parser![Self] { - t![λ] - .ignore_then( - Expr::parse() - .repeated() - .collect() - .delimited_by(t!['('], t![')']), - ) - .map(|x| Self(x)) +impl<'s> Λ<'s> { + pub fn parse(exp: parser![Expr<'s>]) -> parser![Self] { + let mut λ = Recursive::declare(); + λ.define(choice(( + t![λ] + .ignore_then(exp.repeated().collect().delimited_by(t!['('], t![')'])) + .map(|x| Self(x)), + Function::parse(λ.clone()).map(|x| Λ(vec![Expr::Function(x)])), + ))); + λ.labelled("λ") } } impl<'s> Function<'s> { - pub fn parse() -> parser![Self] { + pub fn parse(λ: parser![Λ<'s>]) -> parser![Self] { use Function::*; let basic = select! { Token::Dup => Dup, @@ -88,12 +88,16 @@ impl<'s> Function<'s> { Token::Last => Last, }; macro_rules! two { - ($name:ident) => { - Lambda::parse() - .then(Lambda::parse()) - .then_ignore(just(Token::$name)) - .map(|(a, b)| $name(a, b)) - }; + ($name:ident) => {{ + let mut p = Recursive::declare(); + p.define( + λ.clone() + .then(λ.clone()) + .then_ignore(just(Token::$name)) + .map(|(a, b)| $name(a, b)), + ); + p + }}; } choice((basic, two![Both], two![Fork])) } |