Diffstat (limited to 'src/parser/fun.rs')
-rw-r--r--src/parser/fun.rs151
1 files changed, 113 insertions, 38 deletions
diff --git a/src/parser/fun.rs b/src/parser/fun.rs
index 3a4c01c..a763a81 100644
--- a/src/parser/fun.rs
+++ b/src/parser/fun.rs
@@ -4,55 +4,67 @@ use crate::lexer::Token;
use chumsky::{prelude::*, Parser};
#[derive(Debug, Clone)]
+enum NumberΛ<'s> {
+ Number(u64),
+ Λ(Λ<'s>),
+}
+
+#[derive(Debug, Clone)]
pub enum Function<'s> {
+ Both(Λ<'s>),
+ And(Λ<'s>, Λ<'s>),
+ If { then: Λ<'s>, or: Λ<'s> },
+ Array(Option<NumberΛ<'s>>),
+ Map(Λ<'s>),
Dup,
- Both(Λ<'s>, Λ<'s>),
- Fork(Λ<'s>, Λ<'s>),
- Gap(Λ<'s>),
- Hold(Λ<'s>),
Flip,
- Duck(Λ<'s>),
+ Eq,
Reverse,
Zap,
Add,
Sub,
+ Not,
Mul,
Pow,
+ Type,
+ Merge,
Sqrt,
- Ne,
Lt,
- Le,
Gt,
Ge,
+ Le,
Shl,
Shr,
Neg,
- And,
+ BitAnd,
+ Length,
Or,
Xor,
Div,
Mod,
- Keep,
+ Index,
+ Mask,
+ Group(Λ<'s>),
Split,
First,
Last,
- Each(Λ<'s>),
Reduce(Λ<'s>),
- ReduceStack(Λ<'s>),
Range,
+ With,
Call,
+ Sort,
+ Zip,
+ Ident(&'s str),
+ Define(&'s str),
}
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("λ")
+ exp.repeated()
+ .collect()
+ .delimited_by(t!['('], t![')'])
+ .map(|x| Self(x))
+ .labelled("lambda")
}
}
@@ -62,43 +74,106 @@ impl<'s> Function<'s> {
let basic = select! {
Token::Dup => Dup,
Token::Flip => Flip,
- Token::Reverse => Reverse,
+ // Token::Reverse => Reverse,
Token::Zap => Zap,
Token::Add => Add,
Token::Sub => Sub,
Token::Mul => Mul,
Token::Pow => Pow,
Token::Sqrt => Sqrt,
- Token::Ne => Ne,
Token::Lt => Lt,
- Token::Le => Le,
- Token::Gt => Gt,
- Token::Ge => Ge,
+ Token::Index => Index,
+ Token::Merge => Merge,
Token::Shl => Shl,
Token::Shr => Shr,
Token::Neg => Neg,
- Token::And => And,
+ Token::Eq => Eq,
+ Token::Gt => Gt,
+ Token::Ge => Ge,
+ Token::Length => Length,
+ Token::Range => Range,
+ Token::Le => Le,
+ Token::BitAnd => BitAnd,
Token::Or => Or,
Token::Xor => Xor,
+ Token::Sort => Sort,
+ Token::Zip => Zip,
Token::Div => Div,
Token::Mod => Mod,
- Token::Keep => Keep,
+ Token::Mask => Mask,
+ Token::With => With,
Token::Split => Split,
Token::First => First,
+ Token::Type => Type,
Token::Last => Last,
- };
+ Token::Ident(x) => Ident(x),
+ }
+ .labelled("token");
+
+ let fn_param = choice((
+ basic
+ .map(|x| Λ(vec![Expr::Function(x)]))
+ .labelled("function"),
+ λ.clone(),
+ ))
+ .labelled("operand");
+
+ macro_rules! one {
+ ($name:ident) => {
+ fn_param
+ .clone()
+ .then_ignore(just(Token::$name))
+ .map($name)
+ .labelled(stringify!($name))
+ };
+ }
macro_rules! two {
- ($name:ident) => {{
- let mut p = Recursive::declare();
- p.define(
- λ.clone()
- .then(λ.clone())
- .then_ignore(just(Token::$name))
- .map(|(a, b)| $name(a, b)),
- );
- p
- }};
+ ($name:ident) => {
+ fn_param
+ .clone()
+ .then(fn_param.clone())
+ .then_ignore(just(Token::$name))
+ .map(|(a, b)| $name(a, b))
+ .labelled(stringify!($name))
+ };
}
- choice((basic, two![Both], two![Fork]))
+ choice((
+ two![And],
+ one![Both],
+ one![Reduce],
+ one![Map],
+ λ.clone().then_ignore(just(Token::Group)).map(Group),
+ just(Token::Array)
+ .ignore_then(
+ fn_param
+ .clone()
+ .map(NumberΛ::Λ)
+ .or(select! { Token::Int(x) => NumberΛ::Number(x)}),
+ )
+ .map(Some)
+ .map(Array)
+ .labelled("array")
+ .boxed(),
+ fn_param
+ .clone()
+ .then(fn_param.clone())
+ .then_ignore(just(Token::If))
+ .map(|(then, or)| If { then, or })
+ .labelled("if-else")
+ .boxed(),
+ fn_param
+ .clone()
+ .then_ignore(just(Token::EagerIf).labelled("if"))
+ .map(|then| If {
+ then,
+ or: Λ::default(),
+ })
+ .labelled("if")
+ .boxed(),
+ t![->].ignore_then(t![ident]).map(Define).labelled("def"),
+ basic,
+ ))
+ .boxed()
+ .labelled("function")
}
}