Contents | < Browse | Browse >
17L. EC PreProcessor
EC has an internal preprocessor which features macro substitution and
conditional compilation. These are not features of the E language,
rather it has been integrated with EC for speed and flexibility.
Activating the preprocessor.
Until you type:
EC will behave as normal. This OPT is necessary for any preprocessor
The macropreprocessor is mostly compatible with Mac2E and the C language PP
You can define macros as follows:
#define MACRONAME BODY
#define MACRONAME(ARG,...) BODY
#define MACRONAME(ARG,...) BODY \
REST OF BODY
MACRONAME and ARG may be ANY case, and may contain "_" and 0-9 as usual.
Whitespace may be added everywhere, except between MACRONAME and "(", because
otherwise EC can't see the difference between arguments and a body. The BODY
may contain occurances of the ARGs. A macro may continue on the next line by
preceding the end_of_line with a "\". A body should not extend over more than
one statement. (a macroname with no body is useful in combination with
Macro identifiers have precedence over other identifiers.
Macro definitions defined in a module will be saved in the module only if
OPT EXPORT is on (#define can't be preceded with EXPORT). If that's a problem,
keep macros together in their own modules. Macros in modules can be used in
other code simply by importing them with MODULE and OPT PREPROCESS.
Using a macro.
Using MACRONAME anywhere in the program will insert the body of the macro
at that spot. Note that this substitution is text substitution, and has
little to do with actual E syntax. If the macros have arguments they will
be inserted at their respective places in the macrobody. If the body (or
the arguments) contain futher macros, these will be expanded after that.
#define MAX(x,y) (IF x>y THEN x ELSE y)
WriteF('biggest = \d\n',MAX(10,a))
will equal writing:
WriteF('biggest = \d\n',(IF 10>a THEN 10 ELSE a))
This immediately shows a danger of macros: since it simply copies
textually, writing MAX(large_computation(),1) will generate code
that executes large_computation() twice. Be aware of this.
Differences of the E PP from the C PP and Mac2E
* it doesn't support 0-arg macros, i.e. MACRONAME()
* comments part of a macro definition are not removed
* macro arguments in string constants are replaced as well. This
can actually be quite handy, to write macros such as:
#define debug(x) (WriteF('now evaluating: x\n') BUT x)
This can be useful if you wish to decide at compile time which part of
your code to use. syntax:
the piece of source following this will or won't be compiled depending on
whether MACRONAME was defined. you can simply do this with:
or somesuch. End a conditionally compiled block with:
Blocks like these may be nested. example:
WriteF('now entering bla() with x = \d\n',x)
WriteF('now dumping memory...\n')
/* ... */