use std::fmt::{self, Debug, Formatter};
use std::hash::{Hash};
pub use crate::util::{AsUsize};
array_index! {
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct Register(std::num::NonZeroU8) {
debug_name: "Register",
UInt: u8,
}
}
pub const REGISTERS: [Register; 12] = unsafe {[
Register::new_unchecked(0), Register::new_unchecked(1),
Register::new_unchecked(2), Register::new_unchecked(3),
Register::new_unchecked(4), Register::new_unchecked(5),
Register::new_unchecked(6), Register::new_unchecked(7),
Register::new_unchecked(8), Register::new_unchecked(9),
Register::new_unchecked(10), Register::new_unchecked(11),
]};
pub const GLOBAL: Register = REGISTERS[0];
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct Slot(pub usize);
impl Debug for Slot {
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
write!(f, "Slot({})", self.0)
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub enum Variable {
Register(Register),
Slot(Slot),
}
impl Debug for Variable {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
f.write_str(&match self {
Variable::Register(r) => format!("{:#?}", r),
Variable::Slot(s) => format!("{:#?}", s),
})
}
}
impl From<Register> for Variable {
fn from(v: Register) -> Self {
Variable::Register(v)
}
}
impl From<Slot> for Variable {
fn from(v: Slot) -> Self {
Variable::Slot(v)
}
}
impl TryFrom<Variable> for Register { type Error = Variable;
fn try_from(v: Variable) -> Result<Self, Self::Error> {
if let Variable::Register(r) = v { Ok(r) } else { Err(v) }
}
}
impl TryFrom<Variable> for Slot {
type Error = Variable;
fn try_from(v: Variable) -> Result<Self, Self::Error> {
if let Variable::Slot(s) = v { Ok(s) } else { Err(v) }
}
}
pub trait IntoVariable: Copy + Into<Variable> {}
impl<T: Copy + Into<Variable>> IntoVariable for T {}