summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libexpr/eval.cc2
-rw-r--r--src/libexpr/primops.cc19
2 files changed, 19 insertions, 2 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 37677d3cb0..89cc8254d2 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -221,7 +221,7 @@ Expr evalExpr2(EvalState & state, Expr e)
                     (state, args2);
             } else
                 /* Need more arguments, so propagate the primop. */
-                return ATmake("PrimOp(<int>, <term>, <list>)",
+                return ATmake("PrimOp(<int>, <term>, <term>)",
                     arity, fun, args);
         }
 
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index e97c636b81..ad1c02247e 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -314,8 +314,23 @@ Expr primIsNull(EvalState & state, const ATermVector & args)
 
 
 /* Apply a function to every element of a list. */
-Expr primMap(EvalState & state, Expr fun, Expr list)
+Expr primMap(EvalState & state, const ATermVector & args)
 {
+    Expr fun = evalExpr(state, args[0]);
+    Expr list = evalExpr(state, args[1]);
+
+    ATMatcher m;
+
+    ATermList list2;
+    if (!(atMatch(m, list) >> "List" >> list2))
+        throw Error("`map' expects a list as its second argument");
+
+    ATermList list3 = ATempty;
+    for (ATermIterator i(list2); i; ++i)
+        list3 = ATinsert(list3,
+            ATmake("Call(<term>, <term>)", fun, *i));
+
+    return ATmake("List(<term>)", ATreverse(list3));
 }
 
 
@@ -330,4 +345,6 @@ void EvalState::addPrimOps()
     addPrimOp("baseNameOf", 1, primBaseNameOf);
     addPrimOp("toString", 1, primToString);
     addPrimOp("isNull", 1, primIsNull);
+
+    addPrimOp("map", 2, primMap);
 }