diff options
-rw-r--r-- | cppawk-cons.1 | 78 | ||||
-rw-r--r-- | cppawk-include/fun-priv.h | 2 | ||||
-rwxr-xr-x | runtests | 2 | ||||
-rw-r--r-- | testcases-cons | 38 |
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), \ @@ -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 |