1use crate::{error::Error, heap::Heap, value::Value};
2
3pub struct Memory<V: Value, H: Heap<V>> {
5 root: V::Pointer,
6 heap: H,
7}
8
9impl<V: Value, H: Heap<V>> Memory<V, H> {
10 pub fn new(heap: H) -> Self {
12 Self {
13 root: Default::default(),
14 heap,
15 }
16 }
17
18 #[inline]
20 pub const fn root(&self) -> V::Pointer {
21 self.root
22 }
23
24 #[inline]
26 pub const fn set_root(&mut self, pointer: V::Pointer) {
27 self.root = pointer;
28 }
29
30 #[inline]
32 pub fn get(&self, index: usize) -> Result<V, Error> {
33 self.heap
34 .as_ref()
35 .get(index)
36 .copied()
37 .ok_or(Error::InvalidMemoryAccess)
38 }
39
40 #[inline]
42 pub fn set(&mut self, index: usize, value: V) -> Result<(), Error> {
43 *self
44 .heap
45 .as_mut()
46 .get_mut(index)
47 .ok_or(Error::InvalidMemoryAccess)? = value;
48
49 Ok(())
50 }
51
52 #[inline]
54 pub fn allocate(&mut self, car: V, cdr: V) -> Result<V::Pointer, Error> {
55 let mut cons = self.allocate_unchecked(car, cdr)?;
56
57 if self.is_out_of_memory() || cfg!(feature = "gc_always") {
58 self.collect_garbages(Some(&mut cons))?;
59 }
60
61 Ok(cons)
62 }
63
64 #[expect(clippy::unused_self)]
66 fn allocate_unchecked(&mut self, _car: V, _cdr: V) -> Result<V::Pointer, Error> {
67 Ok(Default::default())
68 }
69
70 #[expect(clippy::unused_self)]
72 const fn is_out_of_memory(&self) -> bool {
73 false
74 }
75
76 #[expect(clippy::unused_self)]
78 const fn collect_garbages(&mut self, _cons: Option<&mut V::Pointer>) -> Result<(), Error> {
79 Ok(())
80 }
81}