1use std::ops::{Index, IndexMut};
4
5use crate::data::atomic::Word;
6use crate::data::composite::Array;
7use crate::data::identification::{Address, Area, Identifier};
8
9#[derive(Clone, Default, Debug)]
11pub struct Memory {
12 data: Vec<Word>,
13}
14
15#[derive(Debug)]
17pub enum MemoryError {
18 OutOfBounds { requested: usize, memory_len: usize },
20 CannotFree { trying_to_free: usize, memory_len: usize },
22}
23
24pub type MemoryResult<T> = Result<T, MemoryError>;
26
27impl Memory {
28 pub fn new() -> Self { Self::default() }
30
31 pub fn with_size(size: usize) -> Self {
33 let mut mem = Self::default();
34 mem.data.resize(size, Word::default());
35 mem
36 }
37
38 pub fn len(&self) -> usize { self.data.len() }
40
41 pub fn is_empty(&self) -> bool { self.data.is_empty() }
43
44 pub fn store(&mut self, address: Address, datum: Word) -> MemoryResult<()> {
46 if address.to_usize() >= self.data.len() {
47 Err(MemoryError::OutOfBounds { requested: address.to_usize(), memory_len: self.len() })
48 } else {
49 self.data[address.to_usize()] = datum;
50 Ok(())
51 }
52 }
53
54 pub fn load(&self, address: Address) -> MemoryResult<Word> {
56 if address.to_usize() >= self.data.len() {
57 Err(MemoryError::OutOfBounds { requested: address.to_usize(), memory_len: self.len() })
58 } else {
59 Ok(self.data[address.to_usize()])
60 }
61 }
62
63 pub fn array(&self, area: Area) -> MemoryResult<Array> {
65 let slice = self.slice(area)?;
66 Ok(Array::from(slice))
67 }
68
69 pub fn slice(&self, area: Area) -> MemoryResult<&[Word]> {
71 let start = area.start().to_usize();
72 let end = area.end().to_usize();
73 if start >= self.data.len() || end >= self.data.len() {
74 Err(MemoryError::OutOfBounds { requested: start.max(end), memory_len: self.len() })
75 } else {
76 Ok(&self.data[start..=end])
77 }
78 }
79
80 pub fn copy(&mut self, to: Address, data: Array) -> MemoryResult<()> {
82 let start = to.to_usize();
83 let end = start + data.len();
84 if start >= self.data.len() || end >= self.data.len() {
85 Err(MemoryError::OutOfBounds { requested: start.max(end), memory_len: self.len() })
86 } else {
87 let mut current = start;
88 for datum in data.iter() {
89 self.data[current] = *datum;
90 current += 1;
91 };
92 Ok(())
93 }
94 }
95
96 pub fn alloc(&mut self, additional_size: usize) {
98 self.data.resize(self.data.len() + additional_size, Word::default());
99 }
100
101 pub fn free(&mut self, sub_size: usize) -> MemoryResult<()> {
103 if sub_size > self.data.len() {
104 return Err(MemoryError::CannotFree { trying_to_free: sub_size, memory_len: self.len() });
105 }
106 self.data.resize(self.data.len() - sub_size, Word::default());
107 Ok(())
108 }
109}
110
111impl Index<Address> for Memory {
112 type Output = Word;
113 fn index(&self, index: Address) -> &Self::Output { &self.data[index.to_usize()] }
114}
115
116impl IndexMut<Address> for Memory {
117 fn index_mut(&mut self, index: Address) -> &mut Self::Output { &mut self.data[index.to_usize()] }
118}