about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2013-10-28T06·34+0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2013-10-28T06·34+0100
commitea6bf0c21fc08ea269514fa9788f8f05fcc54fb5 (patch)
treeebf194d25c923106f489a64b03a5899b3138a09b /src
parent36e67ff16bc6a4cb96466f58616a95a25250274d (diff)
Slightly optimize listToAttrs
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/eval.cc1
-rw-r--r--src/libexpr/eval.hh2
-rw-r--r--src/libexpr/primops.cc16
3 files changed, 10 insertions, 9 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 814c19efcc..4c448ff51a 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -136,6 +136,7 @@ EvalState::EvalState()
     , sType(symbols.create("type"))
     , sMeta(symbols.create("meta"))
     , sName(symbols.create("name"))
+    , sValue(symbols.create("value"))
     , sSystem(symbols.create("system"))
     , sOverrides(symbols.create("__overrides"))
     , sOutputs(symbols.create("outputs"))
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index b896137a69..cac8af8770 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -93,7 +93,7 @@ class EvalState
 public:
     SymbolTable symbols;
 
-    const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName,
+    const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, sValue,
         sSystem, sOverrides, sOutputs, sOutputName, sIgnoreNulls;
     Symbol sDerivationNix;
 
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index cfd669d26c..214bf8b999 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -277,10 +277,10 @@ static void prim_tryEval(EvalState & state, Value * * args, Value & v)
     state.mkAttrs(v, 2);
     try {
         state.forceValue(*args[0]);
-        v.attrs->push_back(Attr(state.symbols.create("value"), args[0]));
+        v.attrs->push_back(Attr(state.sValue, args[0]));
         mkBool(*state.allocAttr(v, state.symbols.create("success")), true);
     } catch (AssertionError & e) {
-        mkBool(*state.allocAttr(v, state.symbols.create("value")), false);
+        mkBool(*state.allocAttr(v, state.sValue), false);
         mkBool(*state.allocAttr(v, state.symbols.create("success")), false);
     }
     v.attrs->sort();
@@ -810,7 +810,8 @@ static void prim_removeAttrs(EvalState & state, Value * * args, Value & v)
 /* Builds a set from a list specifying (name, value) pairs.  To be
    precise, a list [{name = "name1"; value = value1;} ... {name =
    "nameN"; value = valueN;}] is transformed to {name1 = value1;
-   ... nameN = valueN;}. */
+   ... nameN = valueN;}.  In case of duplicate occurences of the same
+   name, the first takes precedence. */
 static void prim_listToAttrs(EvalState & state, Value * * args, Value & v)
 {
     state.forceList(*args[0]);
@@ -828,16 +829,15 @@ static void prim_listToAttrs(EvalState & state, Value * * args, Value & v)
             throw TypeError("`name' attribute missing in a call to `listToAttrs'");
         string name = state.forceStringNoCtx(*j->value);
 
-        Bindings::iterator j2 = v2.attrs->find(state.symbols.create("value"));
-        if (j2 == v2.attrs->end())
-            throw TypeError("`value' attribute missing in a call to `listToAttrs'");
-
         Symbol sym = state.symbols.create(name);
         if (seen.find(sym) == seen.end()) {
+            Bindings::iterator j2 = v2.attrs->find(state.symbols.create(state.sValue));
+            if (j2 == v2.attrs->end())
+                throw TypeError("`value' attribute missing in a call to `listToAttrs'");
+
             v.attrs->push_back(Attr(sym, j2->value, j2->pos));
             seen.insert(sym);
         }
-        /* !!! Throw an error if `name' already exists? */
     }
 
     v.attrs->sort();