use crate::object::Object;
use crate::token::{Token, Type, Location};
static mut HAD_ERROR: bool = false;
static mut HAD_RUNTIME_ERROR: bool = false;
pub fn did_error() -> bool {
unsafe { HAD_ERROR || HAD_RUNTIME_ERROR }
}
pub fn did_runtime_error() -> bool {
unsafe { HAD_RUNTIME_ERROR }
}
pub fn reset_error() {
unsafe {
HAD_ERROR = false;
HAD_RUNTIME_ERROR = false;
}
}
pub trait Error {
fn throw(&self);
}
#[derive(Debug)]
pub struct ScanError {
pub location: Location,
pub message: String,
}
impl Error for ScanError {
fn throw(&self) {
eprintln!(
"[line {line}:{column}] Error: {message}",
line = self.location.line + 1,
column = self.location.column + 1,
message = self.message
);
unsafe {
HAD_ERROR = true;
}
}
}
#[derive(Debug)]
pub struct ParseError {
pub token: Token,
pub message: String,
}
impl Error for ParseError {
fn throw(&self) {
if self.token.r#type == Type::EOF {
eprintln!(
"[line {line}:{column}] Error at end: {message}",
line = self.token.location.line + 1,
column = self.token.location.column + 1,
message = self.message
);
} else {
eprintln!(
"[line {line}:{column}] Error at '{lexeme}': {message}",
line = self.token.location.line + 1,
column = self.token.location.column + 1,
lexeme = self.token.lexeme,
message = self.message
);
}
unsafe {
HAD_ERROR = true;
}
}
}
#[derive(Debug)]
pub struct ResolveError {
pub token: Token,
pub message: String,
}
impl Error for ResolveError {
fn throw(&self) {
eprintln!(
"[line {line}:{column}] Error at '{lexeme}': {message}",
line = self.token.location.line + 1,
column = self.token.location.column + 1,
lexeme = self.token.lexeme,
message = self.message
);
unsafe {
HAD_ERROR = true;
}
}
}
#[derive(Debug)]
pub struct RuntimeError {
pub token: Token,
pub message: String,
}
impl Error for RuntimeError {
fn throw(&self) {
eprintln!(
"[line {line}:{column}] Error at '{lexeme}': {message}",
line = self.token.location.line + 1,
column = self.token.location.column + 1,
lexeme = self.token.lexeme,
message = self.message
);
unsafe {
HAD_RUNTIME_ERROR = true;
}
}
}
#[derive(Debug)]
pub struct ReturnError {
pub value: Object,
}
#[derive(Debug)]
pub struct BreakError;
#[derive(Debug)]
pub enum ReturnType {
Error(RuntimeError),
Return(ReturnError),
Break(BreakError),
}