mirror of
https://github.com/NixOS/nix
synced 2025-06-26 15:51:15 +02:00
* Update autoCallFunction() and findAlongAttrPath().
This commit is contained in:
parent
9a64454faa
commit
af2a372bb0
10 changed files with 120 additions and 188 deletions
|
@ -260,6 +260,12 @@ void EvalState::mkAttrs(Value & v)
|
|||
}
|
||||
|
||||
|
||||
void EvalState::mkThunk_(Value & v, Expr expr)
|
||||
{
|
||||
mkThunk(v, baseEnv, expr);
|
||||
}
|
||||
|
||||
|
||||
void EvalState::cloneAttrs(Value & src, Value & dst)
|
||||
{
|
||||
mkAttrs(dst);
|
||||
|
@ -625,6 +631,37 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v)
|
|||
}
|
||||
|
||||
|
||||
void EvalState::autoCallFunction(const Bindings & args, Value & fun, Value & res)
|
||||
{
|
||||
forceValue(fun);
|
||||
|
||||
ATerm name;
|
||||
ATermList formals;
|
||||
ATermBool ellipsis;
|
||||
|
||||
if (fun.type != tLambda || !matchAttrsPat(fun.lambda.pat, formals, ellipsis, name)) {
|
||||
res = fun;
|
||||
return;
|
||||
}
|
||||
|
||||
Value actualArgs;
|
||||
mkAttrs(actualArgs);
|
||||
|
||||
for (ATermIterator i(formals); i; ++i) {
|
||||
Expr name, def; ATerm def2;
|
||||
if (!matchFormal(*i, name, def2)) abort();
|
||||
Bindings::const_iterator j = args.find(name);
|
||||
if (j != args.end())
|
||||
(*actualArgs.attrs)[name] = j->second;
|
||||
else if (!matchDefaultValue(def2, def))
|
||||
throw TypeError(format("cannot auto-call a function that has an argument without a default value (`%1% ')")
|
||||
% aterm2String(name));
|
||||
}
|
||||
|
||||
callFunction(fun, actualArgs, res);
|
||||
}
|
||||
|
||||
|
||||
void EvalState::eval(Expr e, Value & v)
|
||||
{
|
||||
eval(baseEnv, e, v);
|
||||
|
@ -1058,33 +1095,6 @@ ATermList flattenList(EvalState & state, Expr e)
|
|||
}
|
||||
|
||||
|
||||
Expr autoCallFunction(Expr e, const ATermMap & args)
|
||||
{
|
||||
Pattern pat;
|
||||
ATerm body, pos, name;
|
||||
ATermList formals;
|
||||
ATermBool ellipsis;
|
||||
|
||||
if (matchFunction(e, pat, body, pos) && matchAttrsPat(pat, formals, ellipsis, name)) {
|
||||
ATermMap actualArgs(ATgetLength(formals));
|
||||
|
||||
for (ATermIterator i(formals); i; ++i) {
|
||||
Expr name, def, value; ATerm def2;
|
||||
if (!matchFormal(*i, name, def2)) abort();
|
||||
if ((value = args.get(name)))
|
||||
actualArgs.set(name, makeAttrRHS(value, makeNoPos()));
|
||||
else if (!matchDefaultValue(def2, def))
|
||||
throw TypeError(format("cannot auto-call a function that has an argument without a default value (`%1%')")
|
||||
% aterm2String(name));
|
||||
}
|
||||
|
||||
e = makeCall(e, makeAttrs(actualArgs));
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
/* Evaluation of various language constructs. These have been taken
|
||||
out of evalExpr2 to reduce stack space usage. (GCC is really dumb
|
||||
about stack space: it just adds up all the local variables and
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue