Implementation of the UM-32 "Universal Machine" as described by the Cult of the Bound Variable

refactor `Um::run()`

tjh e33f33cc 7fff4bb8

+27 -23
+27 -23
src/main.rs
··· 107 107 #[cfg(feature = "timing")] 108 108 let start = Instant::now(); 109 109 110 - loop { 111 - match self.ops[self.program_counter as usize] { 112 - Operation::ConditionalMove { a, b, c } => self.conditional_move(a, b, c), 113 - Operation::ArrayIndex { a, b, c } => self.array_index(a, b, c), 114 - Operation::ArrayAmendment { a, b, c } => self.array_amendment(a, b, c), 115 - Operation::Addition { a, b, c } => self.addition(a, b, c), 116 - Operation::Multiplication { a, b, c } => self.multiplication(a, b, c), 117 - Operation::Division { a, b, c } => self.division(a, b, c), 118 - Operation::NotAnd { a, b, c } => self.not_and(a, b, c), 119 - Operation::Halt => break, 120 - Operation::Allocation { b, c } => self.allocation(b, c), 121 - Operation::Abandonment { c } => self.abandonment(c), 122 - Operation::Output { c } => self.output(c), 123 - Operation::Input { c } => self.input(c), 124 - Operation::LoadProgram { b, c } => { 125 - self.load_program(b, c); 126 - continue; 127 - } 128 - Operation::Orthography { a, value } => self.orthography(a, value), 129 - Operation::IllegalInstruction => self.illegal_instruction(), 130 - } 131 - self.program_counter += 1; 132 - } 110 + while self.step() {} 133 111 134 112 #[cfg(feature = "timing")] 135 113 eprintln!("um complete: {:?}", start.elapsed()); 136 114 137 115 self 116 + } 117 + 118 + /// Steps one instruction. 119 + pub fn step(&mut self) -> bool { 120 + match self.ops[self.program_counter as usize] { 121 + Operation::ConditionalMove { a, b, c } => self.conditional_move(a, b, c), 122 + Operation::ArrayIndex { a, b, c } => self.array_index(a, b, c), 123 + Operation::ArrayAmendment { a, b, c } => self.array_amendment(a, b, c), 124 + Operation::Addition { a, b, c } => self.addition(a, b, c), 125 + Operation::Multiplication { a, b, c } => self.multiplication(a, b, c), 126 + Operation::Division { a, b, c } => self.division(a, b, c), 127 + Operation::NotAnd { a, b, c } => self.not_and(a, b, c), 128 + Operation::Halt => return false, 129 + Operation::Allocation { b, c } => self.allocation(b, c), 130 + Operation::Abandonment { c } => self.abandonment(c), 131 + Operation::Output { c } => self.output(c), 132 + Operation::Input { c } => self.input(c), 133 + Operation::LoadProgram { b, c } => { 134 + self.load_program(b, c); 135 + return true; 136 + } 137 + Operation::Orthography { a, value } => self.orthography(a, value), 138 + Operation::IllegalInstruction => self.illegal_instruction(), 139 + } 140 + self.program_counter += 1; 141 + true 138 142 } 139 143 140 144 /// Loads the value from the specified register.