XXIIVV

Uxntal Macros

A macro is a way of defining inline routines, it allows to create new words that will be replaced by the body of the macro, as opposed to a jump where the program counter will move to a routine and back, therefore it needs to be defined before its usage, as follow:

%modulo ( num denum -- res ) {
	DIVk MUL SUB }

@routine ( -- c* )
	#18 #03 modulo JMP2r

In the previous example, the token modulo will get replaced by the body of the macro during assembly:

@routine ( -- c* )
	#18 #03 DIVk MUL SUB JMP2r

A macro may contain nested anonymous labels:

%square-quoted ( a -- res ) {
	{ DUP MUL JMP2r } STH2r }

A macro may be referenced by its local name within a scope, making macros zero-cost abstractions and interchangeable with methods.

@pen/position &x $1 &y $1

%pen/emit-value ( value -- ) {
	DUP #04 SFT emit-nibble emit-nibble
}

@pen/print-position ( -- )
	,&position LDR2 SWP /emit-value /emit-value
	JMP2r

Macros can contain labels but remember that labels and sublabels must be unique, so the macro may not be used in the same scope. It is a common mistake to use macros to encode constants, instead consider using labels.

incoming: forth uxntal uxntal notation uxntal strings 2024