Error state information

This commit is contained in:
Emmanuel BENOîT 2022-12-30 16:33:34 +01:00
parent 9d485a8c63
commit 7b8f15e072

View file

@ -1,8 +1,40 @@
use std::{env, fs, io::{self, Write}}; use std::{env, fs, io::{self, Write}, process::ExitCode};
/// Error handler. Can be used to print error messages; will also retain the
/// current error status.
#[derive(Default, Debug)]
struct ErrorHandler {
had_error: bool
}
impl ErrorHandler {
/// Check whether this handler reported an error.
pub fn had_error(&self) -> bool {
self.had_error
}
/// Report an error.
pub fn error(&mut self, line: usize, message: &str) {
self.report(line, "", message)
}
fn report(&mut self, line: usize, pos: &str, message: &str) {
self.had_error = true;
println!("[line {line}] Error{pos}: {message}")
}
}
/// Execute a script. /// Execute a script.
fn run(_source: String) { fn run(_source: String) -> ErrorHandler {
todo!(); let error_handler = ErrorHandler::default();
/*
let scanner = Scanner::new(source);
let tokens = scanner.scan_tokens();
for token in tokens {
println!("{}", token);
}
*/
error_handler
} }
/// Run the REPL. /// Run the REPL.
@ -14,28 +46,31 @@ fn run_prompt() {
print!("slox> "); print!("slox> ");
stdout.flush().unwrap(); stdout.flush().unwrap();
let n_read = stdin.read_line(&mut buffer).expect("Failed to read from stdin"); let n_read = stdin.read_line(&mut buffer).expect("Failed to read from stdin");
match n_read { let _ = match n_read {
0 => return, 0 => return,
_ => run(buffer.clone()), _ => run(buffer.clone()),
} };
} }
} }
/// Load a file and run the script it contains. /// Load a file and run the script it contains.
fn run_file(file: &str) { fn run_file(file: &str) -> ErrorHandler {
let contents = fs::read_to_string(file).expect(&format!("Could not load {}", file)); let contents = fs::read_to_string(file).expect(&format!("Could not load {}", file));
run(contents) run(contents)
} }
/// Main program. Either load a script from a file, or start the REPL. /// Main program. Either load a script from a file, or start the REPL.
fn main() { fn main() -> Result<(), ExitCode> {
let args: Vec<String> = env::args().skip(1).collect(); let args: Vec<String> = env::args().skip(1).collect();
let n_args = args.len(); let n_args = args.len();
if n_args == 0 { if n_args == 0 {
run_prompt() run_prompt()
} else if n_args == 1 { } else if n_args == 1 {
run_file(&args[0]); if run_file(&args[0]).had_error() {
return Err(ExitCode::from(65));
}
} else { } else {
println!("Usage: slox [script]"); println!("Usage: slox [script]");
} }
Ok(())
} }