use std::fmt::{
self,
Display,
Formatter,
};
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Instruction {
IncrementPointer,
DecrementPointer,
IncrementValue,
DecrementValue,
OutputValue,
InputValue,
JumpForward,
JumpBackward,
NoOp,
}
impl Instruction {
#[must_use]
pub const fn from_char(c: char) -> Self {
match c {
'>' => Self::IncrementPointer,
'<' => Self::DecrementPointer,
'+' => Self::IncrementValue,
'-' => Self::DecrementValue,
'.' => Self::OutputValue,
',' => Self::InputValue,
'[' => Self::JumpForward,
']' => Self::JumpBackward,
_ => Self::NoOp,
}
}
}
impl Display for Instruction {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match *self {
Self::IncrementPointer => write!(f, "INCPTR"),
Self::DecrementPointer => write!(f, "DECPTR"),
Self::IncrementValue => write!(f, "INCVAL"),
Self::DecrementValue => write!(f, "DECVAL"),
Self::OutputValue => write!(f, "OUTVAL"),
Self::InputValue => write!(f, "INPVAL"),
Self::JumpForward => write!(f, "JMPFWD"),
Self::JumpBackward => write!(f, "JMPBCK"),
Self::NoOp => write!(f, "NOOP"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_instruction_from_char() {
assert_eq!(Instruction::from_char('>'), Instruction::IncrementPointer);
assert_eq!(Instruction::from_char('<'), Instruction::DecrementPointer);
assert_eq!(Instruction::from_char('+'), Instruction::IncrementValue);
assert_eq!(Instruction::from_char('-'), Instruction::DecrementValue);
assert_eq!(Instruction::from_char('.'), Instruction::OutputValue);
assert_eq!(Instruction::from_char(','), Instruction::InputValue);
assert_eq!(Instruction::from_char('['), Instruction::JumpForward);
assert_eq!(Instruction::from_char(']'), Instruction::JumpBackward);
assert_eq!(Instruction::from_char(' '), Instruction::NoOp);
}
#[test]
fn test_instruction_display() {
assert_eq!(format!("{}", Instruction::IncrementPointer), "INCPTR");
assert_eq!(format!("{}", Instruction::DecrementPointer), "DECPTR");
assert_eq!(format!("{}", Instruction::IncrementValue), "INCVAL");
assert_eq!(format!("{}", Instruction::DecrementValue), "DECVAL");
assert_eq!(format!("{}", Instruction::OutputValue), "OUTVAL");
assert_eq!(format!("{}", Instruction::InputValue), "INPVAL");
assert_eq!(format!("{}", Instruction::JumpForward), "JMPFWD");
assert_eq!(format!("{}", Instruction::JumpBackward), "JMPBCK");
assert_eq!(format!("{}", Instruction::NoOp), "NOOP");
}
}