Implementation of the UM-32 "Universal Machine" as described by the Cult of the Bound Variable
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//
15const WORD_LEN: usize = std::mem::size_of::<u32>();
16
17#[derive(Debug)]
18pub struct InvalidProgram;
19
20/// Converts a byte slice to a program.
21///
22/// Returns `None` if the byte slice is not a multiple of 4 bytes in length.
23pub fn bytes_to_program(bytes: &[u8]) -> Result<Vec<u32>, InvalidProgram> {
24 if bytes.len().rem_euclid(WORD_LEN) != 0 {
25 return Err(InvalidProgram);
26 }
27
28 Ok(bytes
29 .chunks_exact(WORD_LEN)
30 .map(|word| u32::from_be_bytes(word.try_into().unwrap()))
31 .collect())
32}