From 159e621d1a9c4391b53f3d822109c36931934698 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 2 Aug 2013 15:21:17 +0000 Subject: [PATCH] =?UTF-8?q?Overload=20the=20=E2=80=98+=E2=80=99=20operator?= =?UTF-8?q?=20to=20support=20integer=20addition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libexpr/eval.cc | 30 ++++++++++++++++++----------- tests/lang/eval-okay-arithmetic.exp | 2 +- tests/lang/eval-okay-arithmetic.nix | 6 +++--- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index f891496a7..766440fc6 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -968,31 +968,39 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) { PathSet context; std::ostringstream s; - - bool first = true, isPath = false; - Value vStr; + int n = 0; + + bool first = true; + ValueType firstType; foreach (vector::iterator, i, *es) { - (*i)->eval(state, env, vStr); + Value vTmp; + (*i)->eval(state, env, vTmp); /* 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 = !forceString && vStr.type == tPath; + firstType = vTmp.type; first = false; } - s << state.coerceToString(vStr, context, false, !isPath); + if (firstType == tInt && !forceString) { + if (vTmp.type != tInt) + throwEvalError("cannot add %1% to an integer", showType(vTmp)); + n += vTmp.integer; + } else + s << state.coerceToString(vTmp, context, false, firstType != tPath); } - - 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) + if (firstType == tInt) + mkInt(v, n); + else if (firstType == tPath) { + if (!context.empty()) + throwEvalError("a string that refers to a store path cannot be appended to a path, in `%1%'", s.str()); mkPath(v, s.str().c_str()); - else + } else mkString(v, s.str(), context); } diff --git a/tests/lang/eval-okay-arithmetic.exp b/tests/lang/eval-okay-arithmetic.exp index 9c113c6f7..861c12661 100644 --- a/tests/lang/eval-okay-arithmetic.exp +++ b/tests/lang/eval-okay-arithmetic.exp @@ -1 +1 @@ -1275 +1854 diff --git a/tests/lang/eval-okay-arithmetic.nix b/tests/lang/eval-okay-arithmetic.nix index ac1fcb73c..1f45b122a 100644 --- a/tests/lang/eval-okay-arithmetic.nix +++ b/tests/lang/eval-okay-arithmetic.nix @@ -8,14 +8,14 @@ let { else [first] ++ range (builtins.add first 1) last; /* Supposedly tail recursive version: - - range_ = accum: first: last: + + range_ = accum: first: last: if first == last then ([first] ++ accum) else range_ ([first] ++ accum) (builtins.add first 1) last; range = range_ []; */ - body = sum (range 1 50); + body = sum (range 1 50) + 123 + 456; }