1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
use std::error::Error; use std::fmt; /// An error that could've occurred when performing a [μOp](enum.MicroOp.html). /// /// # Examples /// /// ``` /// # use pir_8_emu::isa::{GeneralPurposeRegister, SpecialPurposeRegister}; /// # use pir_8_emu::micro::{MicroOpPerformError, MicroOp}; /// # use pir_8_emu::vm::{Memory, Ports}; /// # let (mut memory, mut ports, mut registers, mut pc, mut sp, mut adr, mut ins) = /// # (Memory::new(), Ports::new(), GeneralPurposeRegister::defaults(), /// # SpecialPurposeRegister::new("Program Counter", "PC"), SpecialPurposeRegister::new("Stack Pointer", "SP"), /// # SpecialPurposeRegister::new("Memory Address", "ADR"), SpecialPurposeRegister::new("Instruction", "INS")); /// assert_eq!(MicroOp::StackPush.perform(&mut vec![], &mut memory, &mut ports, &mut registers, /// &mut pc, &mut sp, &mut adr, &mut ins), /// Err(MicroOpPerformError::MicrostackUnderflow)); /// ``` #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] pub enum MicroOpPerformError { /// The microstack had too few elements for the μOp being performed MicrostackUnderflow, /// The top of the microstack had a value outside the domain of the μOp being performed InvalidMicrostackTop(u8, &'static [u8]), } impl Error for MicroOpPerformError {} impl fmt::Display for MicroOpPerformError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { MicroOpPerformError::MicrostackUnderflow => f.write_str("μstack underflow"), MicroOpPerformError::InvalidMicrostackTop(actual, valid) => { write!(f, "Invalid top of the μstack: {:#04x}, expected any of: ", actual)?; write_expected(valid, f) } } } } fn write_expected(expected: &[u8], f: &mut fmt::Formatter<'_>) -> fmt::Result { for (i, x) in expected.iter().enumerate() { if i != 0 { f.write_str(", ")?; } write!(f, "{:#04x}", x)?; } Ok(()) }