Implementation of the UM-32 "Universal Machine" as described by the Cult of the Bound Variable
at main 52 lines 1.7 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// 15use std::{ 16 ffi::OsStr, 17 io, 18 path::{Path, PathBuf}, 19}; 20 21fn main() -> io::Result<()> { 22 let mut output = PathBuf::from("./a.um"); 23 24 let mut program = Vec::new(); 25 let mut args = std::env::args().skip(1); 26 while let Some(arg) = args.next() { 27 match arg.as_str() { 28 "-o" | "--out" => { 29 output = PathBuf::from(args.next().expect("expected output path")); 30 } 31 _ => { 32 let path = Path::new(&arg); 33 program.extend_from_slice(&load_program(path)?); 34 } 35 } 36 } 37 38 // Convert the program to bytes. 39 let bytes: Vec<_> = program.into_iter().flat_map(u32::to_be_bytes).collect(); 40 std::fs::write(&output, bytes) 41} 42 43fn load_program(path: &Path) -> io::Result<Vec<u32>> { 44 if let Some(b"uasm" | b"asm") = path.extension().map(OsStr::as_encoded_bytes) { 45 let source = std::fs::read_to_string(path)?; 46 let program = um::asm::assemble(&source); 47 Ok(program) 48 } else { 49 let program = std::fs::read(path)?; 50 Ok(um::conv::bytes_to_program(&program).unwrap()) 51 } 52}