Add positional_count field to Lambda

This field is used for static optimization, determining if parameters
are purely positional.
This commit is contained in:
Michael Schimmel
2026-02-20 14:40:56 +01:00
parent 56d6c3bbde
commit 4e812c1afb
11 changed files with 361 additions and 62 deletions
+24 -4
View File
@@ -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))
}
}