1use crate::tokens::{Token, TokenType};
2
3pub struct ErrorHandler {
4 pub had_errors: bool,
5 pub had_runtime_error: bool,
6 pub errors: Vec<String>,
7}
8
9impl ErrorHandler {
10 pub fn new() -> Self {
11 Self {
12 had_errors: false,
13 had_runtime_error: false,
14 errors: Vec::new(),
15 }
16 }
17
18 pub fn reset(&mut self) {
19 self.had_errors = false;
20 self.had_runtime_error = false;
21 self.errors = Vec::new()
22 }
23
24 pub fn merge(&mut self, other: &ErrorHandler) {
25 self.had_errors |= other.had_errors;
26 self.had_runtime_error |= other.had_runtime_error;
27 for err in &other.errors {
28 self.errors.push(err.clone());
29 }
30 }
31
32 pub fn error(&mut self, line: usize, msg: &str) {
33 self.report(line, "", msg);
34 }
35
36 pub fn error_token(&mut self, token: &Token, msg: &str) {
37 if token.token_type == TokenType::Eof {
38 self.report(token.line, "at end", msg);
39 } else if token.token_type == TokenType::Newline {
40 self.report(token.line - 1, "at newline", msg);
41 } else {
42 self.report(token.line, &format!("at '{}'", token.lexeme), msg);
43 }
44 }
45
46 pub fn runtime_error_token(&mut self, token: Token, msg: &str) {
47 self.had_runtime_error = true;
48 self.errors.push(format!("{}\n[line {}]", msg, token.line));
49 }
50
51 pub fn runtime_error(&mut self, line: usize, msg: &str) {
52 self.had_runtime_error = true;
53 self.report(line, "", msg);
54 }
55
56 fn report(&mut self, line: usize, location: &str, msg: &str) {
57 self.had_errors = true;
58 self.errors
59 .push(format!("[line {}] Error {}: {}", line, location, msg));
60 }
61}
62
63impl Default for ErrorHandler {
64 fn default() -> Self {
65 Self::new()
66 }
67}