Formatting
This commit is contained in:
+95
-31
@@ -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!(
|
||||
|
||||
Reference in New Issue
Block a user