WCPL macros
May 22, 2023WCPL has a simple macro mechanism that mimics most frequent patterns used by C macro writers while being implemented via an entirely different mechanism. While C macros manipulate sequences of tokens, WCPL macros manipulate complete expressions; substitution is done on the level of abstract syntax trees. Although it makes it impossible to use some advanced tricks empoyed by C macro experts, such as introducing unpaired braces, substituting types, and glueing identifiers from individual parts, most popular macro patterns still can be employed, and made to behave in the same way between WCPL and C.
WCPL macros have two flavors: expression macros and statement macros.
Expression macros have a complete expression on the right-hand side of the
macro. Formally, it is a primary_expression
grammar category; informally, it
is either a literal constant (no sign for numerical literals!) or any single
expression enclosed in parentheses, e.g.:
Statement macro’s right-hand side is single statement wrapped in a “fake do”,
i.e. preceded by the do
keyword and followed by while (0)
trailer. It may
look strange, but it is indeed a standard C practice, allowing uses of such
macros to be followed by a semicolon, as required by C statement grammar, e.g.:
Please note two additional features in the example above: the name of the macro being defined can be followed by a parenthesized list of argument names (no space is allowed between the name and the open parenthesis), and long macro bodies can be wrapped into multiple lines if internal end-of-line characters are “escaped” via a backslash. The latter feature is optional in WCPL (it always reads a complete grammar category, not a token list), but supported for compatibility with C preprocessor — the macro above works in the same way both in C and WCPL.
Expression macros can be parameterized as well. Please note that WCPL macro uses, which look like function calls, can only accept grammatically valid expressions as parameters. There is no such limitation in C, where any sequences of tokens will do, as long as they are separated by colons. Example:
WCPL macros can only be defined on top level of the module or header file; they
cannot be re-defined if an earlier definition exists, unless they undefined
via #undef
first:
Some built-in macros such as __WCPL__
cannot be undefined or redefined.
Additional macro features will be described in separate posts.