From f3922ff84da34746f845f5b817573944f8991fa4 Mon Sep 17 00:00:00 2001 From: paladin Date: Mon, 5 Oct 2026 07:32:40 +0100 Subject: [PATCH] Small tweaks --- .gitignore | 1 + Cargo.lock | 53 +++++++++++++++++++++ Cargo.toml | 5 -- macros/src/lib.rs | 117 ++++++++++++++++++++++++++++++++++++++++------ map/Cargo.toml | 5 ++ map/src/lib.rs | 13 ++++-- src/lib.rs | 11 ++++- 7 files changed, 182 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index c507849..58db1f3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ target .idea +Cargo.lock diff --git a/Cargo.lock b/Cargo.lock index 6f3b4cd..b44390e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,3 +5,56 @@ version = 4 [[package]] name = "deimos" version = "0.1.0" +dependencies = [ + "macros", + "map", +] + +[[package]] +name = "macros" +version = "0.0.0" +dependencies = [ + "map", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "map" +version = "0.1.0" + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" diff --git a/Cargo.toml b/Cargo.toml index c4d9815..06449b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,11 +3,6 @@ name = "deimos" version = "0.1.0" edition = "2024" -[features] -bighash = [] -assertions = [] -messages = [] - [dependencies] macros = { path = "macros" } map = { path = "map" } \ No newline at end of file diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 41edcd1..ac82e28 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,19 +1,108 @@ extern crate proc_macro; -use proc_macro::TokenStream; +use proc_macro::{Delimiter, Group, Punct, Ident, TokenStream, TokenTree, Literal, Spacing, Span}; +use proc_macro::token_stream::IntoIter; +use std::iter::Peekable; +use map::{DisplacementSet, Equivalent, Hashed, Hashes, MapEntry, TableEntry}; -use syn::{parse_macro_input, DeriveInput}; -use quote::quote; +type Tokens = Peekable; + +fn brackets(stream: TokenStream) -> TokenStream { + TokenStream::from(TokenTree::Group(Group::new(Delimiter::Brace,stream))) +} + +fn entry(input: &mut Tokens) -> Option> { + if let Some(token) = input.peek() { + let index = match input.next() { // Take one literal as an index + Some(TokenTree::Literal(literal)) => literal.to_string(), + Some(_) => panic!("Expected literal index"), + None => return None, + }; + match input.next() { // Look for '=' in "=>" + Some(TokenTree::Punct(punct)) if punct.as_char() == '=' => {}, + _ => panic!("Expected '=>'"), + }; + match input.next() { // Look for '>' in "=>" + Some(TokenTree::Punct(punct)) if punct.as_char() == '>' => {}, + _ => panic!("Expected '=>'"), + }; + let mut value = Vec::new(); + let mut closure = false; + loop { // Accumulate value token stream until ',' is found + match input.next() { + Some(TokenTree::Punct(punct)) if punct.as_char() == ',' && !closure => break, + Some(ref it@TokenTree::Punct(ref punct)) if punct.as_char() == '|' => { + value.push(it.clone()); + closure = !closure + }, + Some(it) => value.push(it), + None => break, + } + } + let mut value_stream = TokenStream::new(); + value_stream.extend(value); + Some(MapEntry(Some(( + index, + value_stream, + )))) + } else { + None + } +} -/// Example of [function-like procedural macro][1]. -/// -/// [1]: https://doc.rust-lang.org/reference/procedural-macros.html#function-like-procedural-macros #[proc_macro] -pub fn map(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - - let tokens = quote! { - const - }; - - tokens.into() +pub fn map(input: TokenStream) -> TokenStream { // todo: only works for string literals right now + let mut tokens = input.into_iter().peekable(); + let mut entries = DisplacementSet::new(); + while let Some(entry) = entry(&mut tokens) { + entries.set(entry); + } + let mut elements = TokenStream::new(); + for entry in entries.map.iter() { + let option = if let Some(entry) = entry.entry.clone().0 { + let mut inner = TokenStream::new(); + inner.extend(vec![ + TokenTree::Literal(Literal::string(entry.0.as_str())), + TokenTree::Punct(Punct::new(',',Spacing::Alone)), + ]); + inner.extend(entry.1); + let inner = TokenStream::from(TokenTree::Group(Group::new(Delimiter::Parenthesis,inner))); + let mut option = TokenStream::new(); + option.extend(vec![ + TokenTree::Ident(Ident::new("Some",Span::mixed_site())), + TokenTree::Group(Group::new(Delimiter::Parenthesis,inner)) + ]); + option + } else { + TokenStream::from(TokenTree::Ident(Ident::new("None",Span::mixed_site()))) + }; + let mut set_entry = TokenStream::new(); + set_entry.extend(vec![ + TokenTree::Ident(Ident::new("entry",Span::mixed_site())), + TokenTree::Punct(Punct::new(':',Spacing::Alone)), + TokenTree::Ident(Ident::new("MapEntry",Span::mixed_site())), + TokenTree::Group(Group::new(Delimiter::Parenthesis,option)), + TokenTree::Punct(Punct::new(',',Spacing::Alone)), + TokenTree::Ident(Ident::new("home",Span::mixed_site())), + TokenTree::Punct(Punct::new(':',Spacing::Alone)), + TokenTree::Literal(Literal::usize_unsuffixed(entry.home)), + TokenTree::Punct(Punct::new(',',Spacing::Alone)), + TokenTree::Ident(Ident::new("displacement",Span::mixed_site())), + TokenTree::Punct(Punct::new(':',Spacing::Alone)), + TokenTree::Literal(Literal::usize_unsuffixed(entry.displacement as usize)), + TokenTree::Punct(Punct::new(',',Spacing::Alone)), + ]); + elements.extend(vec![ + /*TokenTree::Ident(Ident::new("deimos",Span::mixed_site())), + TokenTree::Punct(Punct::new(':',Spacing::Joint)), + TokenTree::Punct(Punct::new(':',Spacing::Joint)), + TokenTree::Ident(Ident::new("map",Span::mixed_site())), + TokenTree::Punct(Punct::new(':',Spacing::Joint)), + TokenTree::Punct(Punct::new(':',Spacing::Joint)),*/ + TokenTree::Ident(Ident::new("Entry",Span::mixed_site())), + TokenTree::Group(Group::new(Delimiter::Brace,set_entry)), + TokenTree::Punct(Punct::new(',',Spacing::Alone)), + ]) + } + let mut array = TokenStream::from(TokenTree::Group(Group::new(Delimiter::Bracket,elements))); + array } \ No newline at end of file diff --git a/map/Cargo.toml b/map/Cargo.toml index 88e4b56..506bee2 100644 --- a/map/Cargo.toml +++ b/map/Cargo.toml @@ -3,4 +3,9 @@ name = "map" version = "0.1.0" edition = "2024" +[features] +bighash = [] +assertions = [] +messages = [] + [dependencies] diff --git a/map/src/lib.rs b/map/src/lib.rs index 063c53e..d6f5f03 100644 --- a/map/src/lib.rs +++ b/map/src/lib.rs @@ -45,11 +45,18 @@ pub trait Hashes { impl Hashes for &str { fn hashed(&self) -> Hashed { let mut hasher = DefaultHasher::new(); - self[..self.len().min(6)].hash(&mut hasher); + self[..self.len().min(8)].hash(&mut hasher); hasher.finish() as Hashed } } +impl Hashes for String { + fn hashed(&self) -> Hashed { + self.as_str().hashed() + } +} + + pub trait TableEntry: Equivalent + Hashes { const VACANT: Self; fn is_vacant(&self) -> bool; @@ -58,8 +65,8 @@ pub trait TableEntry: Equivalent + Hashes { #[derive(Debug)] pub struct Entry { pub entry: E, - home: usize, - displacement: Displacement, + pub home: usize, + pub displacement: Displacement, } impl Entry { diff --git a/src/lib.rs b/src/lib.rs index 6d83946..88427c4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,18 @@ pub mod gc; pub use macros; +pub use map; + #[cfg(test)] mod tests { + use map::{TableEntry,MapEntry,Entry}; + extern crate self as deimos; + #[test] fn simple() { - + static MAP: &[Entry>] = &deimos::macros::map! { + "hello" => || println!("hello there"), + "hi" => || println!("hi friend"), + "greetings" => || println!("salutations"), + }; } } \ No newline at end of file