2021-12-12 19:59:43 +00:00
|
|
|
use std::fmt::{Debug, Display, Error, Formatter};
|
2021-12-03 21:13:19 +00:00
|
|
|
|
2021-12-29 17:12:58 +00:00
|
|
|
use super::PseudoOp;
|
2021-12-12 19:59:43 +00:00
|
|
|
use crate::tokens::MpsToken;
|
2021-12-03 21:13:19 +00:00
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct SyntaxError {
|
|
|
|
pub line: usize,
|
|
|
|
pub token: MpsToken,
|
2022-01-01 00:56:46 +00:00
|
|
|
pub got: Option<MpsToken>,
|
2021-12-03 21:13:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for SyntaxError {
|
|
|
|
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
2021-12-30 00:46:53 +00:00
|
|
|
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
|
|
|
|
),
|
|
|
|
}
|
2021-12-03 21:13:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MpsLanguageError for SyntaxError {
|
2021-12-12 19:59:43 +00:00
|
|
|
fn set_line(&mut self, line: usize) {
|
|
|
|
self.line = line
|
|
|
|
}
|
2021-12-03 21:13:19 +00:00
|
|
|
}
|
|
|
|
|
2022-01-17 01:55:46 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2021-12-03 21:13:19 +00:00
|
|
|
pub struct RuntimeError {
|
|
|
|
pub line: usize,
|
2021-12-29 17:12:58 +00:00
|
|
|
pub op: PseudoOp,
|
2021-12-03 21:13:19 +00:00
|
|
|
pub msg: String,
|
|
|
|
}
|
|
|
|
|
2022-01-31 20:30:37 +00:00
|
|
|
impl RuntimeError {
|
|
|
|
pub fn decompose(self) -> (RuntimeOp, RuntimeMsg) {
|
|
|
|
(RuntimeOp(self.op), RuntimeMsg(self.msg))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-03 21:13:19 +00:00
|
|
|
impl Display for RuntimeError {
|
|
|
|
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
|
|
|
write!(f, "{} (line {}): {}", &self.msg, &self.line, &self.op)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-02 20:53:57 +00:00
|
|
|
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 {}
|
|
|
|
|
2021-12-03 21:13:19 +00:00
|
|
|
impl MpsLanguageError for RuntimeError {
|
2021-12-12 19:59:43 +00:00
|
|
|
fn set_line(&mut self, line: usize) {
|
|
|
|
self.line = line
|
|
|
|
}
|
2021-12-03 21:13:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub trait MpsLanguageError: Display + Debug {
|
|
|
|
fn set_line(&mut self, line: usize);
|
|
|
|
}
|
2022-01-31 20:30:37 +00:00
|
|
|
|
|
|
|
// RuntimeError builder components
|
2022-02-02 20:53:57 +00:00
|
|
|
#[derive(Debug, Clone, Hash)]
|
2022-01-31 20:30:37 +00:00
|
|
|
pub struct RuntimeMsg(pub String);
|
|
|
|
|
|
|
|
impl RuntimeMsg {
|
|
|
|
pub fn with(self, op: RuntimeOp) -> RuntimeError {
|
|
|
|
RuntimeError {
|
|
|
|
line: 0,
|
|
|
|
op: op.0,
|
|
|
|
msg: self.0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-31 21:25:05 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2022-01-31 20:30:37 +00:00
|
|
|
pub struct RuntimeOp(pub PseudoOp);
|
|
|
|
|
|
|
|
impl RuntimeOp {
|
|
|
|
pub fn with(self, msg: RuntimeMsg) -> RuntimeError {
|
|
|
|
RuntimeError {
|
|
|
|
line: 0,
|
|
|
|
op: self.0,
|
|
|
|
msg: msg.0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|