1use crate::object::Object;
2use crate::token::{Token, Type, Location};
3
4static mut HAD_ERROR: bool = false;
5static mut HAD_RUNTIME_ERROR: bool = false;
6
7pub fn did_error() -> bool {
9 unsafe { HAD_ERROR || HAD_RUNTIME_ERROR }
10}
11
12pub fn did_runtime_error() -> bool {
14 unsafe { HAD_RUNTIME_ERROR }
15}
16
17pub fn reset_error() {
20 unsafe {
21 HAD_ERROR = false;
22 HAD_RUNTIME_ERROR = false;
23 }
24}
25
26pub trait Error {
28 fn throw(&self);
30}
31
32#[derive(Debug)]
34pub struct ScanError {
35 pub location: Location,
36 pub message: String,
37}
38
39impl Error for ScanError {
40 fn throw(&self) {
41 eprintln!(
42 "[line {line}:{column}] Error: {message}",
43 line = self.location.line + 1,
44 column = self.location.column + 1,
45 message = self.message
46 );
47
48 unsafe {
49 HAD_ERROR = true;
50 }
51 }
52}
53
54#[derive(Debug)]
56pub struct ParseError {
57 pub token: Token,
58 pub message: String,
59}
60
61impl Error for ParseError {
62 fn throw(&self) {
63 if self.token.r#type == Type::EOF {
64 eprintln!(
65 "[line {line}:{column}] Error at end: {message}",
66 line = self.token.location.line + 1,
67 column = self.token.location.column + 1,
68 message = self.message
69 );
70 } else {
71 eprintln!(
72 "[line {line}:{column}] Error at '{lexeme}': {message}",
73 line = self.token.location.line + 1,
74 column = self.token.location.column + 1,
75 lexeme = self.token.lexeme,
76 message = self.message
77 );
78 }
79
80 unsafe {
81 HAD_ERROR = true;
82 }
83 }
84}
85
86#[derive(Debug)]
88pub struct ResolveError {
89 pub token: Token,
90 pub message: String,
91}
92
93impl Error for ResolveError {
94 fn throw(&self) {
95 eprintln!(
96 "[line {line}:{column}] Error at '{lexeme}': {message}",
97 line = self.token.location.line + 1,
98 column = self.token.location.column + 1,
99 lexeme = self.token.lexeme,
100 message = self.message
101 );
102
103 unsafe {
104 HAD_ERROR = true;
105 }
106 }
107}
108
109#[derive(Debug)]
111pub struct RuntimeError {
112 pub token: Token,
113 pub message: String,
114}
115
116impl Error for RuntimeError {
117 fn throw(&self) {
118 eprintln!(
119 "[line {line}:{column}] Error at '{lexeme}': {message}",
120 line = self.token.location.line + 1,
121 column = self.token.location.column + 1,
122 lexeme = self.token.lexeme,
123 message = self.message
124 );
125
126 unsafe {
127 HAD_RUNTIME_ERROR = true;
128 }
129 }
130}
131
132#[derive(Debug)]
135pub struct ReturnError {
136 pub value: Object,
137}
138
139#[derive(Debug)]
142pub struct BreakError;
143
144#[derive(Debug)]
146pub enum ReturnType {
147 Error(RuntimeError),
148 Return(ReturnError),
149 Break(BreakError),
150}