2024-02-25 18:49:26 +00:00
|
|
|
use std::sync::PoisonError;
|
|
|
|
|
2024-03-06 20:36:58 +00:00
|
|
|
use ariadne::{Color, Label, Report, ReportKind};
|
|
|
|
use chumsky::{prelude::Rich, span::SimpleSpan};
|
2024-02-25 18:49:26 +00:00
|
|
|
|
2024-03-06 17:15:03 +00:00
|
|
|
use crate::{abstract_tree::Type, lexer::Token};
|
2024-02-25 18:49:26 +00:00
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
2024-03-06 20:36:58 +00:00
|
|
|
pub enum Error {
|
|
|
|
Parse {
|
|
|
|
expected: String,
|
|
|
|
found: Option<String>,
|
|
|
|
span: SimpleSpan,
|
|
|
|
},
|
|
|
|
Lex {
|
|
|
|
expected: String,
|
|
|
|
found: Option<char>,
|
|
|
|
span: SimpleSpan,
|
|
|
|
},
|
2024-02-25 18:49:26 +00:00
|
|
|
Runtime(RuntimeError),
|
|
|
|
}
|
|
|
|
|
2024-03-06 20:36:58 +00:00
|
|
|
impl Error {
|
|
|
|
pub fn report(&self, source: &str) -> Report {
|
|
|
|
match self {
|
|
|
|
Error::Parse {
|
|
|
|
expected,
|
|
|
|
found,
|
|
|
|
span,
|
|
|
|
} => Report::build(ReportKind::Custom("Parsing Error", Color::Red), (), 0).finish(),
|
|
|
|
Error::Lex {
|
|
|
|
expected,
|
|
|
|
found,
|
|
|
|
span,
|
|
|
|
} => Report::build(ReportKind::Custom("Lexing Error", Color::Red), (), 0)
|
|
|
|
.with_label(Label::new(span.start..span.end).with_message(format!(
|
|
|
|
"Exptected {expected} but found {}.",
|
|
|
|
found.unwrap_or(' '),
|
|
|
|
)))
|
|
|
|
.finish(),
|
|
|
|
Error::Runtime(_) => todo!(),
|
|
|
|
}
|
2024-02-25 18:49:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-06 20:36:58 +00:00
|
|
|
impl From<Rich<'_, char>> for Error {
|
|
|
|
fn from(error: Rich<'_, char>) -> Self {
|
|
|
|
Error::Lex {
|
|
|
|
expected: error.expected().map(|error| error.to_string()).collect(),
|
|
|
|
found: error.reason().found().map(|c| c.clone()),
|
|
|
|
span: error.span().clone(),
|
|
|
|
}
|
2024-02-25 18:49:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-06 20:36:58 +00:00
|
|
|
impl<'src> From<Rich<'_, Token<'src>>> for Error {
|
|
|
|
fn from(error: Rich<'_, Token<'src>>) -> Self {
|
|
|
|
Error::Parse {
|
|
|
|
expected: error.expected().map(|error| error.to_string()).collect(),
|
|
|
|
found: error.reason().found().map(|c| c.to_string()),
|
|
|
|
span: error.span().clone(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<RuntimeError> for Error {
|
2024-02-25 18:49:26 +00:00
|
|
|
fn from(error: RuntimeError) -> Self {
|
|
|
|
Error::Runtime(error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum RuntimeError {
|
|
|
|
RwLockPoison(RwLockPoisonError),
|
2024-02-29 02:04:38 +00:00
|
|
|
ValidationFailure(ValidationError),
|
2024-02-25 18:49:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl From<RwLockPoisonError> for RuntimeError {
|
|
|
|
fn from(error: RwLockPoisonError) -> Self {
|
|
|
|
RuntimeError::RwLockPoison(error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-29 02:04:38 +00:00
|
|
|
impl From<ValidationError> for RuntimeError {
|
|
|
|
fn from(error: ValidationError) -> Self {
|
|
|
|
RuntimeError::ValidationFailure(error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum ValidationError {
|
|
|
|
ExpectedBoolean,
|
2024-03-06 17:15:03 +00:00
|
|
|
RwLockPoison(RwLockPoisonError),
|
|
|
|
TypeCheck(TypeCheckError),
|
2024-02-29 02:04:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl From<RwLockPoisonError> for ValidationError {
|
|
|
|
fn from(error: RwLockPoisonError) -> Self {
|
|
|
|
ValidationError::RwLockPoison(error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-06 17:15:03 +00:00
|
|
|
impl From<TypeCheckError> for ValidationError {
|
|
|
|
fn from(error: TypeCheckError) -> Self {
|
|
|
|
ValidationError::TypeCheck(error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-25 18:49:26 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub struct RwLockPoisonError;
|
|
|
|
|
|
|
|
impl<T> From<PoisonError<T>> for RwLockPoisonError {
|
|
|
|
fn from(_: PoisonError<T>) -> Self {
|
|
|
|
RwLockPoisonError
|
|
|
|
}
|
|
|
|
}
|
2024-03-06 17:15:03 +00:00
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub struct TypeCheckError {
|
|
|
|
pub actual: Type,
|
|
|
|
pub expected: Type,
|
|
|
|
}
|