Implementation of the UM-32 "Universal Machine" as described by the Cult of the Bound Variable
at main 81 lines 2.3 kB view raw
1// Copyright (C) 2025 Thom Hayward. 2// 3// This program is free software: you can redistribute it and/or modify it under 4// the terms of the GNU General Public License as published by the Free Software 5// Foundation, version 3. 6// 7// This program is distributed in the hope that it will be useful, but WITHOUT 8// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 9// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 10// details. 11// 12// You should have received a copy of the GNU General Public License along with 13// this program. If not, see <https://www.gnu.org/licenses/>. 14// 15 16#[cfg(feature = "asm")] 17mod asm; 18 19mod conv; 20mod ops; 21mod reg; 22mod universal_machine; 23 24use std::{path::Path, time::Instant}; 25 26use universal_machine::Um; 27 28fn main() { 29 let mut program = Vec::new(); 30 let mut time = false; 31 32 for arg in std::env::args().skip(1) { 33 if arg == "--time" { 34 time = true; 35 continue; 36 } 37 38 let path = Path::new(&arg); 39 program.extend_from_slice(&match load_program(path) { 40 Ok(p) => p, 41 Err(error) => { 42 eprintln!("{error}"); 43 std::process::exit(1); 44 } 45 }); 46 } 47 48 let start = Instant::now(); 49 Um::new(program) 50 .stdout(&mut std::io::stdout()) 51 .stdin(&mut std::io::stdin()) 52 .run(); 53 54 if time { 55 eprintln!("{:?}", start.elapsed()); 56 } 57} 58 59#[cfg(feature = "asm")] 60fn load_program(path: &Path) -> std::io::Result<Vec<u32>> { 61 match path.extension().map(|ext| ext.as_encoded_bytes()) { 62 // In an ideal world we would just add `#[cfg(feature = "asm")]` here. 63 // Unfortunately this leads some wierd code generation fuckery which 64 // makes the version without the 'asm' feature ~1-2 seconds slower 65 // when running the sandmark program. 66 Some(b"uasm" | b"asm") => { 67 let source = std::fs::read_to_string(path)?; 68 Ok(asm::assemble(&source)) 69 } 70 _ => { 71 let program = std::fs::read(path)?; 72 Ok(conv::bytes_to_program(&program).unwrap()) 73 } 74 } 75} 76 77#[cfg(not(feature = "asm"))] 78fn load_program(path: &Path) -> std::io::Result<Vec<u32>> { 79 let program = std::fs::read(path)?; 80 Ok(conv::bytes_to_program(&program).unwrap()) 81}