Scanner - String litterals
This commit is contained in:
parent
4e9e566a4f
commit
75dd3a2db2
1 changed files with 40 additions and 12 deletions
|
@ -59,7 +59,7 @@ impl Scanner {
|
||||||
} else {
|
} else {
|
||||||
self.add_token(TokenType::Slash)
|
self.add_token(TokenType::Slash)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
// Things that may be either alone or followed by '='
|
// Things that may be either alone or followed by '='
|
||||||
'!' => {
|
'!' => {
|
||||||
if self.is_match('=') {
|
if self.is_match('=') {
|
||||||
|
@ -67,33 +67,56 @@ impl Scanner {
|
||||||
} else {
|
} else {
|
||||||
self.add_token(TokenType::Bang)
|
self.add_token(TokenType::Bang)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
'=' => {
|
'=' => {
|
||||||
if self.is_match('=') {
|
if self.is_match('=') {
|
||||||
self.add_token(TokenType::EqualEqual)
|
self.add_token(TokenType::EqualEqual)
|
||||||
} else {
|
} else {
|
||||||
self.add_token(TokenType::Equal)
|
self.add_token(TokenType::Equal)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
'<' => {
|
'<' => {
|
||||||
if self.is_match('=') {
|
if self.is_match('=') {
|
||||||
self.add_token(TokenType::LessEqual)
|
self.add_token(TokenType::LessEqual)
|
||||||
} else {
|
} else {
|
||||||
self.add_token(TokenType::Less)
|
self.add_token(TokenType::Less)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
'>' => {
|
'>' => {
|
||||||
if self.is_match('=') {
|
if self.is_match('=') {
|
||||||
self.add_token(TokenType::GreaterEqual)
|
self.add_token(TokenType::GreaterEqual)
|
||||||
} else {
|
} else {
|
||||||
self.add_token(TokenType::Greater)
|
self.add_token(TokenType::Greater)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
// String litterals
|
||||||
|
'"' => self.string_litteral(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)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn string_litteral(&mut self, err_hdl: &mut ErrorHandler) {
|
||||||
|
loop {
|
||||||
|
let p = self.peek();
|
||||||
|
if p == '"' || self.is_at_end() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if p == '\n' {
|
||||||
|
self.line += 1;
|
||||||
|
}
|
||||||
|
self.advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.is_at_end() {
|
||||||
|
err_hdl.error(self.line, "unterminated string");
|
||||||
|
} else {
|
||||||
|
self.advance(); // Last '"'
|
||||||
|
let value = self.get_substring(self.start + 1, self.current - 1);
|
||||||
|
self.add_token(TokenType::String(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,12 +161,7 @@ impl Scanner {
|
||||||
|
|
||||||
/// Add a token to the output.
|
/// Add a token to the output.
|
||||||
fn add_token(&mut self, token_type: TokenType) {
|
fn add_token(&mut self, token_type: TokenType) {
|
||||||
let lexeme = self
|
let lexeme = self.get_substring(self.start, self.current);
|
||||||
.source
|
|
||||||
.chars()
|
|
||||||
.skip(self.start)
|
|
||||||
.take(self.current - self.start)
|
|
||||||
.collect::<String>();
|
|
||||||
let token = Token {
|
let token = Token {
|
||||||
token_type,
|
token_type,
|
||||||
lexeme,
|
lexeme,
|
||||||
|
@ -151,4 +169,14 @@ impl Scanner {
|
||||||
};
|
};
|
||||||
self.tokens.push(token)
|
self.tokens.push(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a substring from the source.
|
||||||
|
fn get_substring(&self, start: usize, end: usize) -> String {
|
||||||
|
assert!(start <= end);
|
||||||
|
self.source
|
||||||
|
.chars()
|
||||||
|
.skip(start)
|
||||||
|
.take(end - start)
|
||||||
|
.collect::<String>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue