// © 2023 John Breaux //! A [`Register`] represents [one of the MSP430 processor's registers](https://mspgcc.sourceforge.net/manual/x82.html) use super::*; use std::str::FromStr; /// A [Register] epresents [one of the MSP430 processor's registers](https://mspgcc.sourceforge.net/manual/x82.html) #[allow(non_camel_case_types)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Register { /// Program Counter pc, /// Stack Pointer sp, /// Status Register sr, /// Constant Generator cg, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, } impl Parsable for Register { fn parse<'text, T>(_: &Parser, stream: &mut T) -> Result where T: crate::TokenStream<'text> { stream .expect(Type::Register) .map_err(|e: Error| e.context(stream.context()))? .lexeme() .parse() .map_err(|e: Error| e.context(stream.context())) } } impl From for u16 { fn from(value: Register) -> Self { value as u16 } } impl TryFrom for Register { type Error = Error; fn try_from(value: u16) -> Result { use Register::*; Ok(match value { 0 => pc, 1 => sp, 2 => sr, 3 => cg, 4 => r4, 5 => r5, 6 => r6, 7 => r7, 8 => r8, 9 => r9, 10 => r10, 11 => r11, 12 => r12, 13 => r13, 14 => r14, 15 => r15, _ => return Err(Error::RegisterTooHigh(value)), }) } } impl FromStr for Register { type Err = Error; fn from_str(s: &str) -> Result { use Register::*; match s { "pc" => Ok(pc), "sp" => Ok(sp), "sr" => Ok(sr), "cg" => Ok(cg), _ => str::parse::(&s[1..]).map_err(|_| -> Self::Err { Error::NotARegister(s.into()) })?.try_into(), } } } impl From for &str { fn from(value: Register) -> Self { use Register::*; match value { pc => "pc", sp => "sp", sr => "sr", cg => "cg", r4 => "r4", r5 => "r5", r6 => "r6", r7 => "r7", r8 => "r8", r9 => "r9", r10 => "r10", r11 => "r11", r12 => "r12", r13 => "r13", r14 => "r14", r15 => "r15", } } } impl std::fmt::Display for Register { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", <&str>::from(*self)) } }