Add positional_count field to Lambda
This field is used for static optimization, determining if parameters are purely positional.
This commit is contained in:
+24
-4
@@ -231,15 +231,24 @@ impl Environment {
|
||||
/// Runtime: Execute the linked AST in the VM
|
||||
pub fn run(&self, node: &TypedNode) -> Result<Value, String> {
|
||||
let mut vm = VM::new(self.global_values.clone());
|
||||
let result = vm.run(node)?;
|
||||
let mut result = vm.run(node)?;
|
||||
|
||||
// Handle potential script body closure
|
||||
if let Value::Object(obj) = &result
|
||||
&& let Some(closure) = obj.as_any().downcast_ref::<crate::ast::vm::Closure>()
|
||||
{
|
||||
// Execute the script body
|
||||
return vm.run(&closure.function_node);
|
||||
result = vm.run(&closure.function_node)?;
|
||||
}
|
||||
|
||||
// IMPORTANT: Resolve any pending tail call requests from the top-level execution
|
||||
while let Value::TailCallRequest(payload) = result {
|
||||
let (next_obj, next_args) = *payload;
|
||||
if let Some(closure) = next_obj.as_any().downcast_ref::<crate::ast::vm::Closure>() {
|
||||
result = vm.run_with_args(closure, next_args)?;
|
||||
} else {
|
||||
return Err(format!("Tail call target is not a closure: {}", next_obj.type_name()));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
@@ -273,6 +282,17 @@ impl Environment {
|
||||
result = vm.run_with_observer(&mut observer, &closure.function_node);
|
||||
}
|
||||
|
||||
// Resolve top-level tail calls
|
||||
while let Ok(Value::TailCallRequest(payload)) = result {
|
||||
let (next_obj, next_args) = *payload;
|
||||
if let Some(closure) = next_obj.as_any().downcast_ref::<crate::ast::vm::Closure>() {
|
||||
result = vm.run_with_args_observed(&mut observer, closure, next_args);
|
||||
} else {
|
||||
result = Err(format!("Tail call target is not a closure: {}", next_obj.type_name()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok((result, observer.logs))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user