Node:Macros and formatting, Next:Preprocessing, Previous:FWEB macros, Up:Macros
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.