diff options
-rw-r--r-- | src/libexpr/eval.cc | 2 | ||||
-rw-r--r-- | src/libexpr/primops.cc | 19 |
2 files changed, 19 insertions, 2 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 37677d3cb093..89cc8254d2ee 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 e97c636b8194..ad1c02247e3f 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); } |