tmp
| -rw-r--r-- | Cargo.lock | 7 | ||||
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | src/lexer.rs | 18 | ||||
| -rw-r--r-- | src/parser.rs | 10 | ||||
| -rw-r--r-- | src/parser/fun.rs | 100 | ||||
| -rw-r--r-- | src/parser/types.rs | 7 | ||||
| -rw-r--r-- | src/parser/util.rs | 2 | ||||
| -rw-r--r-- | src/stackd | 15 | ||||
| -rw-r--r-- | stackd | 26 |
9 files changed, 151 insertions, 35 deletions
@@ -104,6 +104,7 @@ dependencies = [ "lerr", "logos", "match_deref", + "paste", "tinyvec", ] @@ -168,6 +169,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] name = "proc-macro2" version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -16,3 +16,4 @@ tinyvec = { version = "1.6.0", features = ["alloc"] } comat = "0.1.3" lerr = "0.1.5" match_deref = "0.1.1" +paste = "1.0.14" diff --git a/src/lexer.rs b/src/lexer.rs index 559a9d7..d4d1476 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -22,9 +22,8 @@ macro_rules! tokens { #[regex(r"'.'", |lex| lex.slice().as_bytes()[1] as char)] Char(char), // todo ignore alot - #[regex(r"[^\s\(\)\[\]\{\}0-9Ξ»'\-ββ=π’ππ΄πβ‡οΈ+Γ*ββ <β€>β₯βͺβ©\-Β―β§β¨β»Γ·%ππ§β¬
β‘βοΈβ‘οΈβοΈππ³][^\(\)\[\]\{\}Ξ»ββ='π’ππ΄πβ‡οΈ+Γ*ββ <β€>β₯βͺβ©Β―β§β¨β»Γ·%ππ§β¬
β‘βοΈβ‘οΈβοΈππ³\s]*", priority = 7)] + #[regex(r"[^\s\(\)\[\]\{\}0-9Ξ»'\-ββ=β’β‘π’π¦βπͺ£πππ΄πβ‡οΈβοΈπ+Γ*ββ <β€>β₯βͺβ©\-Β―β§β¨β»Γ·%ππ§β¬
β‘βοΈβ‘οΈβοΈππ³][^\(\)\[\]\{\}Ξ»ββ=β’β‘'π’ππ΄βπβ‡οΈ+πͺ£Γπ*βπ¦β <β€>β₯βοΈπβͺβ©Β―β§β¨β»Γ·%ππ§β¬
β‘βοΈβ‘οΈβοΈππ³\s]*", priority = 7)] Ident(&'strings str), - #[token("[", chr::<'['>)] #[token("(", chr::<'('>)] #[token("{", chr::<'{'>)] @@ -58,18 +57,22 @@ tokens! { "Ξ»" => Lambda, "β" => Place, "β" => Ret, - "=" => Eq, + "β‘" => Eq, "π’" => Dup, "π" => Both, "π΄" => Fork, + "πͺ£" => Gap, + "β" => Hold, "π" => Flip, + "π¦" => Duck, "β" => Reverse, - "‡οΈ" => Pop, + "‡οΈ" => Zap, "+" => Add, + "-" => Sub, "Γ" => Mul, "*" => Pow, "β" => Sqrt, - "β " => Ne, + "β’" => Ne, "<" => Lt, "β€" => Le, ">" => Gt, @@ -79,19 +82,20 @@ tokens! { "Β―" => Neg, "β§" => And, "β¨" => Or, - "-" => Sub, "β»" => Xor, "Γ·" => Div, "%" => Mod, - "π" => Keep, + "π" => Keep, "π§" => Split, "β¬
" => First, "β‘" => Last, "βοΈ" => Each, "β‘οΈ" => Reduce, "βοΈ" => ReduceStack, + "β¬οΈ" => Range, "π" => If, "π³" => Else, + "βοΈ" => Call, } diff --git a/src/parser.rs b/src/parser.rs index df5af22..8cee0ef 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -5,6 +5,7 @@ use chumsky::{ prelude::*, Parser, }; +mod fun; mod util; use types::*; use util::*; @@ -34,7 +35,7 @@ impl<'s> Expr<'s> { choice((t![ident].map(Expr::Ident), val)).boxed() }); - let Ξ» = t![Ξ»].ignore_then(expr.clone().delimited_by(t!['('], t![')'])); + let Ξ» = Lambda::parse().map(Expr::Lambda); let decl = t![ident] .then_ignore(t![<-]) @@ -56,13 +57,18 @@ impl<'s> Expr<'s> { then: Box::new(a), or: Box::new(b.unwrap_or_else(|| Expr::Value(Value::Unit))), }) - .labelled("if") + .labelled("π") .boxed(); choice((decl, r#if, inline_expr, Ξ»)) }) } } +#[test] +fn parse_expr() { + dbg!(Expr::parse().parse(code("a β Ξ» ( +- π΄ )")).unwrap()); +} + pub fn stream(lexer: Lexer<'_>, len: usize) -> SpannedInput<Token<'_>, Span, Stream<Lexer<'_>>> { Stream::from_iter(lexer).spanned((len..len).into()) } diff --git a/src/parser/fun.rs b/src/parser/fun.rs new file mode 100644 index 0000000..9dfd561 --- /dev/null +++ b/src/parser/fun.rs @@ -0,0 +1,100 @@ +use super::types::*; +use super::util::*; +use crate::lexer::Token; +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>), + Flip, + Duck(Lambda<'s>), + Reverse, + Zap, + Add, + Sub, + Mul, + Pow, + Sqrt, + Ne, + Lt, + Le, + Gt, + Ge, + Shl, + Shr, + Neg, + And, + Or, + Xor, + Div, + Mod, + Keep, + Split, + First, + Last, + Each(Lambda<'s>), + Reduce(Lambda<'s>), + ReduceStack(Lambda<'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> Function<'s> { + pub fn parse() -> parser![Self] { + use Function::*; + let basic = select! { + Token::Dup => Dup, + Token::Flip => Flip, + 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::Shl => Shl, + Token::Shr => Shr, + Token::Neg => Neg, + Token::And => And, + Token::Or => Or, + Token::Xor => Xor, + Token::Div => Div, + Token::Mod => Mod, + Token::Keep => Keep, + Token::Split => Split, + Token::First => First, + Token::Last => Last, + }; + macro_rules! two { + ($name:ident) => { + Lambda::parse() + .then(Lambda::parse()) + .then_ignore(just(Token::$name)) + .map(|(a, b)| $name(a, b)) + }; + } + choice((basic, two![Both], two![Fork])) + } +} diff --git a/src/parser/types.rs b/src/parser/types.rs index 298b573..2385564 100644 --- a/src/parser/types.rs +++ b/src/parser/types.rs @@ -15,6 +15,9 @@ pub enum Ast<'s> { Module(Vec<Expr<'s>>), } +#[derive(Clone, Debug)] +pub struct Lambda<'s>(pub Vec<Expr<'s>>); + #[derive(Clone)] pub enum Value<'s> { Float(f64), @@ -34,11 +37,13 @@ impl std::fmt::Debug for Value<'_> { } } -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum Expr<'s> { NoOp, + Function(super::fun::Function<'s>), Value(Value<'s>), Ident(&'s str), + Lambda(Lambda<'s>), Let { name: &'s str, rhs: Box<Expr<'s>>, diff --git a/src/parser/util.rs b/src/parser/util.rs index a4f1c71..60c242a 100644 --- a/src/parser/util.rs +++ b/src/parser/util.rs @@ -29,7 +29,7 @@ macro_rules! t { just(Token::ThinArrow) }; (()) => { - just(Token::Unit) + just(Token::Call) }; ('(') => { just(Token::OpeningBracket('(')) diff --git a/src/stackd b/src/stackd deleted file mode 100644 index 8c48039..0000000 --- a/src/stackd +++ /dev/null @@ -1,15 +0,0 @@ -"1abc25hriwm4" -// { str β int } -line β Ξ» ( - '0'>π'9'<π - '9'- - // modifiers are placed in front - πβ¬
β‘ - 10Γ+ -) - -π’β '\n'π§ -// run function on all values, pushing to the stack -βοΈline -// reduce the stack -βοΈ+
\ No newline at end of file @@ -1,18 +1,26 @@ "1abc25hriwm4" +// usage: 0 π’ Ξ»(<5) Ξ»(1+) π¬βοΈ +π¬ β Ξ» ( + / evaluate the condition / + Ξ»(π’πͺ£βοΈ)ββ + π ( + / evaluate the body / + π’βοΈ + / recurse / + π¬βοΈ + ) +) + // { str β int } line β Ξ» ( - '0'>π'9'<π + '0'>π'9'<π '9'- - // modifiers are placed in front - πβ¬
β‘ + β¬
β‘π΄ 10Γ+ ) -π’β '\n'π§ -// run function on all values, pushing to the stack +π’β’'\n'π§ +/ run function on all values, pushing to the stack / βοΈline -// reduce the stack +/ reduce the stack / βοΈ+ - -// true π (+ π³ -) -// if true { + } else { - }
\ No newline at end of file |