From 4debd88807c538aa430ce69b83fdb291f687b1b1 Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Mon, 27 May 2024 16:04:31 -0700 Subject: Rewrite in Rust. --- src/lexer.rs | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/lexer.rs (limited to 'src/lexer.rs') diff --git a/src/lexer.rs b/src/lexer.rs new file mode 100644 index 0000000..49d2d04 --- /dev/null +++ b/src/lexer.rs @@ -0,0 +1,74 @@ +pub struct Lexer<'a> { + pub buf: &'a str, +} + +impl<'a> Lexer<'a> { + fn skip_whitespace(&mut self) { + while let Some(b' ') = self.buf.as_bytes().first() { + self.buf = &self.buf[1..] + } + } + + fn parse_num(&mut self) -> Option<&'a str> { + let mut i = 0; + while matches!(self.buf.as_bytes().get(i), Some(&b) if b.is_ascii_digit()) { + i += 1; + } + if let Some(b'.') = self.buf.as_bytes().get(i) { + i += 1; + } + while matches!(self.buf.as_bytes().get(i), Some(&b) if b.is_ascii_digit()) { + i += 1; + } + let (Some(b'e') | Some(b'E')) = self.buf.as_bytes().get(i) else { + let t = &self.buf[..i]; + self.buf = &self.buf[i..]; + return Some(t); + }; + i += 1; + if let Some(b'-') = self.buf.as_bytes().get(i) { + i += 1; + } + while matches!(self.buf.as_bytes().get(i), Some(&b) if b.is_ascii_digit()) { + i += 1; + } + let t = &self.buf[..i]; + self.buf = &self.buf[i..]; + Some(t) + } +} + +impl<'a> Iterator for Lexer<'a> { + type Item = &'a str; + + fn next(&mut self) -> Option<&'a str> { + self.skip_whitespace(); + let &first_byte = self.buf.as_bytes().first()?; + if first_byte.is_ascii_digit() || first_byte == b'.' { + return self.parse_num(); + } + match first_byte { + b'/' => { + if let Some(b'/') = self.buf.as_bytes().get(1) { + self.buf = &self.buf[2..]; + return Some("//"); + } + self.buf = &self.buf[1..]; + return Some("/"); + } + b'+' | b'-' | b'*' | b'^' | b'(' | b')' => { + let t = &self.buf[..1]; + self.buf = &self.buf[1..]; + return Some(t); + } + _ => (), + } + let mut i = 0; + while let Some(b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9') = self.buf.as_bytes().get(i) { + i += 1; + } + let t = &self.buf[..i]; + self.buf = &self.buf[i..]; + Some(t) + } +} -- cgit v1.3.1