about summary refs log tree commit diff
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r--src/libexpr/eval.cc33
1 files changed, 30 insertions, 3 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 62b493bbf6af..99149fd7f9fe 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -54,6 +54,7 @@ std::ostream & operator << (std::ostream & str, Value & v)
         str << "]";
         break;
     case tThunk:
+    case tCopy:
         str << "<CODE>";
         break;
     case tLambda:
@@ -160,6 +161,16 @@ LocalNoInlineNoReturn(void throwTypeError(const char * s, const string & s2))
     throw TypeError(format(s) % s2);
 }
 
+LocalNoInlineNoReturn(void throwTypeError(const char * s, const Pos & pos, const string & s2))
+{
+    throw TypeError(format(s) % pos % s2);
+}
+
+LocalNoInlineNoReturn(void throwTypeError(const char * s, const Pos & pos))
+{
+    throw TypeError(format(s) % pos);
+}
+
 LocalNoInlineNoReturn(void throwAssertionError(const char * s, const Pos & pos))
 {
     throw AssertionError(format(s) % pos);
@@ -175,6 +186,11 @@ LocalNoInline(void addErrorPrefix(Error & e, const char * s, const string & s2))
     e.addPrefix(format(s) % s2);
 }
 
+LocalNoInline(void addErrorPrefix(Error & e, const char * s, const Pos & pos))
+{
+    e.addPrefix(format(s) % pos);
+}
+
 LocalNoInline(void addErrorPrefix(Error & e, const char * s, const string & s2, const string & s3))
 {
     e.addPrefix(format(s) % s2 % s3);
@@ -424,6 +440,11 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
             Value & v2 = (*v.attrs)[i->first];
             mkThunk(v2, env, i->second);
         }
+
+        foreach (list<string>::iterator, i, inherited) {
+            Value & v2 = (*v.attrs)[*i];
+            mkCopy(v2, *lookupVar(&env, *i));
+        }
     }
 }
 
@@ -555,7 +576,8 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v)
             nrValues++;
                 
             if (j == arg.attrs->end()) {
-                if (!i->def) throwTypeError("the argument named `%1%' required by the function is missing", i->name);
+                if (!i->def) throwTypeError("function at %1% called without required argument `%2%'",
+                    fun.lambda.fun->pos, i->name);   
                 mkThunk(v, env2, i->def);
             } else {
                 attrsUsed++;
@@ -568,10 +590,15 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v)
            TODO: show the names of the expected/unexpected
            arguments. */
         if (!fun.lambda.fun->formals->ellipsis && attrsUsed != arg.attrs->size())
-            throwTypeError("function called with unexpected argument");
+            throwTypeError("function at %1% called with unexpected argument", fun.lambda.fun->pos);
     }
 
-    eval(env2, fun.lambda.fun->body, v);
+    try {
+        eval(env2, fun.lambda.fun->body, v);
+    } catch (Error & e) {
+        addErrorPrefix(e, "while evaluating the function at %1%:\n", fun.lambda.fun->pos);
+        throw;
+    }
 }