Refactor: Implement Record Layouts and Optimized Field Access
Introduces a new `RecordLayout` system for efficient and type-safe record handling. Key changes: - `RecordLayout` struct with `O(1)` field lookup using FMap optimization. - Field accessors (`.name`) are now first-class callable values. - Parser recognizes dot-prefixed identifiers as field accessors. - Binder and TypeChecker handle field accessors. - Optimizer transforms field accessor calls into specialized `GetField` nodes. - VM executes `GetField` efficiently by directly accessing record values. - Adds a new `records.myc` example showcasing record features. - Improves comparison logic for records to use pointer equality for layout.
This commit is contained in:
@@ -112,6 +112,27 @@ impl Optimizer {
|
||||
)
|
||||
}
|
||||
|
||||
BoundKind::FieldAccessor(k) => (BoundKind::FieldAccessor(k), node.ty.clone()),
|
||||
|
||||
BoundKind::GetField { ref rec, field } => {
|
||||
let rec_opt = self.visit_node((**rec).clone(), sub, path);
|
||||
|
||||
// Constant folding for Field Access
|
||||
if let BoundKind::Constant(Value::Record(layout, values)) = &rec_opt.kind
|
||||
&& let Some(idx) = layout.index_of(field)
|
||||
{
|
||||
return folder.make_constant_node(values[idx].clone(), &node);
|
||||
}
|
||||
|
||||
(
|
||||
BoundKind::GetField {
|
||||
rec: Box::new(rec_opt),
|
||||
field,
|
||||
},
|
||||
node.ty.clone(),
|
||||
)
|
||||
}
|
||||
|
||||
BoundKind::Set { addr, value } => {
|
||||
let value = Box::new(self.visit_node(*value, sub, path));
|
||||
if let BoundKind::Constant(val) = &value.kind {
|
||||
@@ -175,6 +196,23 @@ impl Optimizer {
|
||||
let args = self.visit_node(*args, sub, path);
|
||||
|
||||
if self.enabled {
|
||||
// Optimized Field Access Transformation
|
||||
if let BoundKind::FieldAccessor(k) = &callee.kind
|
||||
&& let BoundKind::Tuple { elements } = &args.kind
|
||||
&& elements.len() == 1
|
||||
{
|
||||
let rec = elements[0].clone();
|
||||
let metrics = node.ty.clone();
|
||||
return Node {
|
||||
identity: node.identity,
|
||||
kind: BoundKind::GetField {
|
||||
rec: Box::new(rec),
|
||||
field: *k,
|
||||
},
|
||||
ty: metrics,
|
||||
};
|
||||
}
|
||||
|
||||
let mut arg_nodes = Vec::new();
|
||||
self.flatten_tuple(args.clone(), &mut arg_nodes);
|
||||
|
||||
@@ -542,11 +580,6 @@ impl Optimizer {
|
||||
self.flatten_tuple(el, into);
|
||||
}
|
||||
}
|
||||
BoundKind::Record { fields } => {
|
||||
for (_, v) in fields {
|
||||
self.flatten_tuple(v, into);
|
||||
}
|
||||
}
|
||||
BoundKind::Nop => {}
|
||||
_ => into.push(node),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user