From bb076ee2ed6f98f9e81714ec039f48a911fe3fa0 Mon Sep 17 00:00:00 2001 From: Wesley Moore Date: Mon, 9 Dec 2019 17:20:03 +1100 Subject: [PATCH] Clean up memory hack --- 2019/src/computer.rs | 51 +++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/2019/src/computer.rs b/2019/src/computer.rs index 7bf36ee..e150743 100644 --- a/2019/src/computer.rs +++ b/2019/src/computer.rs @@ -1,6 +1,7 @@ use std::cell::RefCell; use std::collections::VecDeque; use std::convert::TryFrom; +use std::ops::{Index, IndexMut}; use std::rc::Rc; type Address = i64; @@ -37,10 +38,12 @@ pub enum ComputeResult { NeedsInput, } +struct Memory(Vec); + pub struct Computer { name: char, ip: i64, - memory: Vec, + memory: Memory, input: I, output: O, relative_base: i64, @@ -94,15 +97,11 @@ fn decode(mut instruction: i64) -> Instruction { let opcode = divmod(&mut instruction, 100); match opcode { - 1 => { - // let mode3 = divmod(&mut instruction, 10); - // Parameters that an instruction writes to will never be in immediate mode. - Instruction::Add( - Mode::from(divmod(&mut instruction, 10)), - Mode::from(divmod(&mut instruction, 10)), - Mode::from(divmod(&mut instruction, 10)), - ) - } + 1 => Instruction::Add( + Mode::from(divmod(&mut instruction, 10)), + Mode::from(divmod(&mut instruction, 10)), + Mode::from(divmod(&mut instruction, 10)), + ), 2 => Instruction::Multiply( Mode::from(divmod(&mut instruction, 10)), Mode::from(divmod(&mut instruction, 10)), @@ -139,14 +138,11 @@ where I: Input, O: Output, { - pub fn new(name: char, mut memory: Vec, input: I, output: O) -> Self { - // HACK - let mut buffer = vec![0; 64 * 1024 * 1024]; - memory.append(&mut buffer); + pub fn new(name: char, memory: Vec, input: I, output: O) -> Self { Computer { name, ip: 0, - memory, + memory: Memory(memory), input, output, relative_base: 0, @@ -289,6 +285,31 @@ impl From for Mode { } } +impl Index for Memory { + type Output = i64; + + fn index(&self, index: usize) -> &Self::Output { + if index >= self.0.len() { + // Out of range reads, read 0 + return &0; + } + + self.0.index(index) + } +} + +impl IndexMut for Memory { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + if index >= self.0.len() { + // Out of range write, need to expand to allow + let mut extra = vec![0; (index + 1) - self.0.len()]; + self.0.append(&mut extra); + } + + self.0.index_mut(index) + } +} + #[cfg(test)] mod tests { use super::*;