use super::*;
impl<'a> crate::parser_runtime::ClosureCaller for Vm<'a> {
fn call_closure(&mut self, closure: Value, args: Vec<Value>) -> Result<Value, String> {
self.invoke_closure_value(closure, args)
.map_err(|e| format!("{e:?}"))
}
}
impl<'a> Vm<'a> {
pub fn invoke_closure_value(
&mut self,
closure: Value,
args: Vec<Value>,
) -> Result<Value, VmError> {
let (fn_id, captures) = match closure {
Value::Closure { fn_id, captures, .. } => (fn_id, captures),
other => return Err(VmError::TypeMismatch(
format!("invoke_closure_value: not a closure: {other:?}"))),
};
let mut combined = captures;
combined.extend(args);
self.invoke(fn_id, combined)
}
pub fn invoke_closure_1(&mut self, closure: Value, arg: Value) -> Result<Value, VmError> {
let (fn_id, mut combined) = match closure {
Value::Closure { fn_id, captures, .. } => (fn_id, captures),
other => return Err(VmError::TypeMismatch(
format!("invoke_closure_1: not a closure: {other:?}"))),
};
combined.push(arg);
self.invoke(fn_id, combined)
}
pub fn invoke_closure_2(&mut self, closure: Value, a: Value, b: Value) -> Result<Value, VmError> {
let (fn_id, mut combined) = match closure {
Value::Closure { fn_id, captures, .. } => (fn_id, captures),
other => return Err(VmError::TypeMismatch(
format!("invoke_closure_2: not a closure: {other:?}"))),
};
combined.push(a);
combined.push(b);
self.invoke(fn_id, combined)
}
}