From f65aa8d9216e4f4436b5d6b4e9c85654d5f5d7ab Mon Sep 17 00:00:00 2001 From: janis Date: Fri, 19 Sep 2025 13:47:49 +0200 Subject: [PATCH] -- and ++ tokens --- crates/lexer/src/lib.rs | 42 ++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/crates/lexer/src/lib.rs b/crates/lexer/src/lib.rs index 0ab28c5..b422eb9 100644 --- a/crates/lexer/src/lib.rs +++ b/crates/lexer/src/lib.rs @@ -202,7 +202,9 @@ tokens!(pub Token: { Bang => "!", Tilde => "~", Plus => "+", + PlusPlus => "++", Minus => "-", + MinusMinus => "--", Star => "*", Slash => "/", Percent => "%", @@ -443,9 +445,10 @@ impl LexemeParser { } } -// but what if...? tree! -mod tree { +// but what if...? prefix-tree! +mod trie { use super::Token; + use std::collections::BTreeMap; #[derive(Debug, Default)] struct Node { @@ -496,7 +499,7 @@ mod tree { fn search_tree(tree: &Tree, mut tokens: impl Iterator) -> Option { let mut current = tree.root.as_ref().unwrap(); - let mut p = 0; + let mut p = None; loop { let Some(ch) = tokens.next() else { @@ -507,7 +510,7 @@ mod tree { break; } - p = match current.keys.binary_search(&ch) { + let n = match current.keys.binary_search(&ch) { Ok(p) => p, Err(p) => { eprintln!("No match for {ch} in {:?} (p={p})", current.keys); @@ -515,14 +518,17 @@ mod tree { } }; - current = match current.edges.get(p) { + current = match current.edges.get(n) { Some(Some(node)) => node, - _ => break, + _ => { + p = Some(n); + break; + } }; } eprintln!("current: {:?}", current); - current.values.get(p).copied().flatten() + current.values.get(p?).copied().flatten() } #[cfg(test)] @@ -531,10 +537,28 @@ mod tree { #[test] fn test_tree() { + use werkzeug::iter::AdvanceWhile; let tree = build_tree(); eprintln!("Tree: {tree:?}"); - let tokens = "fn let void"; - assert_eq!(search_tree(&tree, tokens.chars()), Some(Token::Fn)); + let mut tokens = "fn let void+++(++bool)".chars(); + assert_eq!(search_tree(&tree, &mut tokens), Some(Token::Fn)); + tokens.advance_while(|&c| crate::is_things::is_whitespace(c)); + assert_eq!(search_tree(&tree, &mut tokens), Some(Token::Let)); + tokens.advance_while(|&c| crate::is_things::is_whitespace(c)); + assert_eq!(search_tree(&tree, &mut tokens), Some(Token::Void)); + tokens.advance_while(|&c| crate::is_things::is_whitespace(c)); + assert_eq!(search_tree(&tree, &mut tokens), Some(Token::PlusPlus)); + tokens.advance_while(|&c| crate::is_things::is_whitespace(c)); + assert_eq!(search_tree(&tree, &mut tokens), Some(Token::Plus)); + tokens.advance_while(|&c| crate::is_things::is_whitespace(c)); + assert_eq!(search_tree(&tree, &mut tokens), Some(Token::OpenParens)); + tokens.advance_while(|&c| crate::is_things::is_whitespace(c)); + assert_eq!(search_tree(&tree, &mut tokens), Some(Token::PlusPlus)); + tokens.advance_while(|&c| crate::is_things::is_whitespace(c)); + assert_eq!(search_tree(&tree, &mut tokens), Some(Token::Bool)); + tokens.advance_while(|&c| crate::is_things::is_whitespace(c)); + assert_eq!(search_tree(&tree, &mut tokens), Some(Token::CloseParens)); + assert_eq!(search_tree(&tree, &mut tokens), None); } } }