## 1.1 Invoking And Defining Macros

Oz macros are invoked with the following new syntax:

> `<<repeat 5 {Show hello}>>`

angle brackets delimit a sequence of phrases (expressions and statements). The first element should be an atom (here `repeat`) and names the macro to be invoked.

When the compiler encounters a macro, it invokes the macro-expansion facility. The latter eventually returns a syntactic representation that is guaranteed to no longer contain any macro invocation.

A macro is implemented by a macro expander. This is a function of two arguments: (1) a macro form (a syntactic representation), (2) a macro environment. It returns a transformed syntactic representation. Syntactic representations of Oz code use the ``Syntax Tree Format'' which is described in Appendix C of ``The Mozart Compiler''.

Let's define a very simple macro:

> `<<unless B S1 S2 S3>>`

which executes the body `S1 S2 S3` iff `B` evaluates to false.i. e. it is precisely equivalent to:

> `if B then skip else S1 S2 S3 end`

Here is the code for the expander:

> `declare
> fun {UnlessExpander fMacro(M|B|L C) Env}
> fBoolCase(
> B
> fSkip(unit)
> {Macro.listToSequence L}
> C)
> end`

The first argument `fMacro(M|B|L C)` is the macro call form. `M` is the representation of the atom which is the first element of the macro invocation (here `fAtom(unless C2)`, where `C2` is a coordinate indicating the provenance and location of the token in the input). `B` is the 2nd element of the macro call and represents the boolean condition. `L` is the list of the remainder of the macro call and represents the body. `C` is also a coordinate. `Env` is a macro environment and can usually be ignored.

`{Macro.listToSequence L}` turns the list `L` of instructions into the syntactic representation of a sequence. Module `Macro` is described in Section 1.2.

We must now globally register the macro expander:

> `{Macro.defmacro unless UnlessExpander}`

Here is a test:

> `declare
> proc {DO X Y}
> <<unless X<Y {Show X} {Show Y}>>
> end`

`{DO 2 5}` prints nothing while `{DO 5 2}` prints 5 then 2.

A common mistake while using the interactive development environment is to feed a buffer that contains both macro definitions and uses of these macros. This cannot work: when the code in the buffer is being compiled the macros are not yet defined. They become defined only after execution of the code. Thus you must first feed your macro definitions, and only then feed any code that makes use of them.