about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2013-08-02T15·21+0000
committerEelco Dolstra <eelco.dolstra@logicblox.com>2013-08-02T15·21+0000
commit159e621d1a9c4391b53f3d822109c36931934698 (patch)
tree848dc085309b9c8c18b655afcba1d722564e9c79
parent511455965e1a17db3653147a4ac0d284a37915be (diff)
Overload the ‘+’ operator to support integer addition
-rw-r--r--src/libexpr/eval.cc30
-rw-r--r--tests/lang/eval-okay-arithmetic.exp2
-rw-r--r--tests/lang/eval-okay-arithmetic.nix6
3 files changed, 23 insertions, 15 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index f891496a7568..766440fc67cb 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<Expr *>::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 9c113c6f75f9..861c12661a83 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 ac1fcb73c073..1f45b122a2bb 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;
 
 }