feat: ref
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
use std::cell::OnceCell;
|
||||
|
||||
use ecow::EcoString;
|
||||
use itertools::Itertools;
|
||||
use rpds::HashTrieMap;
|
||||
@@ -40,19 +42,19 @@ impl From<ir::Param> for Param {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Func {
|
||||
pub env: Option<CapturedEnv>,
|
||||
pub env: OnceCell<CapturedEnv>,
|
||||
pub param: Param,
|
||||
pub opcodes: OpCodes,
|
||||
}
|
||||
|
||||
impl Func {
|
||||
pub fn call(self, vm: &VM, arg: Value) -> Result<Value> {
|
||||
pub fn call(&self, vm: &VM, arg: Value) -> Result<Value> {
|
||||
use Param::*;
|
||||
|
||||
let env = self.env.unwrap().released();
|
||||
let env = self.env.get().unwrap().clone().released();
|
||||
|
||||
match self.param {
|
||||
Ident(ident) => env.enter(HashTrieMap::new_sync().insert(ident.into(), arg)),
|
||||
match &self.param {
|
||||
Ident(ident) => env.enter(HashTrieMap::new_sync().insert(ident.clone().into(), arg)),
|
||||
Formals {
|
||||
formals,
|
||||
ellipsis,
|
||||
@@ -73,18 +75,18 @@ impl Func {
|
||||
for (formal, default) in formals {
|
||||
let arg = arg
|
||||
.select(formal.clone().into())
|
||||
.or_else(|| default.map(|idx| Value::Thunk(vm.get_thunk(idx))))
|
||||
.or_else(|| default.map(Value::ThunkRef))
|
||||
.unwrap();
|
||||
new.insert_mut(formal.into(), arg);
|
||||
new.insert_mut(formal.clone().into(), arg);
|
||||
}
|
||||
if let Some(alias) = alias {
|
||||
new.insert_mut(alias.into(), Value::AttrSet(arg));
|
||||
new.insert_mut(alias.clone().into(), Value::AttrSet(arg));
|
||||
}
|
||||
env.enter(new);
|
||||
}
|
||||
}
|
||||
|
||||
vm.eval(self.opcodes, env)
|
||||
vm.eval(self.opcodes.clone(), env)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user