fix: PartialFunc
This commit is contained in:
@@ -12,5 +12,5 @@ use super::Value;
|
||||
pub struct PartialFunc {
|
||||
pub idx: usize,
|
||||
pub args: Vec<Value>,
|
||||
pub cache: HashMap<usize, Value>
|
||||
pub cache: HashMap<usize, Value>,
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use super::common::*;
|
||||
use super::public as p;
|
||||
|
||||
use crate::engine::Engine;
|
||||
use crate::env::{Env, VmEnvWeak};
|
||||
use crate::env::Env;
|
||||
use crate::error::*;
|
||||
|
||||
mod attrset;
|
||||
@@ -38,7 +38,7 @@ pub enum Value {
|
||||
PrimOp(Rc<PrimOp>),
|
||||
PartialPrimOp(Rc<PartialPrimOp>),
|
||||
Func(usize),
|
||||
PartialFunc(Rc<PartialFunc>)
|
||||
PartialFunc(Rc<PartialFunc>),
|
||||
}
|
||||
|
||||
impl Hash for Value {
|
||||
@@ -166,21 +166,30 @@ impl Value {
|
||||
PrimOp(func) => func.call(args, engine),
|
||||
PartialPrimOp(func) => func.call(args, engine),
|
||||
PartialFunc(func) => {
|
||||
let self::PartialFunc { idx, args: old_args, cache } = Rc::make_mut(func);
|
||||
let self::PartialFunc {
|
||||
idx,
|
||||
args: old_args,
|
||||
cache,
|
||||
} = Rc::make_mut(func);
|
||||
let idx = *idx;
|
||||
let len = args.len() + old_args.len();
|
||||
env.reserve_args(len);
|
||||
env.enter_args(std::mem::take(old_args));
|
||||
let mut args = args.into_iter().peekable();
|
||||
env.enter_arg(args.next().unwrap());
|
||||
let (ret, cache) = env.enter_cache_level(|env| {
|
||||
let (ret, cache) = env.with_cache(std::mem::take(cache), |env| {
|
||||
engine.eval_func_deps(idx, env)?;
|
||||
let mut ret = engine.eval_thunk(idx, env)?;
|
||||
while args.peek().is_some() {
|
||||
match ret {
|
||||
Value::Func(func) => {
|
||||
env.enter_arg(args.next().unwrap());
|
||||
engine.eval_func_deps(idx, env)?;
|
||||
ret = engine.eval_thunk(func, env)?;
|
||||
}
|
||||
Value::PartialFunc(_) => {
|
||||
todo!()
|
||||
}
|
||||
Value::PrimOp(primop) => {
|
||||
ret = primop.call(args.collect(), engine)?;
|
||||
break;
|
||||
@@ -207,15 +216,21 @@ impl Value {
|
||||
let len = args.len();
|
||||
let mut args = args.into_iter().peekable();
|
||||
env.reserve_args(len);
|
||||
let (ret, cache) = env.enter_cache_level(|env| {
|
||||
env.enter_arg(args.next().unwrap());
|
||||
let (ret, cache) = env.with_new_cache(|env| {
|
||||
engine.eval_func_deps(idx, env)?;
|
||||
let mut ret = engine.eval_thunk(idx, env)?;
|
||||
env.enter_arg(args.next().unwrap());
|
||||
ret.force(engine, env)?;
|
||||
while args.peek().is_some() {
|
||||
match ret {
|
||||
Value::Func(func) => {
|
||||
env.enter_arg(args.next().unwrap());
|
||||
engine.eval_func_deps(idx, env)?;
|
||||
ret = engine.eval_thunk(func, env)?;
|
||||
}
|
||||
Value::PartialFunc(mut func) => {
|
||||
todo!()
|
||||
}
|
||||
Value::PrimOp(primop) => {
|
||||
ret = primop.call(args.collect(), engine)?;
|
||||
break;
|
||||
@@ -481,7 +496,8 @@ impl Value {
|
||||
|
||||
pub fn force(&mut self, engine: &mut Engine, env: &mut Env) -> Result<&mut Self> {
|
||||
if let &mut Value::Thunk(idx) = self {
|
||||
*self = env.lookup_cache(idx, |env| engine.eval_thunk(idx, env))?
|
||||
// *self = env.lookup_cache(idx, |env| engine.eval_thunk(idx, env))?
|
||||
*self = env.lookup_cache(idx, |_| unreachable!())?
|
||||
}
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user