about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libexpr/primops.cc53
-rw-r--r--tests/lang/eval-okay-listToAttrs.nix8
-rw-r--r--tests/lang/eval-okay-listToAttrs.out1
3 files changed, 62 insertions, 0 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 95440c9bf655..044eff657ba1 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -296,6 +296,17 @@ static Expr prim_getEnv(EvalState & state, const ATermVector & args)
     return makeStr(getEnv(name));
 }
 
+/* for debugging purposes. print the first arg on stdout (perhaps stderr should be used?)
+ * and return the second
+ */
+static Expr prim_trace(EvalState & state, const ATermVector & args)
+{
+    //string str = evalStringNoCtx(state, args[0]);
+
+    Expr a = evalExpr(state, args[0]);
+    printf("traced value: %s\n", atPrint(a).c_str());
+    return evalExpr(state, args[1]);
+}
 
 static Expr prim_relativise(EvalState & state, const ATermVector & args)
 {
@@ -744,6 +755,39 @@ static Expr prim_hasAttr(EvalState & state, const ATermVector & args)
 }
 
 
+/* takes 
+ * param: list of { attr="attr"; value=value } 
+ * returns an attribute set
+ * */
+static Expr prim_listToAttrs(EvalState & state, const ATermVector & args)
+{
+  try {
+    ATermMap res = ATermMap();
+
+    ATermList list;
+    list = evalList(state, args[0]);
+    for (ATermIterator i(list); i; ++i){
+      // *i should now contain a pointer to the list item expression
+      ATermList attrs;
+      Expr evaledExpr = evalExpr(state, *i);
+      if (matchAttrs(evaledExpr, attrs)){
+        Expr e = evalExpr(state, makeSelect(evaledExpr, toATerm("attr")));
+        string attr = evalStringNoCtx(state,e);
+        ATerm value;
+        Expr r = makeSelect(evaledExpr, toATerm("value"));
+        res.set(toATerm(attr), makeAttrRHS(r, makeNoPos()));
+      }
+      else {
+        throw EvalError(format("passed list item is a %s (value: %s). Set { attr=\"name\"; value=nix expr; } expected.") % showType(evaledExpr) % showValue(evaledExpr)); 
+      }
+    } // for
+    return makeAttrs(res);
+  } catch (Error & e) {
+    e.addPrefix(format("while calling listToAttrs "));
+    throw;
+  }
+}
+
 static Expr prim_removeAttrs(EvalState & state, const ATermVector & args)
 {
     ATermMap attrs;
@@ -758,6 +802,12 @@ static Expr prim_removeAttrs(EvalState & state, const ATermVector & args)
     return makeAttrs(attrs);
 }
 
+/* Determine whether the argument is a list. */
+static Expr prim_isAttrs(EvalState & state, const ATermVector & args)
+{
+    ATermList list;
+    return makeBool(matchAttrs(evalExpr(state, args[0]), list));
+}
 
 /*************************************************************
  * Lists
@@ -901,6 +951,7 @@ void EvalState::addPrimOps()
     addPrimOp("abort", 1, prim_abort);
     addPrimOp("throw", 1, prim_throw);
     addPrimOp("__getEnv", 1, prim_getEnv);
+    addPrimOp("__trace", 2, prim_trace);
 
     addPrimOp("relativise", 2, prim_relativise);
 
@@ -923,7 +974,9 @@ void EvalState::addPrimOps()
     addPrimOp("__attrNames", 1, prim_attrNames);
     addPrimOp("__getAttr", 2, prim_getAttr);
     addPrimOp("__hasAttr", 2, prim_hasAttr);
+    addPrimOp("__isAttrs", 1, prim_isAttrs);
     addPrimOp("removeAttrs", 2, prim_removeAttrs);
+    addPrimOp("__listToAttrs", 1, prim_listToAttrs);
 
     // Lists
     addPrimOp("__isList", 1, prim_isList);
diff --git a/tests/lang/eval-okay-listToAttrs.nix b/tests/lang/eval-okay-listToAttrs.nix
new file mode 100644
index 000000000000..f5eae92ccd98
--- /dev/null
+++ b/tests/lang/eval-okay-listToAttrs.nix
@@ -0,0 +1,8 @@
+# this test shows how to use listToAttrs and that evaluation is still lazy (throw isn't called)
+let 
+  asi = attr: value : { inherit attr value; };
+  list = [ ( asi "a" "A" ) ( asi "b" "B" ) ];
+  a = builtins.listToAttrs list;
+  b = builtins.listToAttrs ( list ++ list );
+  r = builtins.listToAttrs [ (asi "result" [ a b ]) ( asi "throw" (throw "this should not be thrown")) ];
+in r.result
diff --git a/tests/lang/eval-okay-listToAttrs.out b/tests/lang/eval-okay-listToAttrs.out
new file mode 100644
index 000000000000..4e779ff063f0
--- /dev/null
+++ b/tests/lang/eval-okay-listToAttrs.out
@@ -0,0 +1 @@
+List([Attrs([Bind("a",Str("A",[]),NoPos),Bind("b",Str("B",[]),NoPos)]),Attrs([Bind("a",Str("A",[]),NoPos),Bind("b",Str("B",[]),NoPos)])])