Macros

A macro is a way of expressing a lot of code or data with a simple shorthand. It's also usually configurable. Traditional macro systems such as C's #define mechanic use textual replacement: a macro is expanded before any evaluation or even parsing occurs.

In contrast, Ophis's macro system uses a call by value approach where the arguments to macros are evaluated to bytes or words before being inserted into the macro body. This produces effects much closer to those of a traditional function call. A more detailed discussion of the tradeoffs may be found in the Appendix called Ophis Command Reference.

Macro definitions

A macro definition is a set of statements between a .macro statement and a .macend statement. The .macro statement also names the macro being defined.

No global or anonymous labels may be defined inside a macro: temporary labels only persist in the macro expansion itself. (Each macro body has its own scope. A label map will trace back through macro expansions to describe were a label inside a macro body came from.)

Arguments to macros are referred to by number: the first is _1, the second _2, and so on.

Here's a macro that encapsulates the printing routine in our "Hello World" program, with an argument being the address of the string to print:

.macro print
        ldx #0
_loop:  lda _1, x
        beq _done
        jsr chrout
        inx
        bne _loop
_done:
.macend

Macro invocations

The most common way to invoke a macro is to backquote the name of the macro. It is also possible to use the .invoke command. These commands look like this:

`print msg
.invoke print msg

Arguments are passed to the macro as a comma-separated list. They must all be expressions that evaluate to byte or word values—a mechanism similar to .alias is used to assign their values to the _n names.