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

use `&mut dyn` for `stdin` and `stdout`

tjh 3fd5707a 2677baf0

Changed files
+11 -10
src
+11 -10
src/main.rs
··· 1 1 #[cfg(feature = "smallvec")] 2 2 use smallvec::SmallVec; 3 + use std::io::{Read, Write}; 3 4 #[cfg(feature = "timing")] 4 5 use std::time::Instant; 5 6 use um::{Operation, Parameter, Platter}; ··· 15 16 } 16 17 17 18 Um::from_bytes(program) 18 - .stdout(std::io::stdout()) 19 - .stdin(std::io::stdin()) 19 + .stdout(&mut std::io::stdout()) 20 + .stdin(&mut std::io::stdin()) 20 21 .run(); 21 22 } 22 23 23 24 #[derive(Default)] 24 - pub struct Um { 25 + pub struct Um<'a> { 25 26 program_counter: Platter, 26 27 registers: [Platter; 8], 27 28 #[cfg(feature = "smallvec")] ··· 31 32 #[cfg(feature = "reclaim-memory")] 32 33 free_blocks: Vec<Platter>, 33 34 ops: Vec<Operation>, 34 - stdin: Option<Box<dyn std::io::Read>>, 35 - stdout: Option<Box<dyn std::io::Write>>, 35 + stdin: Option<&'a mut dyn Read>, 36 + stdout: Option<&'a mut dyn Write>, 36 37 } 37 38 38 - impl Um { 39 + impl<'a> Um<'a> { 39 40 /// Initialise a Universal Machine with the specified program scroll. 40 41 pub fn new(program: Vec<Platter>) -> Self { 41 42 let ops = um::decode_ops(&program); ··· 69 70 } 70 71 71 72 /// Sets the output for the universal machine. 72 - pub fn stdout(mut self, stdout: impl std::io::Write + 'static) -> Self { 73 - self.stdout.replace(Box::new(stdout)); 73 + pub fn stdout<T: Write>(mut self, stdout: &'a mut T) -> Self { 74 + self.stdout.replace(stdout); 74 75 self 75 76 } 76 77 77 78 /// Sets the input for the universal machine. 78 - pub fn stdin(mut self, stdin: impl std::io::Read + 'static) -> Self { 79 - self.stdin.replace(Box::new(stdin)); 79 + pub fn stdin<T: Read>(mut self, stdin: &'a mut T) -> Self { 80 + self.stdin.replace(stdin); 80 81 self 81 82 } 82 83