Formatting

This commit is contained in:
Michael Schimmel
2026-03-02 23:13:36 +01:00
parent 5bc69c267b
commit 2eb7a2e136
22 changed files with 3212 additions and 2813 deletions
+95 -31
View File
@@ -177,7 +177,11 @@ impl VM {
}
}
pub fn run_with_args(&mut self, closure_obj: Rc<dyn Object>, args: Vec<Value>) -> Result<Value, String> {
pub fn run_with_args(
&mut self,
closure_obj: Rc<dyn Object>,
args: Vec<Value>,
) -> Result<Value, String> {
let closure = closure_obj.as_any().downcast_ref::<Closure>().unwrap();
self.stack.clear();
self.frames.clear();
@@ -323,29 +327,40 @@ impl VM {
// 2. Downcast! We check at runtime if the pointer actually points to a `RecordSeries`.
// `downcast_ref` is very fast (essentially an O(1) type ID comparison under the hood).
if let Some(record_series) = any_ptr.downcast_ref::<crate::ast::rtl::series::RecordSeries>() {
if let Some(record_series) =
any_ptr.downcast_ref::<crate::ast::rtl::series::RecordSeries>()
{
// 3. We call our highly performant 0-copy method on the series.
// It returns an `Rc<RefCell<dyn SeriesMember>>`, which is a shared pointer
// It returns an `Rc<RefCell<dyn SeriesMember>>`, which is a shared pointer
// to the concrete column array (e.g., a `ScalarSeries<f64>`).
if let Some(field_series) = record_series.field(*field) {
// 4. We wrap this RefCell in our `SeriesView` struct.
// The `SeriesView` acts as a pure `Object` for the VM, holding the reference.
// CRITICAL: No array elements are copied here! This is pure, fast pointer juggling.
// This single operation turns a SoA `RecordSeries` into a high-speed `FloatSeries` view.
let view = crate::ast::rtl::series::SeriesView::new(field_series, *field);
let view =
crate::ast::rtl::series::SeriesView::new(field_series, *field);
return Ok(Value::Object(std::rc::Rc::new(view)));
} else {
return Err(format!("RecordSeries does not have field :{}", field.name()));
return Err(format!(
"RecordSeries does not have field :{}",
field.name()
));
}
}
// Fallback if it's another type of object that is not a RecordSeries.
Err(format!("Attempt to access field on non-record object: {}", obj.type_name()))
Err(format!(
"Attempt to access field on non-record object: {}",
obj.type_name()
))
}
// Error handling for primitives (Int, Float, etc.).
_ => Err(format!("Attempt to access field on non-record: {}", rec_val)),
_ => Err(format!(
"Attempt to access field on non-record: {}",
rec_val
)),
}
}
@@ -413,11 +428,8 @@ impl VM {
});
// Delegate to the RTL Factory for specialized buffer instantiation
let node = crate::ast::rtl::streams::build_pipeline_node(
obs_streams,
executor,
out_type,
);
let node =
crate::ast::rtl::streams::build_pipeline_node(obs_streams, executor, out_type);
Ok(Value::Object(node))
}
@@ -489,23 +501,44 @@ impl VM {
if let Some(idx) = layout.index_of(k) {
return Ok(values[idx].clone());
} else {
return Err(format!("Record does not have field :{}", k.name()));
return Err(format!(
"Record does not have field :{}",
k.name()
));
}
} else if let Value::Object(obj) = rec {
// Polymorphic Field Access: Allow `.field` on a RecordSeries
if let Some(rs) = obj.as_any().downcast_ref::<crate::ast::rtl::series::RecordSeries>() {
if let Some(rs) = obj
.as_any()
.downcast_ref::<crate::ast::rtl::series::RecordSeries>()
{
if let Some(field_series) = rs.field(k) {
let view = crate::ast::rtl::series::SeriesView::new(field_series, k);
let view = crate::ast::rtl::series::SeriesView::new(
field_series,
k,
);
return Ok(Value::Object(std::rc::Rc::new(view)));
} else {
return Err(format!("RecordSeries does not have field :{}", k.name()));
return Err(format!(
"RecordSeries does not have field :{}",
k.name()
));
}
}
return Err(format!("Field accessor .{} expects a record or RecordSeries, got {}", k.name(), obj.type_name()));
return Err(format!(
"Field accessor .{} expects a record or RecordSeries, got {}",
k.name(),
obj.type_name()
));
} else {
return Err(format!("Field accessor .{} expects a record or RecordSeries, got {}", k.name(), rec));
return Err(format!(
"Field accessor .{} expects a record or RecordSeries, got {}",
k.name(),
rec
));
}
} _ => {
}
_ => {
return Err(format!(
"Tail call target is not a function: {}",
func_val
@@ -534,19 +567,37 @@ impl VM {
}
} else if let Value::Object(obj) = rec {
// Polymorphic Field Access: Allow `.field` on a RecordSeries
if let Some(rs) = obj.as_any().downcast_ref::<crate::ast::rtl::series::RecordSeries>() {
if let Some(rs) = obj
.as_any()
.downcast_ref::<crate::ast::rtl::series::RecordSeries>()
{
if let Some(field_series) = rs.field(k) {
let view = crate::ast::rtl::series::SeriesView::new(field_series, k);
let view = crate::ast::rtl::series::SeriesView::new(
field_series,
k,
);
break Ok(Value::Object(std::rc::Rc::new(view)));
} else {
break Err(format!("RecordSeries does not have field :{}", k.name()));
break Err(format!(
"RecordSeries does not have field :{}",
k.name()
));
}
}
break Err(format!("Field accessor .{} expects a record or RecordSeries, got {}", k.name(), obj.type_name()));
break Err(format!(
"Field accessor .{} expects a record or RecordSeries, got {}",
k.name(),
obj.type_name()
));
} else {
break Err(format!("Field accessor .{} expects a record or RecordSeries, got {}", k.name(), rec));
break Err(format!(
"Field accessor .{} expects a record or RecordSeries, got {}",
k.name(),
rec
));
}
} Value::Object(obj) => {
}
Value::Object(obj) => {
if let Some(closure) = obj.as_any().downcast_ref::<Closure>() {
let old_stack_top = self.stack.len();
self.frames.push(CallFrame {
@@ -586,11 +637,17 @@ impl VM {
// Unified Series Access (Step 1 of Dual Series Architecture)
// This handles RecordSeries, SeriesView, and future SharedSeries polymorphically.
if arg_vals.len() != 1 {
break Err(format!("{} indexer expects exactly 1 argument (the lookback index)", obj.type_name()));
break Err(format!(
"{} indexer expects exactly 1 argument (the lookback index)",
obj.type_name()
));
}
if let Value::Int(idx) = arg_vals[0] {
if idx < 0 {
break Err(format!("{} lookback index cannot be negative", obj.type_name()));
break Err(format!(
"{} lookback index cannot be negative",
obj.type_name()
));
}
if let Some(val) = series.get_item(idx as usize) {
break Ok(val);
@@ -599,12 +656,16 @@ impl VM {
break Ok(Value::Void);
}
} else {
break Err(format!("{} index must be an integer", obj.type_name()));
break Err(format!(
"{} index must be an integer",
obj.type_name()
));
}
} else {
break Err(format!("Object is not callable: {}", obj.type_name()));
}
} _ => break Err(format!("Attempt to call non-function: {}", func_val)),
}
_ => break Err(format!("Attempt to call non-function: {}", func_val)),
}
}
}
@@ -651,7 +712,10 @@ impl VM {
for v in values {
evaluated_values.push(self.eval_internal(obs, v)?);
}
Ok(Value::Record(layout.clone(), std::rc::Rc::new(evaluated_values)))
Ok(Value::Record(
layout.clone(),
std::rc::Rc::new(evaluated_values),
))
}
BoundKind::Expansion { bound_expanded, .. } => self.eval_internal(obs, bound_expanded),
BoundKind::Extension(ext) => Err(format!(