able-script/ablescript/src/error.rs

90 lines
2.7 KiB
Rust
Raw Normal View History

use crate::{brian::InterpretError, lexer::Token};
2022-04-12 07:16:34 -05:00
use std::{fmt::Display, io, ops::Range};
#[derive(Debug)]
pub struct Error {
pub kind: ErrorKind,
pub span: Range<usize>,
}
#[derive(Debug)]
pub enum ErrorKind {
2022-07-01 17:27:38 -05:00
/// Parser expected token, but none was available
2022-07-01 17:22:40 -05:00
UnexpectedEoi,
2022-07-01 17:27:38 -05:00
/// Parser expected certain token, but other one appeared
UnexpectedToken(Token),
2022-07-01 17:27:38 -05:00
/// Attempted to assign to undefined variable
UnknownVariable(String),
2022-07-01 17:27:38 -05:00
/// Attempted to access banned variable
MeloVariable(String),
2022-07-01 17:27:38 -05:00
/// Breaking / re-starting loop outside loop
LoopOpOutsideLoop,
/// Rlyeh was executed but host interface's exit
/// doesn't exit the program
2022-07-01 17:17:29 -05:00
NonExitingRlyeh(i32),
2022-07-01 17:27:38 -05:00
/// Missing left-hand side expression in binary expression
MissingLhs,
2022-07-01 17:27:38 -05:00
/// Error when executing BF code
2022-05-06 10:25:50 -05:00
Brian(InterpretError),
2022-07-01 17:27:38 -05:00
/// IO Error
2022-05-06 10:25:50 -05:00
Io(io::Error),
}
impl Error {
pub fn new(kind: ErrorKind, span: Range<usize>) -> Self {
Self { kind, span }
}
2022-07-01 17:22:40 -05:00
/// Create an UnexpectedEoi error, where the EOI occurs at the
/// given index in the input.
pub fn unexpected_eoi(index: usize) -> Self {
Self::new(ErrorKind::UnexpectedEoi, index..index)
}
2021-04-27 06:48:56 -05:00
}
2021-07-13 13:54:27 -05:00
impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Error at range {}-{}: {}",
self.span.start, self.span.end, self.kind
)
}
}
impl std::error::Error for Error {}
impl Display for ErrorKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
2022-07-01 17:22:40 -05:00
ErrorKind::UnexpectedEoi => write!(f, "unexpected end of input"),
2021-12-29 17:06:46 -06:00
ErrorKind::UnexpectedToken(Token::Melo) => write!(f, "unexpected marten"),
2021-07-13 13:54:27 -05:00
ErrorKind::UnexpectedToken(token) => write!(f, "unexpected token {:?}", token),
ErrorKind::UnknownVariable(name) => write!(f, "unknown identifier \"{}\"", name),
ErrorKind::MeloVariable(name) => write!(f, "banned variable \"{}\"", name),
2022-07-01 17:27:38 -05:00
ErrorKind::LoopOpOutsideLoop => write!(
f,
"unable to perform loop operation (enough or and enough) outside a loop"
),
2022-07-01 17:17:29 -05:00
&ErrorKind::NonExitingRlyeh(code) => write!(f, "program exited with code {code}"),
2022-05-06 10:25:50 -05:00
ErrorKind::Brian(err) => write!(f, "brainfuck error: {}", err),
2021-07-13 13:54:27 -05:00
// TODO: give concrete numbers here.
ErrorKind::MissingLhs => write!(f, "missing expression before binary operation"),
2022-05-06 10:25:50 -05:00
ErrorKind::Io(err) => write!(f, "I/O error: {}", err),
2021-07-13 13:54:27 -05:00
}
}
}
impl From<io::Error> for ErrorKind {
fn from(e: io::Error) -> Self {
2022-05-06 10:25:50 -05:00
Self::Io(e)
}
}