Refactor Record and List to use TupleData
The `Value::List` and `Value::Record` variants have been consolidated into a single `Value::Tuple` variant. This new variant uses a `TupleData` struct to store values and an optional `Rc<Vec<Keyword>>` for keys, allowing it to represent both ordered lists/tuples and key-value records. This change simplifies the internal representation and improves performance by allowing schema sharing for records. It also includes updates to the compiler, runtime, and tests to reflect the new structure.
This commit is contained in:
@@ -112,7 +112,13 @@ impl RecordBuilder {
|
||||
}
|
||||
|
||||
pub fn build(self) -> Value {
|
||||
Value::Record(Rc::new(self.fields))
|
||||
let mut keys = Vec::with_capacity(self.fields.len());
|
||||
let mut values = Vec::with_capacity(self.fields.len());
|
||||
for (k, v) in self.fields {
|
||||
keys.push(k);
|
||||
values.push(v);
|
||||
}
|
||||
Value::make_record(keys, values)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,20 +201,26 @@ mod tests {
|
||||
}
|
||||
|
||||
// Check runtime behavior
|
||||
if let Value::Record(fields) = wrapped {
|
||||
let greet_fn = &fields.iter().find(|(k, _)| *k == Keyword::intern("greet")).unwrap().1;
|
||||
if let Value::Function(f) = greet_fn {
|
||||
let res = f(vec![]);
|
||||
if let Value::Text(s) = res {
|
||||
assert_eq!(&*s, "Hello Alice");
|
||||
if let Value::Tuple(t) = wrapped {
|
||||
if let Some(keys) = &t.keys {
|
||||
let idx = keys.iter().position(|k| *k == Keyword::intern("greet")).unwrap();
|
||||
let greet_fn = &t.values[idx];
|
||||
|
||||
if let Value::Function(f) = greet_fn {
|
||||
let res = f(vec![]);
|
||||
if let Value::Text(s) = res {
|
||||
assert_eq!(&*s, "Hello Alice");
|
||||
} else {
|
||||
panic!("Expected Text result");
|
||||
}
|
||||
} else {
|
||||
panic!("Expected Text result");
|
||||
panic!("Expected Function value for method");
|
||||
}
|
||||
} else {
|
||||
panic!("Expected Function value for method");
|
||||
panic!("Expected Record keys");
|
||||
}
|
||||
} else {
|
||||
panic!("Expected Record value");
|
||||
panic!("Expected Tuple value");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,15 +237,19 @@ mod tests {
|
||||
|
||||
if let Value::Function(f) = factory_val {
|
||||
let instance = f(vec![Value::Text("Bob".into()), Value::Int(40)]);
|
||||
if let Value::Record(fields) = instance {
|
||||
let greet_fn = &fields.iter().find(|(k, _)| *k == Keyword::intern("greet")).unwrap().1;
|
||||
if let Value::Function(gf) = greet_fn {
|
||||
let res = gf(vec![]);
|
||||
if let Value::Text(s) = res {
|
||||
assert_eq!(&*s, "Hello Bob");
|
||||
} else { panic!("Wrong return type"); }
|
||||
}
|
||||
} else { panic!("Factory should return Record"); }
|
||||
if let Value::Tuple(t) = instance {
|
||||
if let Some(keys) = &t.keys {
|
||||
let idx = keys.iter().position(|k| *k == Keyword::intern("greet")).unwrap();
|
||||
let greet_fn = &t.values[idx];
|
||||
|
||||
if let Value::Function(gf) = greet_fn {
|
||||
let res = gf(vec![]);
|
||||
if let Value::Text(s) = res {
|
||||
assert_eq!(&*s, "Hello Bob");
|
||||
} else { panic!("Wrong return type"); }
|
||||
}
|
||||
} else { panic!("Expected keys"); }
|
||||
} else { panic!("Factory should return Tuple/Record"); }
|
||||
} else { panic!("Factory is not a function"); }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user