···2020}
21212222type Platter = u32;
2323-type Register = u8;
2323+type Parameter = u8;
24242525#[derive(Clone, Copy, Debug, PartialEq, Eq)]
2626-enum Op {
2626+enum Operation {
2727 ConditionalMove {
2828- a: Register,
2929- b: Register,
3030- c: Register,
2828+ a: Parameter,
2929+ b: Parameter,
3030+ c: Parameter,
3131 },
3232 ArrayIndex {
3333- a: Register,
3434- b: Register,
3535- c: Register,
3333+ a: Parameter,
3434+ b: Parameter,
3535+ c: Parameter,
3636 },
3737 ArrayAmendment {
3838- a: Register,
3939- b: Register,
4040- c: Register,
3838+ a: Parameter,
3939+ b: Parameter,
4040+ c: Parameter,
4141 },
4242 Addition {
4343- a: Register,
4444- b: Register,
4545- c: Register,
4343+ a: Parameter,
4444+ b: Parameter,
4545+ c: Parameter,
4646 },
4747 Multiplication {
4848- a: Register,
4949- b: Register,
5050- c: Register,
4848+ a: Parameter,
4949+ b: Parameter,
5050+ c: Parameter,
5151 },
5252 Division {
5353- a: Register,
5454- b: Register,
5555- c: Register,
5353+ a: Parameter,
5454+ b: Parameter,
5555+ c: Parameter,
5656 },
5757 NotAnd {
5858- a: Register,
5959- b: Register,
6060- c: Register,
5858+ a: Parameter,
5959+ b: Parameter,
6060+ c: Parameter,
6161 },
6262 Halt,
6363 Allocation {
6464- b: Register,
6565- c: Register,
6464+ b: Parameter,
6565+ c: Parameter,
6666 },
6767 Abandonment {
6868- c: Register,
6868+ c: Parameter,
6969 },
7070 Output {
7171- c: Register,
7171+ c: Parameter,
7272 },
7373 Input {
7474- c: Register,
7474+ c: Parameter,
7575 },
7676 LoadProgram {
7777- b: Register,
7878- c: Register,
7777+ b: Parameter,
7878+ c: Parameter,
7979 },
8080 Orthography {
8181- a: Register,
8181+ a: Parameter,
8282 value: u32,
8383 },
8484 IllegalInstruction,
8585}
86868787-impl From<Platter> for Op {
8787+impl From<Platter> for Operation {
8888 fn from(value: Platter) -> Self {
8989- let a = ((value >> 6) & 0x07) as Register;
9090- let b = ((value >> 3) & 0x07) as Register;
9191- let c = ((value >> 0) & 0x07) as Register;
8989+ let a = ((value >> 6) & 0x07) as Parameter;
9090+ let b = ((value >> 3) & 0x07) as Parameter;
9191+ let c = ((value >> 0) & 0x07) as Parameter;
92929393 match value & 0xf0000000 {
9494 0x00000000 => Self::ConditionalMove { a, b, c },
···105105 0xb0000000 => Self::Input { c },
106106 0xc0000000 => Self::LoadProgram { b, c },
107107 0xd0000000 => {
108108- let a = ((value >> 25) & 0x07) as Register;
108108+ let a = ((value >> 25) & 0x07) as Parameter;
109109 let value = value & 0x01ffffff;
110110 Self::Orthography { a, value }
111111 }
···114114 }
115115}
116116117117-fn decode_ops(ops: &[Platter]) -> Vec<Op> {
118118- ops.iter().map(|encoded| Op::from(*encoded)).collect()
117117+fn decode_ops(ops: &[Platter]) -> Vec<Operation> {
118118+ ops.iter()
119119+ .map(|&encoded| Operation::from(encoded))
120120+ .collect()
119121}
120122121123#[derive(Default)]
···128130 memory: Vec<Vec<Platter>>,
129131 #[cfg(feature = "reclaim-memory")]
130132 free_blocks: Vec<Platter>,
131131- ops: Vec<Op>,
133133+ ops: Vec<Operation>,
132134 stdin: Option<Box<dyn std::io::Read>>,
133135 stdout: Option<Box<dyn std::io::Write>>,
134136}
135137136138impl Um {
137137- /// Construct a new Universal Machine with the specified program.
139139+ /// Initialise a Universal Machine with the specified program scroll.
138140 pub fn new(program: Vec<Platter>) -> Self {
139141 let ops = decode_ops(&program);
140142 Self {
···144146 }
145147 }
146148147147- /// Construct a new Universal Machine from a program represented in bytes.
149149+ /// Initialise a Universal Machine with a program read from a legacy
150150+ /// unsigned 8-bit character scroll.
148151 pub fn from_bytes(program: impl AsRef<[u8]>) -> Self {
149152 let bytes = program.as_ref();
150153 let mut program = Vec::with_capacity(bytes.len().div_ceil(size_of::<Platter>()));
···165168 Self::new(program)
166169 }
167170168168- /// Sets the output for the univeral machine.
171171+ /// Sets the output for the universal machine.
169172 pub fn stdout(mut self, stdout: impl std::io::Write + 'static) -> Self {
170173 self.stdout.replace(Box::new(stdout));
171174 self
···188191 //
189192 // The register A receives the value in register B,
190193 // unless the register C contains 0.
191191- Op::ConditionalMove { a, b, c } => {
194194+ Operation::ConditionalMove { a, b, c } => {
192195 if self.load_register(c) != 0 {
193196 self.save_register(a, self.load_register(b));
194197 }
···198201 //
199202 // The register A receives the value stored at offset
200203 // in register C in the array identified by B.
201201- Op::ArrayIndex { a, b, c } => {
204204+ Operation::ArrayIndex { a, b, c } => {
202205 let block = self.load_register(b);
203206 let offset = self.load_register(c);
204207 self.save_register(a, self.load_memory(block, offset));
···208211 //
209212 // The array identified by A is amended at the offset
210213 // in register B to store the value in register C.
211211- Op::ArrayAmendment { a, b, c } => {
214214+ Operation::ArrayAmendment { a, b, c } => {
212215 let block = self.load_register(a);
213216 let offset = self.load_register(b);
214217 let value = self.load_register(c);
···219222 //
220223 // The register A receives the value in register B plus
221224 // the value in register C, modulo 2^32.
222222- Op::Addition { a, b, c } => {
225225+ Operation::Addition { a, b, c } => {
223226 self.save_register(
224227 a,
225228 self.load_register(b).wrapping_add(self.load_register(c)),
···230233 //
231234 // The register A receives the value in register B times
232235 // the value in register C, modulo 2^32.
233233- Op::Multiplication { a, b, c } => {
236236+ Operation::Multiplication { a, b, c } => {
234237 self.save_register(
235238 a,
236239 self.load_register(b).wrapping_mul(self.load_register(c)),
···242245 // The register A receives the value in register B
243246 // divided by the value in register C, if any, where
244247 // each quantity is treated as an unsigned 32 bit number.
245245- Op::Division { a, b, c } => {
248248+ Operation::Division { a, b, c } => {
246249 self.save_register(
247250 a,
248251 self.load_register(b).wrapping_div(self.load_register(c)),
···255258 // either register B or register C has a 0 bit in that
256259 // position. Otherwise the bit in register A receives
257260 // the 0 bit.
258258- Op::NotAnd { a, b, c } => {
261261+ Operation::NotAnd { a, b, c } => {
259262 self.save_register(a, !(self.load_register(b) & self.load_register(c)));
260263 }
261264262265 // Operator #7. Halt.
263266 //
264267 // The universal machine stops computation.
265265- Op::Halt => break,
268268+ Operation::Halt => break,
266269267270 // Operator #8. Allocation.
268271 //
···272275 // holding the value 0. A bit pattern not consisting of
273276 // exclusively the 0 bit, and that identifies no other
274277 // active allocated array, is placed in the B register.
275275- Op::Allocation { b, c } => {
278278+ Operation::Allocation { b, c } => {
276279 let length = self.load_register(c);
277280 let index = self.allocate_memory(length);
278281 self.save_register(b, index);
···282285 //
283286 // The array identified by the register C is abandoned.
284287 // Future allocations may then reuse that identifier.
285285- Op::Abandonment { c } => {
288288+ Operation::Abandonment { c } => {
286289 let block = self.load_register(c);
287290 self.free_memory(block);
288291 }
···292295 // The value in the register C is displayed on the console
293296 // immediately. Only values between and including 0 and 255
294297 // are allowed.
295295- Op::Output { c } => {
298298+ Operation::Output { c } => {
296299 let value = self.load_register(c);
297300 if let Some(stdout) = self.stdout.as_mut() {
298301 let buffer = [(value & 0xff) as u8];
···308311 // If the end of input has been signaled, then the
309312 // register C is endowed with a uniform value pattern
310313 // where every place is pregnant with the 1 bit.
311311- Op::Input { c } => {
314314+ Operation::Input { c } => {
312315 if let Some(stdin) = self.stdin.as_mut() {
313316 let mut buffer = vec![0];
314317 match stdin.read_exact(&mut buffer) {
···333336 // The '0' array shall be the most sublime choice for
334337 // loading, and shall be handled with the utmost
335338 // velocity.
336336- Op::LoadProgram { b, c } => {
339339+ Operation::LoadProgram { b, c } => {
337340 let block = self.load_register(b);
338341339342 // Source array is always copied to array[0], but there
···352355 //
353356 // The value indicated is loaded into the register A
354357 // forthwith.
355355- Op::Orthography { a, value } => {
358358+ Operation::Orthography { a, value } => {
356359 self.save_register(a, value);
357360 }
358361359359- Op::IllegalInstruction => self.panic(),
362362+ Operation::IllegalInstruction => self.panic(),
360363 }
361364362365 self.program_counter += 1;
···367370 }
368371369372 /// Loads the value from the specified register.
370370- fn load_register(&self, index: Register) -> Platter {
373373+ fn load_register(&self, index: Parameter) -> Platter {
371374 assert!(index < 8, "register index out of bounds");
372375 self.registers[index as usize]
373376 }
374377375378 /// Saves a value to the specified register.
376376- fn save_register(&mut self, index: Register, value: Platter) {
379379+ fn save_register(&mut self, index: Parameter, value: Platter) {
377380 assert!(index < 8, "register index out of bounds");
378381 self.registers[index as usize] = value;
379382 }