Next: Preprocessing, Previous: FWEB macros, Up: Macros [Contents][Index]
FWEAVE makes a valiant attempt to pretty-print (see Pretty-printing) the definitions of both outer macros and FWEB macros in a reasonable way. However, this can be a formidable task, because macro syntax can be essentially arbitrary. Consider, for example, the following definition:
@c
@d GET(type) type get_##type()
@a
GET(int){}@; // Expands into ‘int get_int(){}’.
The problem is that the identifier ‘type’ is used in two different ways: as the type of a reserved word (the second ‘type’), and as an ordinary expression (the third ‘type’). The first ‘type’ has both meanings simultaneously. Unfortunately, within any particular language FWEAVE associates one unique type or ilk with each identifier.
One solution to this problem is to use the ‘@R’ command (see ATR_), which changes the ilk of the very next identifier to integer-like. Thus,
@d GET(type) @R type get_##type()@;
will format correctly. An alternative solution uses the related command ‘@E’, which changes the ilk of the very next identifier to an ordinary expression. Thus,
@f type int @d GET(type) type get_##@Etype()@;
Other types of troublesome situations involve spaces. When FWEB understands the syntax, it inserts spaces automatically to make the output pleasing. Consider, however, the (somewhat contrived) example
@c @d A(x, y) x y @d B s1; @d C s2; @a A(B, C)@;
Here FWEAVE will consider ‘x’ and ‘y’ to be ordinary identifiers (simple expressions), and will abut them with no intervening spaces, which is confusing to read. The solution is to insert a space manually with ‘@,’:
@d A(x, y) x @, y
(Whether one should write macros like this at all is a separate issue.) For a related example, see the discussion of ATcomma.
Next: Preprocessing, Previous: FWEB macros, Up: Macros [Contents][Index]