refactor(tazjin/rlox): Thread through scanner errors

... and show them to users, very crudely.

Change-Id: If4491b14db1124313f6ab7e5fbfdce9fea501d11
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2193
Reviewed-by: tazjin <mail@tazj.in>
Tested-by: BuildkiteCI
This commit is contained in:
Vincent Ambo 2020-11-28 18:20:10 +01:00 committed by tazjin
parent af793325c0
commit 36cf7bef24
3 changed files with 29 additions and 9 deletions

View file

@ -10,6 +10,6 @@ pub struct Error {
pub kind: ErrorKind, pub kind: ErrorKind,
} }
pub fn report(loc: &str, err: &Error) { pub fn report(err: &Error) {
eprintln!("[line {}] Error {}: {:?}", err.line, loc, err.kind); eprintln!("[line {}] Error: {:?}", err.line, err.kind);
} }

View file

@ -1,9 +1,24 @@
use crate::scanner; use crate::errors::{report, Error};
use crate::scanner::{self, Token};
// Run some Lox code and print it to stdout // Run some Lox code and print it to stdout
pub fn run(code: &str) { pub fn run(code: &str) {
let chars: Vec<char> = code.chars().collect(); let chars: Vec<char> = code.chars().collect();
for token in scanner::scan(&chars) {
match scanner::scan(&chars) {
Ok(tokens) => print_tokens(tokens),
Err(errors) => report_errors(errors),
}
}
fn print_tokens<'a>(tokens: Vec<Token<'a>>) {
for token in tokens {
println!("{:?}", token); println!("{:?}", token);
} }
} }
fn report_errors(errors: Vec<Error>) {
for error in errors {
report(&error);
}
}

View file

@ -254,19 +254,18 @@ impl<'a> Scanner<'a> {
self.add_token(token_kind); self.add_token(token_kind);
} }
fn scan_tokens(mut self) -> Vec<Token<'a>> { fn scan_tokens(&mut self) {
while !self.is_at_end() { while !self.is_at_end() {
self.start = self.current; self.start = self.current;
self.scan_token(); self.scan_token();
} }
self.add_token(TokenKind::Eof); self.add_token(TokenKind::Eof);
return self.tokens;
} }
} }
pub fn scan<'a>(input: &'a [char]) -> Vec<Token<'a>> { pub fn scan<'a>(input: &'a [char]) -> Result<Vec<Token<'a>>, Vec<Error>> {
let scanner = Scanner { let mut scanner = Scanner {
source: &input, source: &input,
tokens: vec![], tokens: vec![],
errors: vec![], errors: vec![],
@ -275,5 +274,11 @@ pub fn scan<'a>(input: &'a [char]) -> Vec<Token<'a>> {
line: 0, line: 0,
}; };
return scanner.scan_tokens(); scanner.scan_tokens();
if !scanner.errors.is_empty() {
return Err(scanner.errors);
}
return Ok(scanner.tokens);
} }