The macro evaluation order is a complex algorithm designed to fit all necessary needs.
The general rule is that macros are evaluated
-
from the start of the file towards the end, and also
-
from inside towards outside.
For example, when we write
{#define a=1}{a}
first the macro define
is evaluated and then the user defined macro a
.
If we have more complex, nested macro uses, like in the example:
{#define b(x)=x x}{b {a}}
then the result is
1 1
In this case first the macro a
is evaluated before evaluating b
(inside first).
You use the built-in macros with #
or @
in front of the macro’s name.
These characters signal that the macro is built-in (as opposed to user defined,) but also they control the evaluation order.
The typical use is to start a macro with the @
character.
This will instruct Jamal not to evaluate the input of the macro before the macro itself is evaluated.
When we use the #
character in front of the built-in macro’s name then the input is evaluated and after that the macro itself is invoked to process the pre-processed input.
For example:
{@define a=1}
{@define b={a}}
{#define c={a}}
{@define a=2}
{b}{c}
will result
21
When b
is defined the macro used inside it is not evaluated.
That is because the character before the macro name define
is @
.
Therefore, the value of b
is literally {a}
.
The macro a
is already 2 by the time b
is evaluated.
On the other hand, the definition of c
uses the #
.
It means, that the macro use {a}
is evaluated before c
gets defined.
This way the value of the macro is 1.
The results of user-defined macros are also evaluated. This can be controlled and prevented in two ways:
-
At the use of it can be inside the
verbatim
constructs. -
During the definition, the macro can be defined as a "verbatim" one.
For example, writing:
{@verbatim b}
will result in
{a}
There is also a shorthand to denote verbatim evaluation of user-defined macros. If you write a back-tick character in front of the macro name, like in
{`b}
You get the same result:
{b}
We can also define b
to be a verbatim macro:
{@define [verbatim]b={a}}
{b}
and it will also result in
{a}
There are other tools that can be used to modify the evaluation order of the macros. These include: