about summary refs log tree commit diff
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-04-07T15·47+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-04-07T15·47+0000
commitaf2a372bb000d4d5aeec37e43ee0f6245c1bba54 (patch)
tree7d92b153b255d64c1db807595c9577a43b77f50d /src/libexpr/eval.cc
parent9a64454faae2ab4ccedeeaad85a0e094726b4765 (diff)
* Update autoCallFunction() and findAlongAttrPath().
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r--src/libexpr/eval.cc64
1 files changed, 37 insertions, 27 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 0d18c55227..98b6b7bdd1 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