-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock171
-rw-r--r--Cargo.toml10
-rw-r--r--src/lexer.rs116
-rw-r--r--src/main.rs3
-rw-r--r--stackd8
6 files changed, 309 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..b7b788f
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,171 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "ahash"
+version = "0.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "version_check",
+ "zerocopy",
+]
+
+[[package]]
+name = "allocator-api2"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
+
+[[package]]
+name = "beef"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "chumsky"
+version = "1.0.0-alpha.6"
+source = "git+https://github.com/zesterer/chumsky#8b8cf0a04b157df30799d4f385ddedc1dca85014"
+dependencies = [
+ "hashbrown",
+ "unicode-ident",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "hashbrown"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
+dependencies = [
+ "ahash",
+ "allocator-api2",
+]
+
+[[package]]
+name = "kale"
+version = "0.1.0"
+dependencies = [
+ "chumsky",
+ "logos",
+]
+
+[[package]]
+name = "logos"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c000ca4d908ff18ac99b93a062cb8958d331c3220719c52e77cb19cc6ac5d2c1"
+dependencies = [
+ "logos-derive",
+]
+
+[[package]]
+name = "logos-codegen"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc487311295e0002e452025d6b580b77bb17286de87b57138f3b5db711cded68"
+dependencies = [
+ "beef",
+ "fnv",
+ "proc-macro2",
+ "quote",
+ "regex-syntax",
+ "syn",
+]
+
+[[package]]
+name = "logos-derive"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbfc0d229f1f42d790440136d941afd806bc9e949e2bcb8faa813b0f00d1267e"
+dependencies = [
+ "logos-codegen",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
+
+[[package]]
+name = "syn"
+version = "2.0.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "zerocopy"
+version = "0.7.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
+dependencies = [
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.7.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..eb1c8c7
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "kale"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+chumsky = { git = "https://github.com/zesterer/chumsky", version = "1.0.0-alpha.6", default-features = false, features = ["label", "nightly"] }
+logos = "0.13.0"
diff --git a/src/lexer.rs b/src/lexer.rs
new file mode 100644
index 0000000..3345887
--- /dev/null
+++ b/src/lexer.rs
@@ -0,0 +1,116 @@
+use beef::lean::Cow;
+use chumsky::span::SimpleSpan;
+use logos::{Lexer as RealLexer, Logos, SpannedIter};
+
+macro_rules! tokens {
+ ($($z:literal $( | $y:literal)? => $v:ident,)+) => {
+ #[derive(Logos, Debug, PartialEq, Clone)]
+ #[logos(skip r"[\n\s]+")]
+ pub enum Token<'strings> {
+ #[regex("/[^\n/]+/", priority = 8)]
+ Comment(&'strings str),
+ #[regex(r"[0-9]+", |lex| lex.slice().parse().ok())]
+ #[regex(r"0[xX][0-9a-fA-F]+", |lex| u64::from_str_radix(&lex.slice()[2..], 16).ok())]
+ #[regex(r"0[bB][01]+", |lex| u64::from_str_radix(&lex.slice()[2..], 2).ok())]
+ Int(u64),
+ #[regex(r"[0-9]+\.[0-9]+", |lex| lex.slice().parse().ok())]
+ Float(f64),
+ #[regex(r#""([^\\"\n])*""#, callback = |lex| Cow::from(&lex.slice()[1..lex.slice().len()-1]), priority = 12)]
+ #[regex(r#""[^"]*""#, callback = |lex| Cow::from(lex.slice()[1..lex.slice().len()-1].replace(r"\n", "\n")), priority = 8)]
+ String(Cow<'strings, str>),
+ // todo ignore alot
+ #[regex(r"[^\s0-9][^\s]*", priority = 7)]
+ Ident(&'strings str),
+
+ #[token("[", chr::<'['>)]
+ #[token("(", chr::<'('>)]
+ #[token("{", chr::<'{'>)]
+ OpeningBracket(char),
+ #[token("]", chr::<']'>)]
+ #[token(")", chr::<')'>)]
+ #[token("}", chr::<'}'>)]
+ ClosingBracket(char),
+
+ $(#[token($z, priority = 8)] $(#[token($y, priority = 8)])? $v,)+
+ }
+
+ impl std::fmt::Display for Token<'_> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
+ match self {
+ $(Self::$v => write!(f, $z),)+
+ Self::FnIdent(s) | Self::Ident(s) | Self::Comment(s) => write!(f, "{s}"),
+ Self::String(s) => write!(f, "{s}"),
+ Self::Float(n) => write!(f, "{n}"),
+ Self::Int(n) => write!(f, "{n}"),
+ Self::OpeningBracket(x) | Self::ClosingBracket(x) => write!(f,"{x}"),
+ }
+ }
+ }
+ }
+}
+
+tokens! {
+ "λ" => Lamba,
+ "←" => Place,
+ "→" => Ret,
+ "=" => Eq,
+ "." => Dup,
+ ":" => Flip,
+ "⤵️" => Pop,
+ "+" => Add,
+ "×" => Mul,
+ "*" => Pow,
+ "√" => Sqrt,
+ "≠" => Ne,
+ "<" => Lt,
+ "≤" | "≯" => Le,
+ ">" => Gt,
+ "≥" | "≮" => Ge,
+ "«" => Shl,
+ "»" => Shr,
+ "¯" => Neg,
+ "&" => And,
+ "|" => Or,
+ "^" => Xor,
+ "÷" => Div,
+ "%" => Mod,
+ "🔎" => Keep,
+ "🚧" => Split,
+
+}
+
+pub fn lex(s: &str) -> Lexer {
+ Lexer {
+ inner: Token::lexer(s).spanned(),
+ }
+}
+
+fn chr<'src, const CHR: char>(_: &mut RealLexer<'src, Token<'src>>) -> Result<char, ()> {
+ Ok(CHR)
+}
+pub struct Lexer<'s> {
+ inner: SpannedIter<'s, Token<'s>>,
+}
+
+impl<'s> Iterator for Lexer<'s> {
+ type Item = (Token<'s>, SimpleSpan<usize>);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner.find_map(|(x, s)| match x.ok()? {
+ Token::Comment(_) => None,
+ x => Some((x, SimpleSpan::new(s.start, s.end))),
+ })
+ }
+}
+
+#[test]
+fn lexer() {
+ let mut lex = lex(r#""#);
+ // while let Some(x) = lex.next() { print!("{x} "); }
+ macro_rules! test {
+ ($($tok:ident$(($var:literal))?)+) => {{
+ $(assert_eq!(lex.next().map(|(x,_)|x), Some(Token::$tok$(($var.into()))?));)+
+ assert_eq!(lex.next(), None);
+ }}
+ }
+}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..e7a11a9
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,3 @@
+fn main() {
+ println!("Hello, world!");
+}
diff --git a/stackd b/stackd
new file mode 100644
index 0000000..ba2d864
--- /dev/null
+++ b/stackd
@@ -0,0 +1,8 @@
+push "1abc25hriwm4"
+
+line ← λ { str -> int } (
+ 48>🔎57<🔎
+ 57 -
+ first 10 * swap last +
+ dup call swap call
+)