use std::borrow::Cow; use std::num::ParseIntError; use thiserror::Error; use crate::asm::data::{Mask, Register}; use crate::asm::data::literal::Label; use crate::asm::instr::Cond; /// csn_asm unified error type #[derive(Error, Debug)] pub enum CrsnError { #[error("S-expression syntax error: {0:?}")] PreParse(#[from] Box), #[error("Parse error: {0:?}")] Parse(Cow<'static, str>), #[error("Parse error in {1:?}: {0:?}")] ParseIn(Cow<'static, str>, sexp::Sexp), #[error("Assembler error: {0:?}")] Asm(AsmError), #[error("Architecture error: {0:?}")] Arch(ArchError), #[error(transparent)] Other(#[from] anyhow::Error), } impl From for CrsnError { fn from(e: ParseIntError) -> Self { CrsnError::Other(anyhow::anyhow!(e)) } } /// Error from the assembler stage (after parsing S-expressions and basic validation) #[derive(Error, Debug)] pub enum AsmError { #[error("Unknown instruction")] UnknownInstruction, #[error("Bad bit mask")] BadMask(Mask), #[error("Uneven operand size")] UnevenOperandSize(Mask, Mask), #[error("Value provided as output argument")] ValueAsOutput, #[error("Discard (_) provided as input argument")] DiscardAsValue, #[error("Conditional branch already defined for \"{0}\"")] ConditionalAlreadyUsed(Cond), #[error("Label \"{0:?}\" not defined")] LabelNotDefined(Label), #[error("Bad register type: {0}")] BadRegisterType(Register), } /// Architectural error - the code is syntactically OK, but cannot run #[derive(Error, Debug)] pub enum ArchError { #[error("Register {0} does not exist")] RegisterNotExist(Register), #[error("Register {0} is not writable")] RegisterNotWritable(Register), #[error("Register {0} is not readable")] RegisterNotReadable(Register), }