aboutsummaryrefslogtreecommitdiffstats
path: root/cppawk-narg.1
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-03-29 23:11:21 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-03-29 23:11:21 -0700
commita7c84ea38a2883ba1b33d05d729715ed0acaccad (patch)
tree9ca3ddae549c12ca0190dfdb043dad8aa21a0f9b /cppawk-narg.1
parentf3614cce61ab22526ff34b311e4ef4e8c63b90f7 (diff)
downloadcppawk-a7c84ea38a2883ba1b33d05d729715ed0acaccad.tar.gz
cppawk-a7c84ea38a2883ba1b33d05d729715ed0acaccad.tar.bz2
cppawk-a7c84ea38a2883ba1b33d05d729715ed0acaccad.zip
man cppawk-narg: use fonts in synopsis and examples.
Diffstat (limited to 'cppawk-narg.1')
-rw-r--r--cppawk-narg.1138
1 files changed, 93 insertions, 45 deletions
diff --git a/cppawk-narg.1 b/cppawk-narg.1
index 409a602..985ea1c 100644
--- a/cppawk-narg.1
+++ b/cppawk-narg.1
@@ -8,9 +8,9 @@
.ft B
#include <narg.h>
- #define narg(...)
- #define splice(args)
- #define varexpand(first_mac, rest_mac, ...)
+ #define narg(...P)
+ #define splice(\fIargs\fP)
+ #define varexpand(\fIfirst_mac\fP, \fIrest_mac\fP, ...)
#define revarg(...)
.ft R
@@ -22,10 +22,12 @@ In particular, these macros make it easy to develop variable argument
macros which take one or more argument, and have complex expansions.
In this manual, the
-.B ->
+.I ->
(arrow) notation means "expands to". For instance
- foo(bar) -> 42 // the macro call foo(bar) expands to 42
+.ft B
+ foo(bar) \fI->\fP 42 // the macro call foo(bar) expands to 42
+.ft R
A description of each macro follows:
@@ -33,9 +35,11 @@ A description of each macro follows:
This macro takes one or more arguments, and expands to a decimal integer which
indicates how many arguments there are.
- narg(x) -> 1
- narg(x, y) -> 2
- narg(x, y, z) -> 3
+.ft B
+ narg(\fIx\fP) \fI->\fP 1
+ narg(\fIx\fP, \fIy\fP) \fI->\fP 2
+ narg(\fIx\fP, \fIy\fP, \fIz\fP) \fI->\fP 3
+.ft R
The
.B narg
@@ -56,11 +60,15 @@ macro provides a shim for inserting a parenthesized argument into
a macro expansion, such that the argument turns into individual
arguments. Suppose we have a macro like this:
- #define vmac(a, b, ...) ...
+.ft B
+ #define vmac(\fIa\fP, \fIb\fP, ...) ...
+.ft R
For some reason, we need to write fixed a macro like this:
- #define fmac(x, y, args) vmac(x, y, ???)
+.ft B
+ #define fmac(\fIx\fP, \fIy\fP, \fIargs\fP) vmac(\fIx\fP, \fIy\fP, \fI???\fP)
+.ft R
where the
.B args
@@ -72,26 +80,34 @@ macro. That is to say,
.B fmac
is to be invoked like this, with the indicated expansion:
- fmac(1, 2, (3, 4, 5)) -> vmac(1, 2, 3, 4, 5)
+.ft B
+ fmac(\fI1\fP, \fI2\fP, (\fI3\fP, \fI4\fP, \fI5\fP)) \fI->\fP vmac(\fI1\fP, \fI2\fP, \fI3\fP, \fI4\fP, \fI5\fP)
+.ft R
The
.B splice
macro solves the question of what to write into the position
indicated by the ??? question marks to achieve this:
- #define fmac(x, y, args) vmac(x, y, splice(args))
+.ft B
+ #define fmac(\fIx\fP, \fIy\fP, \fIargs\fP) vmac(\fIx\fP, \fIy\fP, splice(\fIargs\fP))
+.ft R
Example: produce the following macro:
- csum((a, b, c), (x, y)) -> (sqrt(sumsq(a, b, c)) +
- sqrt(sumsq(x, y)))
+.ft B
+ csum((\fIa\fP, \fIb\fP, \fIc\fP), (\fIx\fP, \fIy\fP)) \fI->\fP (sqrt(sumsq(\fIa\fP, \fIb\fP, \fIc\fP)) +
+ sqrt(sumsq(\fIx\fP, \fIy\fP)))
+.ft R
This is a trick example:
.B splice
is not required at all:
- #define csum(left, right) (sqrt(sumsq left) + \e
- sqrt(sumsq right))
+.ft B
+ #define csum(\fIleft\fP, \fIright\fP) (sqrt(sumsq \fIleft\fP) + \e
+ sqrt(sumsq \fIright\fP))
+.ft R
The
.B splice
@@ -101,23 +117,29 @@ the entire argument list of
However, suppose the requirement is this, requiring the parenthesized
arguments to be inserted into an argument list containing other arguments:
- csum(t, (a, b, c), (x, y)) -> (sqrt(sumsq(t, a, b, c)) +
- sqrt(sumsq(t, x, y)))
+.ft B
+ csum(\fIt\fP, (\fIa\fP, \fIb\fP, \fIc\fP), (\fIx\fP, \fIy\fP)) -> (sqrt(sumsq(\fIt\fP, \fIa\fP, \fIb\fP, \fIc\fP)) +
+ sqrt(sumsq(\fIt\fP, \fIx\fP, \fIy\fP)))
+.ft R
Now we need:
- #define csum(parm, left, right) (sqrt(sumsq(parm, \e
- splice(left)) + \e
- sumsq(parm, \e
- splice(right))))
+.ft B
+ #define csum(\fIparm\fP, \fIleft\fP, \fIright\fP) (sqrt(sumsq(\fIparm\fP, \e
+ splice(\fIleft\fP)) + \e
+ sumsq(\fIparm\fP, \e
+ splice(\fIright\fP))))
+.ft R
.IP \fBrevarg\fR
This macro expands to a comma-separated list of its arguments, which
appear in reverse.
- revarg(1) -> 1
- revarg(1, 2) -> 2, 1
- revarg(1, 2, 3) -> 3, 2, 1
+.ft B
+ revarg(\fI1\fP) \fI->\fP \fI1\fP
+ revarg(\fI1\fP, \fI2\fP) \fI->\fP \fI2\fP, \fI1\fP
+ revarg(\fI1\fP, \fI2\fP, \fI3\fP) \fI->\fP \fI3\fP, \fI2\fP, \fI1\fP
+.ft R
Like
.BR narg ,
@@ -149,7 +171,9 @@ function found in functional languages. Recall that the prototype of the
.BI varexpand
macro is this:
+.ft B
#define varexpand(first_mac, rest_mac, ...)
+.ft R
To use
.B varexpand
@@ -178,20 +202,26 @@ followed by unspecified behavior for 49 or more arguments.
Example: suppose we want to write a macro with an expansion like this:
- add(1) -> 1
- add(1, 2) -> 1 + 2
- add(1, 2, 3) -> 1 + 2 + 3
+.ft B
+ add(\fI1\fP) \fI\fP-> \fI1\fP
+ add(\fI1\fP, \fI2\fP) \fI->\fP \fI1\fP + \fI2\fP
+ add(\fI1\fP, \fI2\fP, \fI3\fP) \fI->\fP \fI1\fP + \fI2\fP + \fI3\fP
+.ft R
First, we must write a macro for handling the base case of the induction, which
is used for the leftmost argument. The expansion is trivial:
- #define add_first(x) x
+.ft B
+ #define add_first(\fIx\fP) \fIx\fP
+.ft R
The second macro is more complex. It takes two arguments. The left argument is
the accumulated expansion so far, of all the arguments previous to that
argument. The right argument is the next argument to be added to the expansion.
- #define add_next(acc, x) acc + x
+.ft B
+ #define add_next(\fIacc\fP, \fIx\fP) \fIacc\fP + \fIx\fP
+.ft R
For instance, if the arguments 1, 2 have already been expanded to 1 + 2
and the next argument is 3, then
@@ -200,26 +230,34 @@ takes on the tokens 1 + 2, and
.B x
takes on 3. Thus the expansion is:
- add_next(1 + 2, 3) -> 1 + 2 + 3
+.ft B
+ add_next(\fI1\fP + \fI2\fP, \fI3\fP) \fI->\fP \fI1\fP + \fI2\fP + \fI3\fP
+.ft R
With these two macros, we can then write
.B add
like this:
- #define add(...) varexpand(add_first, add_next, __VA_ARGS__)
+.ft B
+ #define add(\fI\fP...) varexpand(\fIadd_first\fP, \fIadd_next\fP, __VA_ARGS__)
+.ft R
More complex example: suppose we want an inline sum-of-squares macro
which works like this:
- sumsq(x) -> ((x)*(x))
- sumsq(x, y, z) -> ((x)*(x) + (y)*(y) + (z)*(z))
+.ft B
+ sumsq(\fIx\fP) \fI->\fP ((\fIx\fP)*(\fIx\fP))
+ sumsq(\fIx\fP, \fIy\fP, \fIz\fP) \fI->\fP ((\fIx\fP)*(\fIx\fP) + (\fIy\fP)*(\fIy\fP) + (\fIz\fP)*(\fIz\fP))
+.ft R
Note the detail that there are outer parentheses around the entire
expansion, but the individual terms are not parenthesized, only
the products. We write the helper macros like this:
- #define sumsq_first(x) (x)*(x)
- #define sumsq_next(a, x) a + sumsq_first(x)
+.ft B
+ #define sumsq_first(\fIx\fP) (\fIx\fP)*(\fIx\fP)
+ #define sumsq_next(\fIa\fP, \fIx\fP) \fIa\fP + sumsq_first(\fIx\fP)
+.ft R
Note that
.B sumsq_next
@@ -227,9 +265,11 @@ reuses
.B sumsq_first
to avoid repeating the (x)*(x) term. Then we complete the implementation:
- #define sumsq(...) (varexpand(sumsq_first, \e
- sumsq_next,\e
+.ft B
+ #define sumsq(...) (varexpand(\fIsumsq_first\fP, \e
+ \fIsumsq_next\fP,\e
__VA_ARGS__))
+.ft R
The outer parentheses are written around the
.B varexpand
@@ -242,28 +282,36 @@ Example:
.BI rlist
macro which generates a left-associative nested expression, like this:
- rlist(1) -> cons(1, nil)
- rlist(1, 2) -> cons(2, cons(1, nil))
- rlist(1, 2, 3) -> cons(3, cons(2, cons(1, nil)))
+.ft B
+ rlist(\fI1\fP) \fI->\fP cons(\fI1\fP, Inil)
+ rlist(\fI1\fP, \fI2\fP) \fI->\fP cons(\fI2\fP, cons(\fI1\fP, nil))
+ rlist(\fI1\fP, \fI2\fP, \fI3\fP) -> cons(\fI3\fP, cons(\fI2\fP, cons(\fI1\fP, nil)))
+.ft R
Implementation:
- #define rlist_first(x) cons(x, nil)
- #define rlist_next(a, x) cons(x, a)
+.ft B
+ #define rlist_first(\fIx\fP) cons(\fIx\fP, nil)
+ #define rlist_next(\fIa\fP, \fIx\fP) cons(\fIx\fP, \fIa\fP)
- #define rlist(...) varexpand(rlist_first, rlist_next, \e
+ #define rlist(...) varexpand(\fIrlist_first\fP, \fIrlist_next\fP, \e
__VA_ARGS__)
+.ft R
What if we want the consing to produce the list in order via right
association, rather than in reverse? So that is to say:
- list(1, 2, 3) -> cons(1, cons(2, cons(3, nil)))
+.ft B
+ list(\fI1\fP, \fI2\fP, \fI3\fP) -> cons(\fI1\fP, cons(\fI2\fP, cons(\fI3\fP, nil)))
+.ft R
Here we simply take advantage of the
.B revarg
macro to reverse the arguments:
+.ft B
#define list(...) rlist(revarg(__VA_ARG__))
+.ft R
.SH BUGS
As noted in the DESCRIPTION, the