116 lines
2.7 KiB
Rust

// © 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<Self, Error>
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<Register> for u16 {
fn from(value: Register) -> Self { value as u16 }
}
impl TryFrom<u16> for Register {
type Error = Error;
fn try_from(value: u16) -> Result<Self, Self::Error> {
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<Self, Self::Err> {
use Register::*;
match s {
"pc" => Ok(pc),
"sp" => Ok(sp),
"sr" => Ok(sr),
"cg" => Ok(cg),
_ => str::parse::<u16>(&s[1..]).map_err(|_| -> Self::Err { Error::NotARegister(s.into()) })?.try_into(),
}
}
}
impl From<Register> 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)) }
}