1#[derive(Debug)]
2pub struct Memory {
3 size: u16,
4 memory: Vec<u16>,
5 position: usize,
6 position_as_u16: u16,
7}
8
9#[derive(Debug)]
10pub enum MemoryError {
11 Overflow,
12 OutOfRange,
13}
14
15#[derive(Debug)]
16pub enum ShiftDirection {
17 Right,
18 Left,
19}
20
21impl Memory {
22 pub fn new(size: u16) -> Self {
23 Memory {
24 size,
25 memory: vec![0; size.into()],
26 position: 0,
27 position_as_u16: 0,
28 }
29 }
30
31 fn update_position(&mut self, new_value: u16) -> u16 {
32 self.position_as_u16 = new_value;
33 self.position = new_value.into();
34
35 new_value
36 }
37
38 pub fn write(&mut self, value: u16) -> u16 {
39 self.memory[self.position] = value;
40
41 value
42 }
43
44 pub fn add(&mut self, value: u16) -> Result<u16, MemoryError> {
45 let current = self.memory[self.position];
46
47 if let Some(result) = current.checked_add(value) {
48 self.memory[self.position] = result;
49 return Ok(result);
50 }
51
52 Err(MemoryError::Overflow)
53 }
54
55 pub fn add_modulo(&mut self, value: u16) -> u16 {
56 self.memory[self.position] ^= value;
57
58 value
59 }
60
61 fn shift(&mut self, value: u16, direction: ShiftDirection) -> Result<u16, MemoryError> {
62 match direction {
63 ShiftDirection::Left => match self.position_as_u16.checked_sub(value) {
64 Some(value) => Ok(self.update_position(value)),
65 None => Err(MemoryError::OutOfRange),
66 },
67 ShiftDirection::Right => match self.position_as_u16.checked_add(value) {
68 Some(value) => Ok(self.update_position(value)),
69 None => Err(MemoryError::OutOfRange),
70 },
71 }
72 }
73
74 pub fn shift_right(&mut self) -> Result<u16, MemoryError> {
75 self.shift(1, ShiftDirection::Right)
76 }
77
78 pub fn shift_left(&mut self) -> Result<u16, MemoryError> {
79 self.shift(1, ShiftDirection::Left)
80 }
81
82 fn rotate(&mut self, value: usize, direction: ShiftDirection) {
83 let guard: usize = self.size.into();
84
85 match direction {
86 ShiftDirection::Right => self.memory.rotate_right(value % guard),
87 ShiftDirection::Left => self.memory.rotate_left(value % guard),
88 }
89 }
90
91 pub fn shift_word_left(&mut self) {
92 self.rotate(1, ShiftDirection::Left)
93 }
94
95 pub fn shift_word_right(&mut self) {
96 self.rotate(1, ShiftDirection::Right)
97 }
98
99 #[allow(dead_code)]
100 pub fn get_size(&self) -> u16 {
101 self.size
102 }
103
104 pub fn memory_view(&self) -> Vec<u16> {
105 self.memory.clone()
106 }
107}
108
109impl IntoIterator for Memory {
110 type IntoIter = std::vec::IntoIter<u16>;
111 type Item = u16;
112
113 fn into_iter(self) -> Self::IntoIter {
114 self.memory.into_iter()
115 }
116}