xbasic/
error_handler.rs

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}