diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 37677d3cb0938d2995c35b90e441e92497b8c7cb..89cc8254d2ee5289aa9537d1d39ece976cfb3451 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 e97c636b81946afbfd29ba13e90e6d3f4f7f2d5c..ad1c02247e3f934e101edfbe6ecaa4a547208cc8 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); }