Refactor map and record representation

Replaces the use of `BTreeMap` and `HashMap` for maps and records with
`Vec<(Keyword, Value)>` and `Vec<(Keyword, StaticType)>`. This
simplifies the data structure and allows for ordered iteration, which is
important for serialization and comparison.

Also updates the `unpack` function in `vm.rs` to handle records as well
as lists when destructuring.
This commit is contained in:
Michael Schimmel
2026-02-20 15:10:07 +01:00
parent 6ddc1c0a11
commit ca2c85a8a4
6 changed files with 60 additions and 37 deletions
+6 -8
View File
@@ -1,4 +1,4 @@
use std::collections::{HashMap, BTreeMap};
use std::collections::HashMap;
use std::rc::Rc;
use std::cell::RefCell;
use std::fmt;
@@ -66,7 +66,7 @@ pub enum Value {
Text(Rc<str>),
Keyword(Keyword),
List(Rc<Vec<Value>>),
Record(Rc<HashMap<Keyword, Value>>),
Record(Rc<Vec<(Keyword, Value)>>),
Function(Rc<dyn Fn(Vec<Value>) -> Value>),
Object(Rc<dyn Object>), // For compiled Closures and other opaque types
Cell(Rc<RefCell<Value>>), // Boxed value for captures
@@ -93,7 +93,7 @@ pub enum StaticType {
Tuple(Vec<StaticType>), // Heterogeneous fixed-size
Vector(Box<StaticType>, usize), // Homogeneous fixed-size
Matrix(Box<StaticType>, Vec<usize>), // Multi-dimensional homogeneous
Record(Rc<BTreeMap<Keyword, StaticType>>),
Record(Rc<Vec<(Keyword, StaticType)>>),
Function(Box<Signature>),
FunctionOverloads(Vec<Signature>),
Object(&'static str),
@@ -255,9 +255,9 @@ impl Value {
}
},
Value::Record(r) => {
let mut fields = BTreeMap::new();
let mut fields = Vec::with_capacity(r.len());
for (k, v) in r.iter() {
fields.insert(*k, v.static_type());
fields.push((*k, v.static_type()));
}
StaticType::Record(Rc::new(fields))
},
@@ -293,10 +293,8 @@ impl fmt::Display for Value {
write!(f, "]")
},
Value::Record(r) => {
let mut entries: Vec<_> = r.iter().collect();
entries.sort_by_key(|(k, _)| k.name());
write!(f, "{{")?;
for (i, (k, v)) in entries.iter().enumerate() {
for (i, (k, v)) in r.iter().enumerate() {
if i > 0 { write!(f, ", ")?; }
write!(f, ":{} {}", k.name(), v)?;
}