aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r--src/libexpr/eval.cc128
1 files changed, 59 insertions, 69 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 8ead986b8..21c22333b 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -160,9 +160,9 @@ LocalNoInlineNoReturn(void throwTypeError(const char * s, const string & s2))
throw TypeError(format(s) % s2);
}
-LocalNoInlineNoReturn(void throwAssertionError(const char * s, const string & s2))
+LocalNoInlineNoReturn(void throwAssertionError(const char * s, const Pos & pos))
{
- throw AssertionError(format(s) % s2);
+ throw AssertionError(format(s) % pos);
}
LocalNoInline(void addErrorPrefix(Error & e, const char * s))
@@ -341,73 +341,13 @@ void EvalState::eval(Env & env, Expr * e, Value & v)
char x;
if (&x < deepestStack) deepestStack = &x;
- //debug(format("eval: %1%") % e);
+ //debug(format("eval: %1%") % *e);
checkInterrupt();
nrEvaluated++;
e->eval(*this, env, v);
-
-#if 0
- Sym name;
- int n;
- ATerm s; ATermList context, es;
- ATermList rbnds, nrbnds;
- Expr e1, e2, e3, fun, arg, attrs;
- Pattern pat; Expr body; Pos pos;
-
- else if (matchConcatStrings(e, es)) {
- PathSet context;
- std::ostringstream s;
-
- bool first = true, isPath = false;
- Value vStr;
-
- for (ATermIterator i(es); i; ++i) {
- eval(env, *i, vStr);
-
- /* If the first element is a path, then the result will
- also be a path, we don't copy anything (yet - that's
- done later, since paths are copied when they are used
- in a derivation), and none of the strings are allowed
- to have contexts. */
- if (first) {
- isPath = vStr.type == tPath;
- first = false;
- }
-
- s << coerceToString(vStr, context, false, !isPath);
- }
-
- if (isPath && !context.empty())
- throwEvalError("a string that refers to a store path cannot be appended to a path, in `%1%'", s.str());
-
- if (isPath)
- mkPath(v, s.str().c_str());
- else
- mkString(v, s.str(), context);
- }
-
- /* Assertions. */
- else if (matchAssert(e, e1, e2, pos)) {
- if (!evalBool(env, e1))
- throwAssertionError("assertion failed at %1%", showPos(pos));
- eval(env, e2, v);
- }
-
- /* Negation. */
- else if (matchOpNot(e, e1))
- mkBool(v, !evalBool(env, e1));
-
- /* Attribute existence test (?). */
- else if (matchOpHasAttr(e, e1, name)) {
- Value vAttrs;
- eval(env, e1, vAttrs);
- forceAttrs(vAttrs);
- mkBool(v, vAttrs.attrs->find(name) != vAttrs.attrs->end());
- }
-#endif
}
@@ -516,6 +456,15 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
}
+void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v)
+{
+ Value vAttrs;
+ state.eval(env, e, vAttrs);
+ state.forceAttrs(vAttrs);
+ mkBool(v, vAttrs.attrs->find(name) != vAttrs.attrs->end());
+}
+
+
void ExprLambda::eval(EvalState & state, Env & env, Value & v)
{
v.type = tLambda;
@@ -663,6 +612,20 @@ void ExprIf::eval(EvalState & state, Env & env, Value & v)
}
+void ExprAssert::eval(EvalState & state, Env & env, Value & v)
+{
+ if (!state.evalBool(env, cond))
+ throwAssertionError("assertion failed at %1%", pos);
+ state.eval(env, body, v);
+}
+
+
+void ExprOpNot::eval(EvalState & state, Env & env, Value & v)
+{
+ mkBool(v, !state.evalBool(env, e));
+}
+
+
void ExprOpEq::eval(EvalState & state, Env & env, Value & v)
{
Value v1; state.eval(env, e1, v1);
@@ -713,12 +676,6 @@ void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
}
-void ExprOpConcatStrings::eval(EvalState & state, Env & env, Value & v)
-{
- abort();
-}
-
-
void ExprOpConcatLists::eval(EvalState & state, Env & env, Value & v)
{
Value v1; state.eval(env, e1, v1);
@@ -735,6 +692,39 @@ void ExprOpConcatLists::eval(EvalState & state, Env & env, Value & v)
}
+void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
+{
+ PathSet context;
+ std::ostringstream s;
+
+ bool first = true, isPath = false;
+ Value vStr;
+
+ foreach (vector<Expr *>::iterator, i, *es) {
+ state.eval(env, *i, vStr);
+
+ /* If the first element is a path, then the result will also
+ be a path, we don't copy anything (yet - that's done later,
+ since paths are copied when they are used in a derivation),
+ and none of the strings are allowed to have contexts. */
+ if (first) {
+ isPath = vStr.type == tPath;
+ first = false;
+ }
+
+ s << state.coerceToString(vStr, context, false, !isPath);
+ }
+
+ if (isPath && !context.empty())
+ throwEvalError("a string that refers to a store path cannot be appended to a path, in `%1%'", s.str());
+
+ if (isPath)
+ mkPath(v, s.str().c_str());
+ else
+ mkString(v, s.str(), context);
+}
+
+
void EvalState::forceValue(Value & v)
{
if (v.type == tThunk) {