From 29f1ead96cd4597a0e8bc3c9df88b95d7c33ba98 Mon Sep 17 00:00:00 2001 From: tjh <14987462+thomhayward@users.noreply.github.com> Date: Tue, 14 Jan 2025 16:37:40 +0000 Subject: [PATCH] remove `Platter` type --- src/asm.rs | 26 ++++++++--------- src/asm/lexer.rs | 8 ++--- src/asm/parse.rs | 6 ++-- src/bin/uasm.rs | 7 ++--- src/bin/um.rs | 8 ++--- src/lib.rs | 76 +++++++++++++++++++++++------------------------- 6 files changed, 63 insertions(+), 68 deletions(-) diff --git a/src/asm.rs b/src/asm.rs index dba95fb..ff1262a 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -1,7 +1,7 @@ mod lexer; mod parse; -use crate::{Platter, Register}; +use crate::Register; use lexer::Token; use parse::{Instruction, Node, NodeType, PragmaType}; use std::collections::HashMap; @@ -12,7 +12,7 @@ enum Section { Data, } -pub fn assemble<'s>(source: &'s str) -> Vec { +pub fn assemble<'s>(source: &'s str) -> Vec { let parsed = parse::parse("", source).unwrap(); let mut sections: HashMap>> = HashMap::new(); @@ -145,7 +145,7 @@ pub fn assemble<'s>(source: &'s str) -> Vec { Section::Data => data_offset + *offset, }; - 0xd0000000 | destination.encode_a_ortho() | encode_literal(value as Platter) + 0xd0000000 | destination.encode_a_ortho() | encode_literal(value as u32) } Instruction::LiteralMove { destination, @@ -165,7 +165,7 @@ pub fn assemble<'s>(source: &'s str) -> Vec { let encoded = match &pragma.payload { PragmaType::WideString { value } => { for byte in value.as_bytes() { - program.push(*byte as Platter); + program.push(*byte as u32); } Some(0) // terminating byte. } @@ -181,13 +181,13 @@ pub fn assemble<'s>(source: &'s str) -> Vec { program } -fn encode_literal(value: Platter) -> Platter { - const LITERAL_MAX: Platter = 0x1ffffff; +fn encode_literal(value: u32) -> u32 { + const LITERAL_MAX: u32 = 0x1ffffff; assert!(value <= LITERAL_MAX, "literal value exceeds available bits. value: {value} (0x{value:x}), max: {LITERAL_MAX} (0x{LITERAL_MAX:x})"); - value as Platter + value as u32 } -fn encode_standard(op: Platter, a: &Register, b: &Register, c: &Register) -> Platter { +fn encode_standard(op: u32, a: &Register, b: &Register, c: &Register) -> u32 { (op << 28) | a.encode_a() | b.encode_b() | c.encode_c() } @@ -210,11 +210,11 @@ mod tests { assert_eq!(ops[0], Operation::Orthography { a: R0, value: 1 }); let mut platters = program.into_iter().skip(1); - assert_eq!(platters.next(), Some('H' as Platter)); - assert_eq!(platters.next(), Some('e' as Platter)); - assert_eq!(platters.next(), Some('l' as Platter)); - assert_eq!(platters.next(), Some('l' as Platter)); - assert_eq!(platters.next(), Some('o' as Platter)); + assert_eq!(platters.next(), Some('H' as u32)); + assert_eq!(platters.next(), Some('e' as u32)); + assert_eq!(platters.next(), Some('l' as u32)); + assert_eq!(platters.next(), Some('l' as u32)); + assert_eq!(platters.next(), Some('o' as u32)); assert_eq!(platters.next(), Some(0)); assert_eq!(platters.next(), None); } diff --git a/src/asm/lexer.rs b/src/asm/lexer.rs index f5ada2f..e49da3d 100644 --- a/src/asm/lexer.rs +++ b/src/asm/lexer.rs @@ -1,4 +1,4 @@ -use crate::{Platter, Register}; +use crate::Register; use logos::{Lexer, Logos}; #[derive(Clone, Debug, Default, PartialEq, Eq)] @@ -43,7 +43,7 @@ pub enum Token<'source> { Here, #[regex(r#"(0x[a-fA-F0-9]+)|([0-9]+)"#, lex_number)] - Number(Platter), + Number(u32), #[token("\"", lex_string_literal)] String(&'source str), @@ -61,10 +61,10 @@ fn lex_label<'source>(lex: &mut Lexer<'source, Token<'source>>) -> &'source str &slice[..slice.len() - 1] } -fn lex_number<'source>(lex: &mut Lexer<'source, Token<'source>>) -> Platter { +fn lex_number<'source>(lex: &mut Lexer<'source, Token<'source>>) -> u32 { let slice = &lex.slice(); if slice.starts_with("0x") { - Platter::from_str_radix(slice.trim_start_matches("0x"), 16).unwrap() + u32::from_str_radix(slice.trim_start_matches("0x"), 16).unwrap() } else { slice.parse().unwrap() } diff --git a/src/asm/parse.rs b/src/asm/parse.rs index c0a2de3..84736c4 100644 --- a/src/asm/parse.rs +++ b/src/asm/parse.rs @@ -1,5 +1,5 @@ use super::Token; -use crate::{Platter, Register}; +use crate::Register; use logos::{Logos, Source}; use std::{borrow::Cow, collections::HashMap, iter::Peekable, ops::Range}; @@ -312,7 +312,7 @@ pub enum Instruction<'s> { /// Operation #13. LiteralMove { destination: Register, - literal: Platter, + literal: u32, }, Load { destination: Register, @@ -660,7 +660,7 @@ where } } -fn consume_number<'s, I>(tokens: &mut I) -> Result<(Platter, Range), Error> +fn consume_number<'s, I>(tokens: &mut I) -> Result<(u32, Range), Error> where I: Iterator, Range)>, { diff --git a/src/bin/uasm.rs b/src/bin/uasm.rs index 2976cb9..7552aa4 100644 --- a/src/bin/uasm.rs +++ b/src/bin/uasm.rs @@ -1,5 +1,4 @@ use std::path::{Path, PathBuf}; -use um::Platter; fn main() { let mut output = PathBuf::from("./a.um"); @@ -33,7 +32,7 @@ fn main() { std::fs::write(&output, bytes).unwrap(); } -fn load_program(path: &Path) -> std::io::Result> { +fn load_program(path: &Path) -> std::io::Result> { match path.extension().map(|ext| ext.as_encoded_bytes()) { Some(b"uasm") | Some(b"asm") => { let source = std::fs::read_to_string(path)?; @@ -43,8 +42,8 @@ fn load_program(path: &Path) -> std::io::Result> { _ => { let program = std::fs::read(path)?; Ok(program - .chunks_exact(std::mem::size_of::()) - .map(|pl| Platter::from_be_bytes(pl.try_into().unwrap())) + .chunks_exact(std::mem::size_of::()) + .map(|word| u32::from_be_bytes(word.try_into().unwrap())) .collect()) } } diff --git a/src/bin/um.rs b/src/bin/um.rs index d4dc9f9..0ec6adf 100644 --- a/src/bin/um.rs +++ b/src/bin/um.rs @@ -1,5 +1,5 @@ use std::{path::Path, time::Instant}; -use um::{Platter, Um}; +use um::Um; fn main() { let mut program = Vec::new(); @@ -32,7 +32,7 @@ fn main() { } } -fn load_program(path: &Path) -> std::io::Result> { +fn load_program(path: &Path) -> std::io::Result> { match path.extension().map(|ext| ext.as_encoded_bytes()) { Some(b"uasm") | Some(b"asm") => { let source = std::fs::read_to_string(path)?; @@ -41,8 +41,8 @@ fn load_program(path: &Path) -> std::io::Result> { _ => { let program = std::fs::read(path)?; Ok(program - .chunks_exact(std::mem::size_of::()) - .map(|pl| Platter::from_be_bytes(pl.try_into().unwrap())) + .chunks_exact(std::mem::size_of::()) + .map(|word| u32::from_be_bytes(word.try_into().unwrap())) .collect()) } } diff --git a/src/lib.rs b/src/lib.rs index 1392ff7..c0ba3c4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,8 +7,6 @@ use std::{ pub mod asm; pub mod str; -pub type Platter = u32; - /// A reference to a register of the UM-32. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] pub enum Register { @@ -32,28 +30,28 @@ impl std::fmt::Display for Register { impl Register { /// Encodes the register as the 'a' parameter of an encoded /// instruction (bits 6..=8). - fn encode_a(self) -> Platter { - ((self as Platter) & 0x7) << 6 + fn encode_a(self) -> u32 { + ((self as u32) & 0x7) << 6 } /// Encodes the register as the 'b' parameter of an encoded /// instruction (bits 3..=5). - fn encode_b(self) -> Platter { - ((self as Platter) & 0x7) << 3 + fn encode_b(self) -> u32 { + ((self as u32) & 0x7) << 3 } /// Encodes the register as the 'c' parameter of an encoded /// instruction (bits 0..=2). - fn encode_c(self) -> Platter { - (self as Platter) & 0x7 + fn encode_c(self) -> u32 { + (self as u32) & 0x7 } /// Encodes the register as the 'a' parameter of an `Orthography` /// operation. /// /// This is *only* valid for `Orthography` operations. - fn encode_a_ortho(self) -> Platter { - ((self as Platter) & 0x7) << 25 + fn encode_a_ortho(self) -> u32 { + ((self as u32) & 0x7) << 25 } fn from_u8(index: u8) -> Self { @@ -73,10 +71,10 @@ impl Register { /// A set of registers. #[derive(Debug, Default)] -struct Page([Platter; 8]); +struct Page([u32; 8]); impl ops::Index for Page { - type Output = Platter; + type Output = u32; #[inline(always)] fn index(&self, index: Register) -> &Self::Output { &self.0[index as usize] @@ -90,8 +88,8 @@ impl ops::IndexMut for Page { } } -impl From<[Platter; 8]> for Page { - fn from(value: [Platter; 8]) -> Self { +impl From<[u32; 8]> for Page { + fn from(value: [u32; 8]) -> Self { Self(value) } } @@ -234,9 +232,8 @@ enum Operation { IllegalInstruction, } -impl From for Operation { - #[inline] - fn from(value: Platter) -> Self { +impl From for Operation { + fn from(value: u32) -> Self { let a = Register::from_u8(((value >> 6) & 0x07) as u8); let b = Register::from_u8(((value >> 3) & 0x07) as u8); let c = Register::from_u8((value & 0x07) as u8); @@ -264,7 +261,7 @@ impl From for Operation { } } -fn decode_ops(ops: &[Platter]) -> Vec { +fn decode_ops(ops: &[u32]) -> Vec { ops.iter() .map(|&encoded| Operation::from(encoded)) .collect() @@ -295,18 +292,18 @@ compile_error!("16 bit architectures are unsupported"); // usize *may* be 16 bits, so only implement if it is 32 or 64 bits. #[cfg(any(target_pointer_width = "64", target_pointer_width = "32"))] -impl_into_index!(Platter); +impl_into_index!(u32); #[derive(Default)] pub struct Um<'a> { - pub program_counter: Platter, + pub program_counter: u32, registers: Page, /// Program memory, modelled as a `Vec` of `SmallVec`. /// /// Memory allocations greater than `SMALLVEC_SIZE` will incur a memory /// indirection penalty for every memory access within that block. - memory: Vec>, - free_blocks: Vec, + memory: Vec>, + free_blocks: Vec, /// Partially decoded operations cache. ops: Vec, stdin: Option<&'a mut dyn Read>, @@ -315,7 +312,7 @@ pub struct Um<'a> { impl<'a> Um<'a> { /// Initialise a Universal Machine with the specified program scroll. - pub fn new(program: Vec) -> Self { + pub fn new(program: Vec) -> Self { let ops = decode_ops(&program); Self { memory: vec![program.into()], @@ -328,13 +325,12 @@ impl<'a> Um<'a> { /// unsigned 8-bit character scroll. pub fn from_bytes(program: impl AsRef<[u8]> + 'a) -> Self { fn inner<'a>(bytes: &[u8]) -> Um<'a> { - let mut program = - Vec::with_capacity(bytes.len().div_ceil(std::mem::size_of::())); + let mut program = Vec::with_capacity(bytes.len().div_ceil(std::mem::size_of::())); // Split the program into platters. - let mut chunks = bytes.chunks_exact(std::mem::size_of::()); + let mut chunks = bytes.chunks_exact(std::mem::size_of::()); for word in &mut chunks { - program.push(Platter::from_be_bytes(unsafe { + program.push(u32::from_be_bytes(unsafe { // SAFETY: The `chunks_exact` iterator will *always* emit // a slice of the correct length. word.try_into().unwrap_unchecked() @@ -431,12 +427,12 @@ impl<'a> Um<'a> { // } /// Loads the value from the specified register. - fn load_register(&self, register: Register) -> Platter { + fn load_register(&self, register: Register) -> u32 { self.registers[register] } /// Saves a value to the specified register. - fn save_register(&mut self, register: Register, value: Platter) { + fn save_register(&mut self, register: Register, value: u32) { self.registers[register] = value; } @@ -499,10 +495,10 @@ impl<'a> Um<'a> { let mut buffer = vec![0]; match stdin.read_exact(&mut buffer) { Ok(()) => self.save_register(c, buffer[0] as u32), - Err(_) => self.save_register(c, Platter::MAX), + Err(_) => self.save_register(c, u32::MAX), } } else { - self.save_register(c, Platter::MAX); + self.save_register(c, u32::MAX); } } @@ -520,7 +516,7 @@ impl<'a> Um<'a> { self.program_counter = self.load_register(c); } - fn orthography(&mut self, a: Register, value: Platter) { + fn orthography(&mut self, a: Register, value: u32) { self.save_register(a, value); } @@ -535,14 +531,14 @@ impl<'a> Um<'a> { ) } - fn load_memory(&self, block: Platter, offset: Platter) -> Platter { + fn load_memory(&self, block: u32, offset: u32) -> u32 { let block = block.into_index(); let offset = offset.into_index(); assert!(block < self.memory.len() && offset < self.memory[block].len()); self.memory[block][offset] } - fn store_memory(&mut self, block: Platter, offset: Platter, value: Platter) { + fn store_memory(&mut self, block: u32, offset: u32, value: u32) { let block = block.into_index(); let offset = offset.into_index(); assert!(block < self.memory.len() && offset < self.memory[block].len()); @@ -552,7 +548,7 @@ impl<'a> Um<'a> { /// Duplicates a block of memory. /// /// The block is copied to the first block of memory. - fn duplicate_memory(&mut self, block: Platter) -> &[Platter] { + fn duplicate_memory(&mut self, block: u32) -> &[u32] { let block = block.into_index(); assert!(block < self.memory.len()); self.memory[0] = self.memory[block].clone(); @@ -560,18 +556,18 @@ impl<'a> Um<'a> { } /// Allocates a block of memory of the specified length. - fn allocate_memory(&mut self, length: Platter) -> Platter { + fn allocate_memory(&mut self, length: u32) -> u32 { if let Some(index) = self.free_blocks.pop() { self.memory[index.into_index()] = Self::new_block(length.into_index()); - index as Platter + index as u32 } else { self.memory.push(Self::new_block(length.into_index())); - (self.memory.len() - 1) as Platter + (self.memory.len() - 1) as u32 } } /// Frees a block of memory. - fn free_memory(&mut self, block: Platter) { + fn free_memory(&mut self, block: u32) { assert!(block.into_index() < self.memory.len()); self.free_blocks.push(block); self.memory[block.into_index()] = Self::new_block(0); @@ -580,7 +576,7 @@ impl<'a> Um<'a> { /// Creates a new block of memory. /// /// The block is initialised with `len` zeroes. - fn new_block(len: usize) -> SmallVec<[Platter; SMALLVEC_SIZE]> { + fn new_block(len: usize) -> SmallVec<[u32; SMALLVEC_SIZE]> { smallvec::smallvec![0; len] } } -- 2.51.2