don't use a null sentinel

main
Alpha Chen 2 years ago
parent 02abf5ca96
commit 7baa16ee8e
Signed by: alpha
SSH Key Fingerprint: SHA256:3fOT8fiYQG/aK9ntivV3Bqtg8AYQ7q4nV6ZgihOA20g

@ -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<Token> {
@ -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<char> {
self.source.get(self.current).map(|&x| x as char)
}
fn peek_next(&mut self) -> char {
fn peek_next(&mut self) -> Option<char> {
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<Token> {
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<Token> {
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<Token> {
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);
}

Loading…
Cancel
Save