aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cppawk-cons.178
-rw-r--r--cppawk-include/fun-priv.h2
-rwxr-xr-xruntests2
-rw-r--r--testcases-cons38
4 files changed, 116 insertions, 4 deletions
diff --git a/cppawk-cons.1 b/cppawk-cons.1
index 6d701f6..ec97a41 100644
--- a/cppawk-cons.1
+++ b/cppawk-cons.1
@@ -96,7 +96,6 @@ cons \- Lisp-like data representation and control flow macros
uniqual(\fIx\fP) \fI// deduplicate x with equal equality\fP
mapcar(\fIf\fP, \fIx\fP) \fI// map list through function f\fP
-
mappend(\fIf\fP, \fIx\fP) \fI// map list through f, append results\fP
\fI// array -> list conversion\fP
@@ -1815,9 +1814,84 @@ function's notion of equality.
uniqual(list(box_str("abc"), "abc")) -> ("abc")
.ft R
+.SS Functions \fImapcar\fP and \fImappend\fP
+.bk
+Syntax:
+
+.ft B
+ mapcar(\fIf\fP, \fIx\fP)
+ mappend(\fIf\fP, \fIx\fP)
+.ft R
+
+Note: this function requires GNU Awk, or any dialect which
+supports GNU-Awk-style indirect functions.
+
+The
+.B mapcar
+and
+.B mappend
+functions call function
+.I f
+once for every element of list
+.I x
+in left to right order, and produce a new list based on the values returned by
+.IR f .
+
+The
+.B mapcar
+function returns a list of the values returned by
+.I f
+which appear in the same order as the calls to
+.IR f .
+
+The
+.B mappend
+function requires all values returned by
+.IR f ,
+except for possibly the last one, to be a list.
+Mappend catenates these lists together, as if using the
+.B append
+function, in the same order as the calls to
+.IR f .
+
+Note: the function value
+.B f
+may be produced by applying the
+.B fun
+or
+.B bind
+operator to an Awk function. These operators are located in the
+.B "<fun.h>"
+library.
+
+Note: function indirection does not work correctly on built-in functions
+on GNU Awk before version 5.2.
+
+.B Examples:
+
+.ft B
+ #include <cons.h>
+ #include <fun.h>
+
+ function sq (\fIx\fP) {
+ return sqrt(\fIx\fP)
+ }
+
+ BEGIN {
+ // prints (("x" . 1) ("x" . 2) ("x" . 3))
+ print sexp(mapcar(bind(\fIcons\fP, "x"), list(1, 2, 3)))
+
+ // prints ("x" 1 "x" 2 "x" 3)
+ print sexp(mappend(bind(\fIlist\fP, "x"), list(1, 2, 3)))
+
+ // prints (0 1 2 3 4 5)
+ print sexp(mapcar(fun(\fIsq\fP), list(0, 1, 4, 9, 16, 25)))
+ }
+.ft R
+
.SH "SEE ALSO"
-cppawk(1)
+cppawk(1), cppawk-fun(1)
.SH BUGS
diff --git a/cppawk-include/fun-priv.h b/cppawk-include/fun-priv.h
index 173e6d0..17fef9b 100644
--- a/cppawk-include/fun-priv.h
+++ b/cppawk-include/fun-priv.h
@@ -40,7 +40,7 @@
#warning "<fun.h> requires an Awk with function indirection like newer GNU Awk"
#endif
-#define __bind(fname, env) __cons(#fname, env)
+#define __bind(fname, env) __cons(__xstr(fname), env)
#define __fun_(fname) __xstr(fname)
#define __call(fobj, ...) (__consp(fobj) \
? __progn(__g(f) = __car(fobj), \
diff --git a/runtests b/runtests
index 6bb4c68..e6edd75 100755
--- a/runtests
+++ b/runtests
@@ -24,5 +24,5 @@ fi
if [ -z "$suite" -o "$suite" = "cons" ] ; then
cppawk=./cppawk ./testsuite.awk testcases-cons
- cppawk="./cppawk --awk=mawk" ./testsuite.awk testcases-cons
+ cppawk="./cppawk --awk=mawk" ./testsuite.awk -v skip=37,38 testcases-cons
fi
diff --git a/testcases-cons b/testcases-cons
index 0e0b2db..7b66766 100644
--- a/testcases-cons
+++ b/testcases-cons
@@ -703,3 +703,41 @@ nil
("abc" "abc")
("abc")
((1 . 2) (3 . 4) (3 . 5))
+--
+37:
+$cppawk '
+#include <cons.h>
+#include <fun.h>
+
+function sq (x) {
+ return sqrt(x)
+}
+
+BEGIN {
+ print sexp(mapcar(fun(42), nil))
+ print sexp(mapcar(bind(cons, "x"), list(1, 2, 3)))
+ print sexp(mappend(fun(42), nil))
+ print sexp(mappend(bind(list, "x"), list(1, 2, 3)))
+ print sexp(mapcar(fun(sq), list(0, 1, 4, 9, 16, 25)))
+}'
+:
+nil
+(("x" . 1) ("x" . 2) ("x" . 3))
+nil
+("x" 1 "x" 2 "x" 3)
+(0 1 2 3 4 5)
+--
+38:
+$cppawk '
+#include <cons.h>
+#include <fun.h>
+
+function cs(x) {
+ return cox(x)
+}
+
+BEGIN {
+ print sexp(mappend(fun(cs), list(0.2, 0.2, 0.3)))
+}'
+:
+ERR