mapEnvBindings

This commit is contained in:
Ben Burdette 2021-06-11 18:55:15 -06:00
parent d22de1dd0c
commit 129dd760e6

View file

@ -618,6 +618,15 @@ std::optional<EvalState::Doc> EvalState::getDoc(Value & v)
typedef std::map<std::string, Value *> valmap; typedef std::map<std::string, Value *> valmap;
/*void addEnv(Value * v, valmap &vmap)
{
if (v.isThunk()) {
Env * env = v.thunk.env;
Expr * expr = v.thunk.expr;
}
*/
LocalNoInline(valmap * map0()) LocalNoInline(valmap * map0())
{ {
return new valmap(); return new valmap();
@ -628,17 +637,16 @@ LocalNoInline(valmap * map1(const char *name, Value *v))
return new valmap({{name, v}}); return new valmap({{name, v}});
} }
LocalNoInline(valmap * map2(const char *name1, Value *v1, const char *name2, Value *v2)) LocalNoInline(valmap * map2(const char *name1, Value *v1, const char *name2, Value *v2))
{ {
return new valmap({{name1, v1}, {name2, v2}}); return new valmap({{name1, v1}, {name2, v2}});
} }
LocalNoInline(valmap * mapBindings(Bindings *b)) LocalNoInline(valmap * mapBindings(Bindings &b))
{ {
auto map = new valmap(); auto map = new valmap();
for (auto i = b->begin(); i != b->end(); ++i) for (auto i = b.begin(); i != b.end(); ++i)
{ {
std::string s = i->name; std::string s = i->name;
(*map)[s] = i->value; (*map)[s] = i->value;
@ -647,6 +655,15 @@ LocalNoInline(valmap * mapBindings(Bindings *b))
return map; return map;
} }
LocalNoInline(valmap * mapEnvBindings(Env &env))
{
if (env.values[0]->type() == nAttrs) {
return mapBindings(*env.values[0]->attrs);
} else {
return map0();
}
}
/* Every "format" object (even temporary) takes up a few hundred bytes /* Every "format" object (even temporary) takes up a few hundred bytes
of stack space, which is a real killer in the recursive of stack space, which is a real killer in the recursive
evaluator. So here are some helper functions for throwing evaluator. So here are some helper functions for throwing
@ -813,13 +830,11 @@ LocalNoInline(void addErrorTrace(Error & e, const Pos & pos, const char * s, con
e.addTrace(pos, s, s2); e.addTrace(pos, s, s2);
} }
void mkString(Value & v, const char * s) void mkString(Value & v, const char * s)
{ {
v.mkString(dupString(s)); v.mkString(dupString(s));
} }
Value & mkString(Value & v, std::string_view s, const PathSet & context) Value & mkString(Value & v, std::string_view s, const PathSet & context)
{ {
v.mkString(dupStringWithLen(s.data(), s.size())); v.mkString(dupStringWithLen(s.data(), s.size()));
@ -862,7 +877,8 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval)
} }
if (!env->prevWith) if (!env->prevWith)
// TODO: env.attrs? // TODO: env.attrs?
throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, map0()); throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name,
mapEnvBindings(*env));
for (size_t l = env->prevWith; l; --l, env = env->up) ; for (size_t l = env->prevWith; l; --l, env = env->up) ;
} }
} }
@ -1171,7 +1187,8 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
Bindings::iterator j = v.attrs->find(nameSym); Bindings::iterator j = v.attrs->find(nameSym);
if (j != v.attrs->end()) if (j != v.attrs->end())
throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos, throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos,
map1("value", &v)); // TODO dynamicAttrs to env? mapEnvBindings(env));
// map1("value", &v)); // TODO dynamicAttrs to env?
i.valueExpr->setName(nameSym); i.valueExpr->setName(nameSym);
/* Keep sorted order so find can catch duplicates */ /* Keep sorted order so find can catch duplicates */
@ -1261,7 +1278,9 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
} else { } else {
state.forceAttrs(*vAttrs, pos); state.forceAttrs(*vAttrs, pos);
if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end()) if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end())
throwEvalError(pos, "attribute '%1%' missing", name, mapBindings(vAttrs->attrs)); throwEvalError(pos, "attribute '%1%' missing", name,
mapEnvBindings(env));
// mapBindings(*vAttrs->attrs));
} }
vAttrs = j->value; vAttrs = j->value;
pos2 = j->pos; pos2 = j->pos;
@ -1519,7 +1538,8 @@ this case it must have its arguments supplied either by default
values, or passed explicitly with '--arg' or '--argstr'. See values, or passed explicitly with '--arg' or '--argstr'. See
https://nixos.org/manual/nix/stable/#ss-functions.)", https://nixos.org/manual/nix/stable/#ss-functions.)",
i.name, i.name,
map1("fun", &fun)); // todo add bindings + fun mapBindings(args));
// map1("fun", &fun)); // todo add bindings + fun
} }
} }
} }
@ -1704,15 +1724,20 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
firstType = nFloat; firstType = nFloat;
nf = n; nf = n;
nf += vTmp.fpoint; nf += vTmp.fpoint;
} else } else {
throwEvalError(pos, "cannot add %1% to an integer", showType(vTmp), map0()); std::cerr << "envtype: " << showType(env.values[0]->type()) << std::endl;
throwEvalError(pos, "cannot add %1% to an integer", showType(vTmp),
mapEnvBindings(env));
}
} else if (firstType == nFloat) { } else if (firstType == nFloat) {
if (vTmp.type() == nInt) { if (vTmp.type() == nInt) {
nf += vTmp.integer; nf += vTmp.integer;
} else if (vTmp.type() == nFloat) { } else if (vTmp.type() == nFloat) {
nf += vTmp.fpoint; nf += vTmp.fpoint;
} else } else
throwEvalError(pos, "cannot add %1% to a float", showType(vTmp), map0()); throwEvalError(pos, "cannot add %1% to a float", showType(vTmp),
mapEnvBindings(env));
} else } else
s << state.coerceToString(pos, vTmp, context, false, firstType == nString); s << state.coerceToString(pos, vTmp, context, false, firstType == nString);
} }
@ -1871,10 +1896,10 @@ string EvalState::forceStringNoCtx(Value & v, const Pos & pos)
if (v.string.context) { if (v.string.context) {
if (pos) if (pos)
throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')",
v.string.s, v.string.context[0], map1("value", &v)); v.string.s, v.string.context[0], map1("value", &v));
else else
throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')",
v.string.s, v.string.context[0], map1("value", &v)); v.string.s, v.string.context[0], map1("value", &v));
} }
return s; return s;
} }