it was fun not really dumb

This commit is contained in:
nora 2021-12-30 14:14:30 +01:00
parent d3125945eb
commit e7e8ee4b4d

View file

@ -307,52 +307,23 @@ impl<'code> Iterator for Lexer<'code> {
} }
fn keyword_or_ident(name: &str) -> TokenType { fn keyword_or_ident(name: &str) -> TokenType {
// make this efficient using the trie pattern match name {
// ignore that unicode exists, because all keywords are in ascii "loop" => TokenType::Loop,
// we need to use bytes though instead of indexing into the string directly to avoid panics "let" => TokenType::Let,
let bs = name.as_bytes(); "fn" => TokenType::Fn,
let len = bs.len(); "for" => TokenType::For,
// there are no single letter keywords "false" => TokenType::False,
if len < 2 { "if" => TokenType::If,
return TokenType::Ident(name); "else" => TokenType::Else,
} "while" => TokenType::While,
match bs[0] { "break" => TokenType::Break,
// loop && let "return" => TokenType::Return,
b'l' => match bs[1] { "true" => TokenType::True,
b'o' if len == 4 && bs[2..4] == *b"op" => TokenType::Loop, "null" => TokenType::Null,
b'e' if len == 3 && bs[2] == b't' => TokenType::Let, "not" => TokenType::Not,
_ => TokenType::Ident(name), "and" => TokenType::And,
}, "or" => TokenType::Or,
// for && fn && false "print" => TokenType::Print,
b'f' => match bs[1] {
b'n' if len == 2 => TokenType::Fn,
b'o' if len == 3 && bs[2] == b'r' => TokenType::For,
b'a' if len == 5 && bs[2..5] == *b"lse" => TokenType::False,
_ => TokenType::Ident(name),
},
// if
b'i' if len == 2 && bs[1] == b'f' => TokenType::If,
// else
b'e' if len == 4 && bs[1..4] == *b"lse" => TokenType::Else,
// while
b'w' if len == 5 && bs[1..5] == *b"hile" => TokenType::While,
// break
b'b' if len == 5 && bs[1..5] == *b"reak" => TokenType::Break,
// return
b'r' if len == 6 && bs[1..6] == *b"eturn" => TokenType::Return,
// true
b't' if len == 4 && bs[1..4] == *b"rue" => TokenType::True,
// null && not
b'n' => match bs[1] {
b'u' if len == 4 && bs[2..4] == *b"ll" => TokenType::Null,
b'o' if len == 3 && bs[2] == b't' => TokenType::Not,
_ => TokenType::Ident(name),
},
// and
b'a' if len == 3 && bs[1..3] == *b"nd" => TokenType::And,
// or
b'o' if len == 2 && bs[1] == b'r' => TokenType::Or,
b'p' if len == 5 && bs[1..5] == *b"rint" => TokenType::Print,
_ => TokenType::Ident(name), _ => TokenType::Ident(name),
} }
} }