Something went wrong. Try again.
Implementation of the UM-32 "Universal Machine" as described by the [Cult of the Bound Variable](http://boundvariable.org/)
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114// Copyright (C) 2025 Thom Hayward.//// This program is free software: you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free Software// Foundation, version 3.//// This program is distributed in the hope that it will be useful, but WITHOUT// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more// details.//// You should have received a copy of the GNU General Public License along with// this program. If not, see <https://www.gnu.org/licenses/>.//
/// A reference to a register of the UM-32.#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]pub enum Register { #[default] R0, R1, R2, R3, R4, R5, R6, R7,}
impl std::fmt::Display for Register { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "r{}", *self as u8) }}
impl Register { /// Create a [`Register`] from a register index. /// /// # Panics /// /// Panics if `index` is not in `0..8`. /// #[must_use] pub const fn from_u8(index: u8) -> Self { match index { 0 => Self::R0, 1 => Self::R1, 2 => Self::R2, 3 => Self::R3, 4 => Self::R4, 5 => Self::R5, 6 => Self::R6, 7 => Self::R7, _ => panic!("register index must be in range 0..8"), } }}
#[cfg(feature = "asm")]impl Register { /// Encode the register as the 'a' parameter of an encoded /// instruction (bits 6..=8). #[must_use] pub const fn encode_a(self) -> u32 { ((self as u32) & 0x7) << 6 }
/// Encode the register as the 'b' parameter of an encoded /// instruction (bits 3..=5). #[must_use] pub const fn encode_b(self) -> u32 { ((self as u32) & 0x7) << 3 }
/// Encode the register as the 'c' parameter of an encoded /// instruction (bits 0..=2). #[must_use] pub const fn encode_c(self) -> u32 { (self as u32) & 0x7 }
/// Encode the register as the 'a' parameter of an `Orthography` /// operation. /// /// This is *only* valid for `Orthography` operations. #[must_use] pub const fn encode_a_ortho(self) -> u32 { ((self as u32) & 0x7) << 25 }}
/// A set of registers.#[derive(Debug, Default)]pub struct Page([u32; 8]);
impl std::ops::Index<Register> for Page { type Output = u32; fn index(&self, index: Register) -> &Self::Output { &self.0[index as usize] }}
impl std::ops::IndexMut<Register> for Page { fn index_mut(&mut self, index: Register) -> &mut Self::Output { &mut self.0[index as usize] }}
impl From<[u32; 8]> for Page { fn from(value: [u32; 8]) -> Self { Self(value) }}