From 7baa16ee8e797f51c627de9be5a00e6fb445c085 Mon Sep 17 00:00:00 2001 From: Alpha Chen Date: Tue, 18 Oct 2022 09:37:47 -0700 Subject: [PATCH] don't use a null sentinel --- rust/src/scanner.rs | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/rust/src/scanner.rs b/rust/src/scanner.rs index 1b82962..879d7cb 100644 --- a/rust/src/scanner.rs +++ b/rust/src/scanner.rs @@ -76,7 +76,7 @@ impl<'a> Scanner<'a> { } fn is_at_end(&self) -> bool { - self.source[self.current] == 0 + self.current == self.source.len() } fn make_token(&self, kind: TokenKind) -> Result { @@ -115,20 +115,19 @@ impl<'a> Scanner<'a> { fn skip_whitespace(&mut self) { loop { - let c = self.peek(); - match c { - ' ' | '\r' | '\t' => { + match self.peek() { + Some(' ') | Some('\r') | Some('\t') => { self.advance(); break; } - '\n' => { + Some('\n') => { self.line += 1; self.advance(); break; } - '/' => { - if self.peek_next() == '/' { - while self.peek() != '\n' && !self.is_at_end() { + Some('/') => { + if matches!(self.peek_next(), Some(c) if c == '/') { + while matches!(self.peek(), Some(c) if c != '\n') { self.advance(); } } else { @@ -142,21 +141,21 @@ impl<'a> Scanner<'a> { } } - fn peek(&self) -> char { - self.source[self.current] as char + fn peek(&self) -> Option { + self.source.get(self.current).map(|&x| x as char) } - fn peek_next(&mut self) -> char { + fn peek_next(&mut self) -> Option { if self.is_at_end() { - 0 as char + None } else { - self.source[self.current + 1] as char + Some(self.source[self.current + 1] as char) } } fn string(&mut self) -> Result { - while self.peek() != '"' && !self.is_at_end() { - if self.peek() == '\n' { + while matches!(self.peek(), Some(c) if c != '"') { + if self.peek() == Some('\n') { self.line += 1; } self.advance(); @@ -171,14 +170,14 @@ impl<'a> Scanner<'a> { } fn number(&mut self) -> Result { - while self.peek().is_ascii_digit() { + while matches!(self.peek(), Some(c) if c.is_ascii_digit()) { self.advance(); } - if self.peek() == '.' && self.peek_next().is_ascii_digit() { + if self.peek() == Some('.') && matches!(self.peek_next(), Some(c) if c.is_ascii_digit()) { self.advance(); - while self.peek().is_ascii_digit() { + while matches!(self.peek(), Some(c) if c.is_ascii_digit()) { self.advance(); } } @@ -187,7 +186,7 @@ impl<'a> Scanner<'a> { } fn identifier(&mut self) -> Result { - while is_alpha(self.peek()) || self.peek().is_ascii_digit() { + while matches!(self.peek(), Some(c) if is_alpha(c) || c.is_ascii_digit()) { self.advance(); } @@ -339,9 +338,7 @@ mod tests { } fn assert_scan_token(source: &str, kind: TokenKind) { - let mut s = source.to_string(); - s.push(0 as char); - let mut scanner = Scanner::new(&s); + let mut scanner = Scanner::new(source); let token = scanner.scan().unwrap(); assert_eq!(token.kind, kind); }