Scanner - Numbers

This commit is contained in:
Emmanuel BENOîT 2022-12-30 19:10:14 +01:00
parent 75dd3a2db2
commit 3ccbcbc1c2

View file

@ -54,7 +54,7 @@ impl Scanner {
'/' => { '/' => {
if self.is_match('/') { if self.is_match('/') {
while self.peek() != '\n' && !self.is_at_end() { while self.peek() != '\n' && !self.is_at_end() {
self.advance(); self.current += 1;
} }
} else { } else {
self.add_token(TokenType::Slash) self.add_token(TokenType::Slash)
@ -91,14 +91,19 @@ impl Scanner {
} }
// String litterals // String litterals
'"' => self.string_litteral(err_hdl), '"' => self.string_litteral(err_hdl),
// Numbers
'0'..='9' => self.number(err_hdl),
// Handle whitespace // Handle whitespace
' ' | '\r' | '\t' => (), ' ' | '\r' | '\t' => (),
'\n' => self.line += 1, '\n' => self.line += 1,
// Anything else is an error // Anything else is an error
ch => err_hdl.error(self.line, &format!("unexpected character {:#?}", ch)), ch => {
err_hdl.error(self.line, &format!("unexpected character {:#?}", ch));
}
} }
} }
/// Read the rest of a string litteral
fn string_litteral(&mut self, err_hdl: &mut ErrorHandler) { fn string_litteral(&mut self, err_hdl: &mut ErrorHandler) {
loop { loop {
let p = self.peek(); let p = self.peek();
@ -108,18 +113,47 @@ impl Scanner {
if p == '\n' { if p == '\n' {
self.line += 1; self.line += 1;
} }
self.advance(); self.current += 1;
} }
if self.is_at_end() { if self.is_at_end() {
err_hdl.error(self.line, "unterminated string"); err_hdl.error(self.line, "unterminated string");
} else { } else {
self.advance(); // Last '"' self.current += 1; // Last '"'
let value = self.get_substring(self.start + 1, self.current - 1); let value = self.get_substring(self.start + 1, self.current - 1);
self.add_token(TokenType::String(value)); self.add_token(TokenType::String(value));
} }
} }
/// Read the rest of a number.
fn number(&mut self, err_hdl: &mut ErrorHandler) {
while self.peek().is_digit(10) {
self.current += 1;
}
if self.peek() == '.' && self.peek_next().is_digit(10) {
self.current += 1;
while self.peek().is_digit(10) {
self.current += 1;
}
}
let tok_string = self.get_substring(self.start, self.current);
match tok_string.parse::<f64>() {
Err(e) => {
err_hdl.error(
self.line,
&format!(
"Could not parse {} as a floating point number: {:?}",
tok_string, e
),
);
}
Ok(value) => {
self.add_token(TokenType::Number(value));
}
};
}
/// Check whether the end of the input has been reached. /// Check whether the end of the input has been reached.
fn is_at_end(&self) -> bool { fn is_at_end(&self) -> bool {
self.current >= self.len self.current >= self.len
@ -154,6 +188,16 @@ impl Scanner {
} }
} }
/// Returns the next character, or a NULL character if the end has been
/// reached.
fn peek_next(&self) -> char {
if self.current + 1 >= self.source.chars().count() {
'\0'
} else {
self.source.chars().nth(self.current + 1).unwrap()
}
}
/// Read the current character. /// Read the current character.
fn cur_char(&self) -> char { fn cur_char(&self) -> char {
self.source.chars().nth(self.current).unwrap() self.source.chars().nth(self.current).unwrap()