2024-01-20 13:04:58 +00:00
|
|
|
use std::fmt::{self, Display, Formatter};
|
|
|
|
|
2024-01-21 01:21:37 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-20 13:04:58 +00:00
|
|
|
pub enum SyntaxErr {
|
|
|
|
TraillingComma,
|
2024-01-21 01:21:37 +00:00
|
|
|
/// false for '(' true for ')'
|
|
|
|
UnmatchedParen(bool),
|
|
|
|
UnexpectedChar,
|
|
|
|
OutsideOp(String),
|
2024-01-21 12:36:38 +00:00
|
|
|
MemoryInvalidRegister,
|
2024-01-20 13:04:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for SyntaxErr {
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
|
|
|
match self {
|
|
|
|
SyntaxErr::TraillingComma => write!(f, "trailling comma"),
|
2024-01-21 01:21:37 +00:00
|
|
|
SyntaxErr::UnmatchedParen(_) => write!(f, "unmatched parenthesis"),
|
|
|
|
SyntaxErr::UnexpectedChar => write!(f, "unexpected character"),
|
|
|
|
SyntaxErr::OutsideOp(kind) => write!(f, "{kind} before opcode"),
|
2024-01-21 12:36:38 +00:00
|
|
|
SyntaxErr::MemoryInvalidRegister => write!(f, "invalid register"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SyntaxErr {
|
|
|
|
pub fn note(&self) -> String {
|
|
|
|
match self {
|
|
|
|
SyntaxErr::TraillingComma => "remove the final comma".to_string(),
|
|
|
|
SyntaxErr::UnmatchedParen(false) => "add ')' after the register name".to_string(),
|
|
|
|
SyntaxErr::UnmatchedParen(true) => "add '(' before the register name".to_string(),
|
|
|
|
SyntaxErr::UnexpectedChar => "ensure the input is well-formed".to_string(),
|
2024-01-21 16:31:36 +00:00
|
|
|
SyntaxErr::OutsideOp(_) => format!("add arguments after the opcode"),
|
2024-01-22 00:12:59 +00:00
|
|
|
SyntaxErr::MemoryInvalidRegister => {
|
|
|
|
"registers are either xN (N < 32 with no leading 0) or the standard aliases"
|
|
|
|
.to_string()
|
|
|
|
}
|
2024-01-20 13:04:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-21 01:21:37 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-20 13:04:58 +00:00
|
|
|
pub enum RuntimeErr {
|
|
|
|
InvalidRegister(String),
|
|
|
|
UnexpectedImmediate,
|
|
|
|
UnexpectedRegister,
|
|
|
|
InvalidOp(String),
|
|
|
|
InvalidOpArity(String, usize, usize),
|
2024-01-22 00:12:59 +00:00
|
|
|
InvalidType(String, String),
|
2024-01-20 13:04:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for RuntimeErr {
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
|
|
|
match self {
|
|
|
|
RuntimeErr::InvalidRegister(reg) => write!(f, "invalid register {}", reg),
|
|
|
|
RuntimeErr::UnexpectedImmediate => write!(f, "unexpected immediate"),
|
|
|
|
RuntimeErr::UnexpectedRegister => write!(f, "unexpected register"),
|
|
|
|
RuntimeErr::InvalidOp(op) => write!(f, "invalid operation {}", op),
|
2024-01-22 00:12:59 +00:00
|
|
|
RuntimeErr::InvalidOpArity(op, actual, expected) => write!(
|
2024-01-20 13:04:58 +00:00
|
|
|
f,
|
|
|
|
"invalid operation arity {} expected {} got {}",
|
|
|
|
op, expected, actual
|
|
|
|
),
|
2024-01-22 00:12:59 +00:00
|
|
|
RuntimeErr::InvalidType(actual, expected) => {
|
|
|
|
write!(f, "expected {}, got {}", expected, actual)
|
|
|
|
}
|
2024-01-20 13:04:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|