diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-03-29 23:11:21 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-03-29 23:11:21 -0700 |
commit | a7c84ea38a2883ba1b33d05d729715ed0acaccad (patch) | |
tree | 9ca3ddae549c12ca0190dfdb043dad8aa21a0f9b /cppawk-narg.1 | |
parent | f3614cce61ab22526ff34b311e4ef4e8c63b90f7 (diff) | |
download | cppawk-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.1 | 138 |
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 |