1use crate::values::{LambdaDef, PrimitiveValue, ReifiedIterableValue, Value};
2use anyhow::{Result, anyhow};
3use indexmap::IndexMap;
4use serde::{Deserialize, Serialize};
5use std::fmt::{self, Display, Formatter};
6use std::sync::LazyLock;
7
8pub static CONSTANTS: LazyLock<IndexMap<String, PrimitiveValue>> = LazyLock::new(|| {
9 let mut constants = IndexMap::new();
10 constants.insert(
11 String::from("pi"),
12 PrimitiveValue::Number(core::f64::consts::PI),
13 );
14 constants.insert(
15 String::from("e"),
16 PrimitiveValue::Number(core::f64::consts::E),
17 );
18 constants.insert(String::from("max_value"), PrimitiveValue::Number(f64::MAX));
19 constants.insert(
20 String::from("min_value"),
21 PrimitiveValue::Number(f64::MIN_POSITIVE),
22 );
23 constants
24});
25
26#[derive(Debug, Clone)]
27pub enum HeapValue {
28 List(Vec<Value>),
29 String(String),
30 Record(IndexMap<String, Value>),
31 Lambda(LambdaDef),
32}
33
34impl HeapValue {
35 pub fn get_type(&self) -> &str {
36 match self {
37 HeapValue::List(_) => "list",
38 HeapValue::String(_) => "string",
39 HeapValue::Record(_) => "record",
40 HeapValue::Lambda(_) => "function",
41 }
42 }
43
44 pub fn as_list(&self) -> Result<&Vec<Value>> {
45 match self {
46 HeapValue::List(list) => Ok(list),
47 _ => Err(anyhow!("expected a list, but got a {}", self.get_type())),
48 }
49 }
50
51 pub fn as_string(&self) -> Result<&str> {
52 match self {
53 HeapValue::String(string) => Ok(string),
54 _ => Err(anyhow!("expected a list, but got a {}", self.get_type())),
55 }
56 }
57
58 pub fn as_record(&self) -> Result<&IndexMap<String, Value>> {
59 match self {
60 HeapValue::Record(record) => Ok(record),
61 _ => Err(anyhow!("expected a list, but got a {}", self.get_type())),
62 }
63 }
64
65 pub fn as_lambda(&self) -> Result<&LambdaDef> {
66 match self {
67 HeapValue::Lambda(lambda) => Ok(lambda),
68 _ => Err(anyhow!("expected a list, but got a {}", self.get_type())),
69 }
70 }
71
72 pub fn as_iterable(&self) -> Result<ReifiedIterableValue<'_>> {
73 match self {
74 HeapValue::List(list) => Ok(ReifiedIterableValue::List(list)),
75 HeapValue::String(string) => Ok(ReifiedIterableValue::String(string)),
76 HeapValue::Record(record) => Ok(ReifiedIterableValue::Record(record)),
77 _ => Err(anyhow!(
78 "expected an iterable, but got a {}",
79 self.get_type()
80 )),
81 }
82 }
83}
84
85#[derive(Debug, Clone)]
86pub struct Heap {
87 values: Vec<HeapValue>,
88}
89
90impl Heap {
91 pub fn new() -> Self {
92 let mut s = Self { values: Vec::new() };
93 s.insert_record(
94 CONSTANTS
95 .clone()
96 .into_iter()
97 .map(|(k, v)| (k, v.into()))
98 .collect(),
99 );
100
101 s
102 }
103
104 pub fn insert(&mut self, value: HeapValue) -> usize {
105 self.values.push(value);
106
107 self.values.len() - 1
108 }
109
110 pub fn insert_list(&mut self, list: Vec<Value>) -> Value {
111 Value::List(ListPointer::new(self.insert(HeapValue::List(list))))
112 }
113
114 pub fn insert_string(&mut self, string: String) -> Value {
115 Value::String(StringPointer::new(self.insert(HeapValue::String(string))))
116 }
117
118 pub fn insert_record(&mut self, record: IndexMap<String, Value>) -> Value {
119 Value::Record(RecordPointer::new(self.insert(HeapValue::Record(record))))
120 }
121
122 pub fn insert_lambda(&mut self, lambda: LambdaDef) -> Value {
123 Value::Lambda(LambdaPointer::new(self.insert(HeapValue::Lambda(lambda))))
124 }
125
126 pub fn get(&self, id: usize) -> Option<&HeapValue> {
127 self.values.get(id)
128 }
129
130 pub fn get_mut(&mut self, id: usize) -> Option<&mut HeapValue> {
131 self.values.get_mut(id)
132 }
133}
134
135impl Default for Heap {
136 fn default() -> Self {
137 Self::new()
138 }
139}
140
141pub trait HeapPointer<'h> {
142 fn reify(&self, heap: &'h Heap) -> &'h HeapValue;
143 fn reify_mut(&self, heap: &'h mut Heap) -> &'h mut HeapValue;
144 fn get_type(&self) -> &str;
145}
146
147macro_rules! define_pointer {
148 ($name:ident, $type:literal) => {
149 #[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, PartialOrd)]
150 pub struct $name(usize);
151
152 impl $name {
153 pub fn new(index: usize) -> Self {
154 $name(index)
155 }
156
157 pub fn index(&self) -> usize {
158 self.0
159 }
160 }
161
162 impl<'h> HeapPointer<'h> for $name {
163 fn reify(&self, heap: &'h Heap) -> &'h HeapValue {
164 heap.get(self.0).expect("Dangling pointer!")
165 }
166
167 fn reify_mut(&self, heap: &'h mut Heap) -> &'h mut HeapValue {
168 heap.get_mut(self.0).expect("Dangling pointer!")
169 }
170
171 fn get_type(&self) -> &str {
172 $type
173 }
174 }
175
176 impl Display for $name {
177 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
178 write!(f, "{}@{}", $type, self.0)
179 }
180 }
181 };
182}
183
184define_pointer!(ListPointer, "list");
185define_pointer!(StringPointer, "string");
186define_pointer!(RecordPointer, "record");
187define_pointer!(LambdaPointer, "function");
188
189#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, PartialOrd)]
190pub enum IterablePointer {
191 List(ListPointer),
192 String(StringPointer),
193 Record(RecordPointer),
194}
195
196impl From<ListPointer> for IterablePointer {
197 fn from(pointer: ListPointer) -> Self {
198 IterablePointer::List(pointer)
199 }
200}
201
202impl From<StringPointer> for IterablePointer {
203 fn from(pointer: StringPointer) -> Self {
204 IterablePointer::String(pointer)
205 }
206}
207
208impl From<RecordPointer> for IterablePointer {
209 fn from(pointer: RecordPointer) -> Self {
210 IterablePointer::Record(pointer)
211 }
212}
213
214impl<'h> HeapPointer<'h> for IterablePointer {
215 fn get_type(&self) -> &str {
216 match self {
217 IterablePointer::List(pointer) => pointer.get_type(),
218 IterablePointer::String(pointer) => pointer.get_type(),
219 IterablePointer::Record(pointer) => pointer.get_type(),
220 }
221 }
222
223 fn reify(&self, heap: &'h Heap) -> &'h HeapValue {
224 match self {
225 IterablePointer::List(pointer) => pointer.reify(heap),
226 IterablePointer::String(pointer) => pointer.reify(heap),
227 IterablePointer::Record(pointer) => pointer.reify(heap),
228 }
229 }
230
231 fn reify_mut(&self, heap: &'h mut Heap) -> &'h mut HeapValue {
232 match self {
233 IterablePointer::List(pointer) => pointer.reify_mut(heap),
234 IterablePointer::String(pointer) => pointer.reify_mut(heap),
235 IterablePointer::Record(pointer) => pointer.reify_mut(heap),
236 }
237 }
238}
239
240impl Display for IterablePointer {
241 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
242 match self {
243 IterablePointer::List(pointer) => write!(f, "{}", pointer),
244 IterablePointer::String(pointer) => write!(f, "{}", pointer),
245 IterablePointer::Record(pointer) => write!(f, "{}", pointer),
246 }
247 }
248}