forked from lix-project/lix
prim_mapAttrs: `f' must be evaluated lazily to avoid infinite recursion
This commit is contained in:
parent
aa64e95bc8
commit
627e28ba33
|
@ -1076,6 +1076,8 @@ void EvalState::callPrimOp(Value & fun, Value & arg, Value & v, const Pos & pos)
|
||||||
|
|
||||||
void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & pos)
|
void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & pos)
|
||||||
{
|
{
|
||||||
|
forceValue(fun, pos);
|
||||||
|
|
||||||
if (fun.type == tPrimOp || fun.type == tPrimOpApp) {
|
if (fun.type == tPrimOp || fun.type == tPrimOpApp) {
|
||||||
callPrimOp(fun, arg, v, pos);
|
callPrimOp(fun, arg, v, pos);
|
||||||
return;
|
return;
|
||||||
|
@ -1091,10 +1093,8 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po
|
||||||
auto & fun2 = *allocValue();
|
auto & fun2 = *allocValue();
|
||||||
fun2 = fun;
|
fun2 = fun;
|
||||||
/* !!! Should we use the attr pos here? */
|
/* !!! Should we use the attr pos here? */
|
||||||
forceValue(*found->value, pos);
|
|
||||||
Value v2;
|
Value v2;
|
||||||
callFunction(*found->value, fun2, v2, pos);
|
callFunction(*found->value, fun2, v2, pos);
|
||||||
forceValue(v2, pos);
|
|
||||||
return callFunction(v2, arg, v, pos);
|
return callFunction(v2, arg, v, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1181,7 +1181,6 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
|
||||||
if (fun.type == tAttrs) {
|
if (fun.type == tAttrs) {
|
||||||
auto found = fun.attrs->find(sFunctor);
|
auto found = fun.attrs->find(sFunctor);
|
||||||
if (found != fun.attrs->end()) {
|
if (found != fun.attrs->end()) {
|
||||||
forceValue(*found->value);
|
|
||||||
Value * v = allocValue();
|
Value * v = allocValue();
|
||||||
callFunction(*found->value, fun, *v, noPos);
|
callFunction(*found->value, fun, *v, noPos);
|
||||||
forceValue(*v);
|
forceValue(*v);
|
||||||
|
@ -1565,7 +1564,6 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context,
|
||||||
if (v.type == tAttrs) {
|
if (v.type == tAttrs) {
|
||||||
auto i = v.attrs->find(sToString);
|
auto i = v.attrs->find(sToString);
|
||||||
if (i != v.attrs->end()) {
|
if (i != v.attrs->end()) {
|
||||||
forceValue(*i->value, pos);
|
|
||||||
Value v1;
|
Value v1;
|
||||||
callFunction(*i->value, v, v1, pos);
|
callFunction(*i->value, v, v1, pos);
|
||||||
return coerceToString(pos, v1, context, coerceMore, copyToStore);
|
return coerceToString(pos, v1, context, coerceMore, copyToStore);
|
||||||
|
|
|
@ -1359,7 +1359,6 @@ static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args
|
||||||
/* Apply a function to every element of an attribute set. */
|
/* Apply a function to every element of an attribute set. */
|
||||||
static void prim_mapAttrs(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_mapAttrs(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceFunction(*args[0], pos);
|
|
||||||
state.forceAttrs(*args[1], pos);
|
state.forceAttrs(*args[1], pos);
|
||||||
|
|
||||||
state.mkAttrs(v, args[1]->attrs->size());
|
state.mkAttrs(v, args[1]->attrs->size());
|
||||||
|
@ -1368,7 +1367,7 @@ static void prim_mapAttrs(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
Value * vName = state.allocValue();
|
Value * vName = state.allocValue();
|
||||||
Value * vFun2 = state.allocValue();
|
Value * vFun2 = state.allocValue();
|
||||||
mkString(*vName, i.name);
|
mkString(*vName, i.name);
|
||||||
state.callFunction(*args[0], *vName, *vFun2, pos);
|
mkApp(*vFun2, *args[0], *vName);
|
||||||
mkApp(*state.allocAttr(v, i.name), *vFun2, *i.value);
|
mkApp(*state.allocAttr(v, i.name), *vFun2, *i.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue