From 760c77bd3936f1c655fb1886eb312aa6e9d89d9c Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sat, 16 Apr 2022 09:00:18 -0700 Subject: cons: mapcar, mappend: doc, tests. --- cppawk-cons.1 | 78 +++++++++++++++++++++++++++++++++++++++++++++-- cppawk-include/fun-priv.h | 2 +- runtests | 2 +- 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 "" +library. + +Note: function indirection does not work correctly on built-in functions +on GNU Awk before version 5.2. + +.B Examples: + +.ft B + #include + #include + + 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 " 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 +#include + +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 +#include + +function cs(x) { + return cox(x) +} + +BEGIN { + print sexp(mappend(fun(cs), list(0.2, 0.2, 0.3))) +}' +: +ERR -- cgit v1.2.3