use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct SourceLocation {
pub line: usize,
pub col: usize,
}
impl fmt::Display for SourceLocation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "line {}, column {}", self.line, self.col)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AssemblerError {
LexerError {
message: String,
loc: SourceLocation,
},
ParserError {
message: String,
loc: SourceLocation,
},
SymbolError {
message: String,
loc: SourceLocation,
}, EncodingError {
message: String,
loc: SourceLocation,
}, IoError(String), MultipleErrors(Vec<AssemblerError>),
StdParseError(String),
}
impl fmt::Display for AssemblerError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AssemblerError::LexerError { message, loc } => {
write!(f, "Lexer Error at {}: {}", loc, message)
}
AssemblerError::ParserError { message, loc } => {
write!(f, "Parser Error at {}: {}", loc, message)
}
AssemblerError::SymbolError { message, loc } => {
write!(f, "Symbol Error near {}: {}", loc, message)
}
AssemblerError::EncodingError { message, loc } => {
write!(f, "Encoding Error near {}: {}", loc, message)
}
AssemblerError::IoError(msg) => write!(f, "I/O Error: {}", msg),
AssemblerError::StdParseError(msg) => write!(f, "Parse Error: {}", msg),
AssemblerError::MultipleErrors(errs) => {
writeln!(f, "Multiple errors found:")?;
for err in errs {
writeln!(f, "- {}", err)?;
}
Ok(())
}
}
}
}
impl std::error::Error for AssemblerError {}
pub fn err_lex(message: impl Into<String>, line: usize, col: usize) -> AssemblerError {
AssemblerError::LexerError {
message: message.into(),
loc: SourceLocation { line, col },
}
}
pub fn err_parse(message: impl Into<String>, line: usize, col: usize) -> AssemblerError {
AssemblerError::ParserError {
message: message.into(),
loc: SourceLocation { line, col },
}
}
pub fn err_symbol(message: impl Into<String>, line: usize, col: usize) -> AssemblerError {
AssemblerError::SymbolError {
message: message.into(),
loc: SourceLocation { line, col },
}
}
pub fn err_encoding(message: impl Into<String>, line: usize, col: usize) -> AssemblerError {
AssemblerError::EncodingError {
message: message.into(),
loc: SourceLocation { line, col },
}
}
pub fn err_io(message: impl Into<String>) -> AssemblerError {
AssemblerError::IoError(message.into())
}
pub fn err_multiple(errors: Vec<AssemblerError>) -> AssemblerError {
AssemblerError::MultipleErrors(errors)
}