aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libexpr/eval.cc13
-rw-r--r--src/libexpr/nixexpr.cc20
-rw-r--r--src/libexpr/nixexpr.hh4
-rw-r--r--src/libexpr/parser.y1
-rw-r--r--src/libexpr/symbol-table.hh13
5 files changed, 43 insertions, 8 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 551ed4ba5..c927db2c1 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -247,6 +247,11 @@ LocalNoInlineNoReturn(void throwTypeError(const char * s, const Pos & pos, const
throw TypeError(format(s) % pos % s2);
}
+LocalNoInlineNoReturn(void throwTypeError(const char * s, const string & s1, const string & s2))
+{
+ throw TypeError(format(s) % s1 % s2);
+}
+
LocalNoInlineNoReturn(void throwTypeError(const char * s, const Pos & pos))
{
throw TypeError(format(s) % pos);
@@ -755,8 +760,8 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v)
foreach (Formals::Formals_::iterator, i, fun.lambda.fun->formals->formals) {
Bindings::iterator j = arg.attrs->find(i->name);
if (j == arg.attrs->end()) {
- if (!i->def) throwTypeError("function at %1% called without required argument `%2%'",
- fun.lambda.fun->pos, i->name);
+ if (!i->def) throwTypeError("%1% called without required argument `%2%'",
+ fun.lambda.fun->showNamePos(), i->name);
env2.values[displ++] = i->def->maybeThunk(*this, env2);
} else {
attrsUsed++;
@@ -771,7 +776,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v)
user. */
foreach (Bindings::iterator, i, *arg.attrs)
if (fun.lambda.fun->formals->argNames.find(i->name) == fun.lambda.fun->formals->argNames.end())
- throwTypeError("function at %1% called with unexpected argument `%2%'", fun.lambda.fun->pos, i->name);
+ throwTypeError("%1% called with unexpected argument `%2%'", fun.lambda.fun->showNamePos(), i->name);
abort(); // can't happen
}
}
@@ -782,7 +787,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v)
try {
fun.lambda.fun->body->eval(*this, env2, v);
} catch (Error & e) {
- addErrorPrefix(e, "while evaluating the function at %1%:\n", fun.lambda.fun->pos);
+ addErrorPrefix(e, "while evaluating %1%:\n", fun.lambda.fun->showNamePos());
throw;
}
}
diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc
index c52a41391..9b75bb644 100644
--- a/src/libexpr/nixexpr.cc
+++ b/src/libexpr/nixexpr.cc
@@ -324,4 +324,24 @@ void ExprConcatStrings::bindVars(const StaticEnv & env)
}
+/* Storing function names. */
+
+void Expr::setName(Symbol & name)
+{
+}
+
+
+void ExprLambda::setName(Symbol & name)
+{
+ this->name = name;
+ body->setName(name);
+}
+
+
+string ExprLambda::showNamePos()
+{
+ return (format("%1% at %2%") % (name.set() ? "`" + (string) name + "'" : "an anonymous function") % pos).str();
+}
+
+
}
diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh
index 86a7bfd50..8256605b5 100644
--- a/src/libexpr/nixexpr.hh
+++ b/src/libexpr/nixexpr.hh
@@ -63,6 +63,7 @@ struct Expr
virtual void bindVars(const StaticEnv & env);
virtual void eval(EvalState & state, Env & env, Value & v);
virtual Value * maybeThunk(EvalState & state, Env & env);
+ virtual void setName(Symbol & name);
};
std::ostream & operator << (std::ostream & str, Expr & e);
@@ -197,6 +198,7 @@ struct Formals
struct ExprLambda : Expr
{
Pos pos;
+ Symbol name;
Symbol arg;
bool matchAttrs;
Formals * formals;
@@ -208,6 +210,8 @@ struct ExprLambda : Expr
throw ParseError(format("duplicate formal function argument `%1%' at %2%")
% arg % pos);
};
+ void setName(Symbol & name);
+ string showNamePos();
COMMON_METHODS
};
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index f78780b1d..964527be6 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -104,6 +104,7 @@ static void addAttr(ExprAttrs * attrs, AttrPath & attrPath,
}
}
}
+ e->setName(attrPath.back());
}
diff --git a/src/libexpr/symbol-table.hh b/src/libexpr/symbol-table.hh
index 143fc495b..ccdabb028 100644
--- a/src/libexpr/symbol-table.hh
+++ b/src/libexpr/symbol-table.hh
@@ -28,17 +28,17 @@ private:
public:
Symbol() : s(0) { };
-
+
bool operator == (const Symbol & s2) const
{
return s == s2.s;
}
-
+
bool operator != (const Symbol & s2) const
{
return s != s2.s;
}
-
+
bool operator < (const Symbol & s2) const
{
return s < s2.s;
@@ -49,6 +49,11 @@ public:
return *s;
}
+ bool set() const
+ {
+ return s;
+ }
+
bool empty() const
{
return s->empty();
@@ -66,7 +71,7 @@ inline std::ostream & operator << (std::ostream & str, const Symbol & sym)
class SymbolTable
{
private:
-#if HAVE_TR1_UNORDERED_SET
+#if HAVE_TR1_UNORDERED_SET
typedef std::tr1::unordered_set<string> Symbols;
#else
typedef std::set<string> Symbols;