muss/mps-interpreter/src/lang/error.rs
2022-02-03 16:56:42 -05:00

108 lines
2.3 KiB
Rust

use std::fmt::{Debug, Display, Error, Formatter};
use super::PseudoOp;
use crate::tokens::MpsToken;
#[derive(Debug)]
pub struct SyntaxError {
pub line: usize,
pub token: MpsToken,
pub got: Option<MpsToken>,
}
impl Display for SyntaxError {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
match &self.got {
Some(t) => write!(
f,
"SyntaxError (line {}): Expected {}, got {}",
&self.line, &self.token, t
),
None => write!(
f,
"SyntaxError (line {}): Expected {}, got nothing",
&self.line, &self.token
),
}
}
}
impl MpsLanguageError for SyntaxError {
fn set_line(&mut self, line: usize) {
self.line = line
}
}
#[derive(Debug, Clone)]
pub struct RuntimeError {
pub line: usize,
pub op: PseudoOp,
pub msg: String,
}
impl RuntimeError {
pub fn decompose(self) -> (RuntimeOp, RuntimeMsg) {
(RuntimeOp(self.op), RuntimeMsg(self.msg))
}
}
impl Display for RuntimeError {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
write!(f, "{} (line {}): {}", &self.msg, &self.line, &self.op)
}
}
impl std::hash::Hash for RuntimeError {
fn hash<H>(&self, state: &mut H)
where
H: std::hash::Hasher,
{
self.line.hash(state);
self.msg.hash(state);
}
}
impl std::cmp::PartialEq for RuntimeError {
fn eq(&self, other: &Self) -> bool {
self.line == other.line && self.msg == other.msg
}
}
impl std::cmp::Eq for RuntimeError {}
impl MpsLanguageError for RuntimeError {
fn set_line(&mut self, line: usize) {
self.line = line
}
}
pub trait MpsLanguageError: Display + Debug {
fn set_line(&mut self, line: usize);
}
// RuntimeError builder components
#[derive(Debug, Clone, Hash)]
pub struct RuntimeMsg(pub String);
impl RuntimeMsg {
pub fn with(self, op: RuntimeOp) -> RuntimeError {
RuntimeError {
line: 0,
op: op.0,
msg: self.0,
}
}
}
#[derive(Debug, Clone)]
pub struct RuntimeOp(pub PseudoOp);
impl RuntimeOp {
pub fn with(self, msg: RuntimeMsg) -> RuntimeError {
RuntimeError {
line: 0,
op: self.0,
msg: msg.0,
}
}
}