Refactor: Use Value::Closure enum variant

Previously, compiled closures were stored as `Value::Object` and then
downcasted. This commit introduces a dedicated `Value::Closure` enum
variant to represent compiled closures. This improves type safety and
simplifies handling of closures throughout the compiler and VM.

This change involves:
- Updating type definitions to use `Value::Closure`.
- Adjusting downcasting logic to directly access the `Closure` struct.
- Modifying `run_with_args` and `run_with_args_observed` to expect
  `Value::Closure` for tail-call targets.
- Refining the handling of closures in the `Optimizer` and `Inliner` for
  better type clarity.
This commit is contained in:
2026-03-22 19:41:23 +01:00
parent 6c37b0c64f
commit 843ee7dfed
7 changed files with 134 additions and 141 deletions
+3 -12
View File
@@ -668,13 +668,11 @@ impl Environment {
info.positional_count,
node.ty.stack_size,
));
let closure_obj: Rc<dyn Object> = closure;
return Rc::new(NativeFunction {
purity: Purity::Impure,
func: Rc::new(move |args| {
let mut vm = VM::new(root_values.clone());
match vm.run_with_args(closure_obj.clone(), args) {
match vm.run_with_args(closure.clone(), args) {
Ok(v) => v,
Err(e) => panic!("Myc Runtime Error: {}", e),
}
@@ -692,12 +690,7 @@ impl Environment {
Err(e) => panic!("Myc Runtime Error: {}", e),
};
if let Value::Object(obj) = &res
&& obj
.as_any()
.downcast_ref::<Closure>()
.is_some()
{
if let Value::Closure(obj) = &res {
match vm.run_with_args(obj.clone(), args) {
Ok(v) => v,
Err(e) => panic!("Myc Runtime Error (Closure): {}", e),
@@ -837,9 +830,7 @@ impl Environment {
// 2. Execute the root closure immediately to get the actual script result.
// All Myc scripts are wrapped in a parameterless lambda for consistency.
let mut final_result = result;
if let Ok(Value::Object(obj)) = &final_result
&& let Some(_closure) = obj.as_any().downcast_ref::<Closure>()
{
if let Ok(Value::Closure(obj)) = &final_result {
final_result = vm.run_with_args_observed(&mut observer, obj.clone(), &[]);
}