|
|
@ -27,7 +27,7 @@ static KEYWORDS: phf::Map<&'static str, TokenType> = phf_map! { |
|
|
|
};
|
|
|
|
|
|
|
|
pub struct Scanner {
|
|
|
|
source: String,
|
|
|
|
chars: Vec<char>,
|
|
|
|
tokens: Vec<Token>,
|
|
|
|
start: usize,
|
|
|
|
current: usize,
|
|
|
@ -36,8 +36,9 @@ pub struct Scanner { |
|
|
|
|
|
|
|
impl Scanner {
|
|
|
|
pub fn new(source: String) -> Self {
|
|
|
|
let chars = source.chars().collect();
|
|
|
|
Self {
|
|
|
|
source,
|
|
|
|
chars,
|
|
|
|
tokens: Vec::new(),
|
|
|
|
start: 0,
|
|
|
|
current: 0,
|
|
|
@ -142,21 +143,19 @@ impl Scanner { |
|
|
|
}
|
|
|
|
|
|
|
|
fn is_at_end(&self) -> bool {
|
|
|
|
self.current >= self.source.chars().count()
|
|
|
|
self.current >= self.chars.len()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn advance(&mut self) -> char {
|
|
|
|
self.current += 1;
|
|
|
|
self.source.chars().collect::<Vec<char>>()[self.current - 1]
|
|
|
|
self.chars[self.current - 1]
|
|
|
|
}
|
|
|
|
|
|
|
|
fn add_token(&mut self, token_type: TokenType) {
|
|
|
|
if token_type == NoToken {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let text: String = self.source.chars().collect::<Vec<char>>()[self.start..self.current]
|
|
|
|
.iter()
|
|
|
|
.collect();
|
|
|
|
let text: String = self.chars[self.start..self.current].iter().collect();
|
|
|
|
self.tokens.push(Token::new(token_type, text, self.line));
|
|
|
|
}
|
|
|
|
|
|
|
@ -164,7 +163,7 @@ impl Scanner { |
|
|
|
if self.is_at_end() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if self.source.chars().collect::<Vec<char>>()[self.current] != expected {
|
|
|
|
if self.chars[self.current] != expected {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
@ -176,15 +175,15 @@ impl Scanner { |
|
|
|
if self.is_at_end() {
|
|
|
|
return '\0';
|
|
|
|
}
|
|
|
|
self.chars()[self.current]
|
|
|
|
self.chars[self.current]
|
|
|
|
}
|
|
|
|
|
|
|
|
fn peek_next(&self) -> char {
|
|
|
|
if self.current + 1 >= self.source.chars().count() {
|
|
|
|
if self.current + 1 >= self.chars.len() {
|
|
|
|
return '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
self.chars()[self.current + 1]
|
|
|
|
self.chars[self.current + 1]
|
|
|
|
}
|
|
|
|
|
|
|
|
fn string(&mut self) -> Result<(), (usize, String)> {
|
|
|
@ -202,7 +201,7 @@ impl Scanner { |
|
|
|
|
|
|
|
self.advance(); // Closing "
|
|
|
|
|
|
|
|
let value: String = self.chars()[(self.start + 1)..(self.current - 1)]
|
|
|
|
let value: String = self.chars[(self.start + 1)..(self.current - 1)]
|
|
|
|
.iter()
|
|
|
|
.collect();
|
|
|
|
self.add_token(TokenType::String(value));
|
|
|
@ -210,10 +209,6 @@ impl Scanner { |
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn chars(&self) -> Vec<char> {
|
|
|
|
self.source.chars().collect()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn number(&mut self) {
|
|
|
|
while Scanner::is_digit(self.peek()) {
|
|
|
|
self.advance();
|
|
|
@ -227,7 +222,7 @@ impl Scanner { |
|
|
|
} // Keep consuming digits
|
|
|
|
}
|
|
|
|
|
|
|
|
let s: String = self.chars()[self.start..self.current].iter().collect();
|
|
|
|
let s: String = self.chars[self.start..self.current].iter().collect();
|
|
|
|
self.add_token(Number(f64::from_str(&s).unwrap()))
|
|
|
|
}
|
|
|
|
|
|
|
@ -236,7 +231,7 @@ impl Scanner { |
|
|
|
self.advance();
|
|
|
|
}
|
|
|
|
|
|
|
|
let text: String = self.chars()[self.start..self.current].iter().collect();
|
|
|
|
let text: String = self.chars[self.start..self.current].iter().collect();
|
|
|
|
let token: TokenType = match KEYWORDS.get(text.as_str()) {
|
|
|
|
Some(x) => x.clone(),
|
|
|
|
None => Identifier,
|
|
|
|