diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 37677d3cb..89cc8254d 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(, , )", + return ATmake("PrimOp(, , )", arity, fun, args); } diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index e97c636b8..ad1c02247 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(, )", fun, *i)); + + return ATmake("List()", 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); }