| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Cargo.lock | 171 | ||||
| -rw-r--r-- | Cargo.toml | 10 | ||||
| -rw-r--r-- | src/lexer.rs | 116 | ||||
| -rw-r--r-- | src/main.rs | 3 | ||||
| -rw-r--r-- | stackd | 8 |
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!"); +} @@ -0,0 +1,8 @@ +push "1abc25hriwm4" + +line ← λ { str -> int } ( + 48>🔎57<🔎 + 57 - + first 10 * swap last + + dup call swap call +) |