From af2a372bb000d4d5aeec37e43ee0f6245c1bba54 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 7 Apr 2010 15:47:06 +0000 Subject: * Update autoCallFunction() and findAlongAttrPath(). --- src/libexpr/eval.cc | 64 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 27 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 0d18c552275a..98b6b7bdd150 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -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 -- cgit 1.4.1