1use std::collections::{BTreeMap, BTreeSet};
15
16use crate::value::Value;
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
24pub struct Address(usize);
25
26impl Address {
27 #[must_use]
29 pub fn value(&self) -> usize {
30 self.0
31 }
32}
33
34impl From<usize> for Address {
35 fn from(value: usize) -> Self {
36 Self(value)
37 }
38}
39
40impl std::fmt::Display for Address {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 write!(f, "#{}", self.0)
43 }
44}
45
46#[derive(Debug, Clone, PartialEq, Eq)]
48pub struct Heap {
49 cells: BTreeMap<Address, Value>,
50 next: usize,
51}
52
53impl Heap {
54 #[must_use]
56 pub fn empty() -> Self {
57 Self {
58 cells: BTreeMap::new(),
59 next: 0,
60 }
61 }
62
63 #[must_use]
65 pub fn len(&self) -> usize {
66 self.cells.len()
67 }
68
69 #[must_use]
71 pub fn is_empty(&self) -> bool {
72 self.cells.is_empty()
73 }
74
75 #[must_use]
77 pub fn contains(&self, address: Address) -> bool {
78 self.cells.contains_key(&address)
79 }
80
81 pub fn addresses(&self) -> impl Iterator<Item = Address> + '_ {
83 self.cells.keys().copied()
84 }
85
86 #[must_use]
89 pub fn alloc(&self, value: Value) -> (Self, Address) {
90 let addr = Address(self.next);
91 let cells: BTreeMap<Address, Value> = self
92 .cells
93 .iter()
94 .map(|(k, v)| (*k, v.clone()))
95 .chain(std::iter::once((addr, value)))
96 .collect();
97 (
98 Self {
99 cells,
100 next: self.next + 1,
101 },
102 addr,
103 )
104 }
105
106 #[must_use]
108 pub fn load(&self, address: Address) -> Option<&Value> {
109 self.cells.get(&address)
110 }
111
112 #[must_use]
115 pub fn store(&self, address: Address, value: Value) -> Option<Self> {
116 self.cells.contains_key(&address).then(|| {
117 let cells: BTreeMap<Address, Value> = self
118 .cells
119 .iter()
120 .filter(|(k, _)| **k != address)
121 .map(|(k, v)| (*k, v.clone()))
122 .chain(std::iter::once((address, value)))
123 .collect();
124 Self {
125 cells,
126 next: self.next,
127 }
128 })
129 }
130
131 #[must_use]
135 pub fn retain(&self, live: &BTreeSet<Address>) -> Self {
136 let cells: BTreeMap<Address, Value> = self
137 .cells
138 .iter()
139 .filter(|(k, _)| live.contains(k))
140 .map(|(k, v)| (*k, v.clone()))
141 .collect();
142 Self {
143 cells,
144 next: self.next,
145 }
146 }
147}
148
149impl Default for Heap {
150 fn default() -> Self {
151 Self::empty()
152 }
153}
154
155impl std::fmt::Display for Heap {
156 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
157 let entries = self
158 .cells
159 .iter()
160 .map(|(k, v)| format!("{k} = {v}"))
161 .collect::<Vec<_>>()
162 .join(", ");
163 write!(f, "[{entries}]")
164 }
165}