macro librarylib/Macros.xtlm
A small macro library, an example of macros of your own (MC10). A macro is an ordinary function of the source text written on each side of its call; the text it gives replaces the call, then is read as code. Import it with an alias of your own, "x:" u_se< "Macros", and see what a program becomes with xetal expand FILE.
Statements and definitions
ᵐw̲hen< : Char -> Char -> Char
Run the statements on the right when the condition on the left holds; the value is @ either way (the other way round from the system macro u_nless<).
ˣ⁼u̲se< "Macros"
"1 < 2" ˣw̲hen< "p_rint! 7" 7 @
ᵐw̲hen< ← { cond body → "{ @ -> (n_ot " c̲at cond c̲at ") ? @; " c̲at body c̲at "; @ } @" }
ᵐd̲ef< : Char -> Char -> Char
Define the function named on the left (in u:) as the lambda body on the right, its name written as text.
ˣ⁼u̲se< "Macros"
"s_quare" ˣd̲ef< "_r * _r"
ᵘs̲quare 7 49
ᵐd̲ef< ← { name body → "u:" c̲at name c̲at " := { " c̲at body c̲at " }" }
Checks
ᵐc̲heck< : Char -> Char -> Char
The line "ok: label" when the condition on the left holds, else "FAIL: label (cond)", the condition shown as it was written, which a function, given only the condition's value, cannot do.
ˣ⁼u̲se< "Macros"
"5 = 2 * 2" ˣc̲heck< "doubling" FAIL: doubling (5 = 2 * 2)
ᵐc̲heck< ← { cond label → "{ @ -> (" c̲at cond c̲at ") ? \"ok: " c̲at label c̲at "\"; \"FAIL: " c̲at label c̲at " (" c̲at cond c̲at ")\" } @" }
Names a macro binds
ᵐt̲wice< : Unit -> Char -> Char
Twice the expression on the right: the macro binds a local t (to 2) around your expression, and hygiene renames it (to g1:t, say), so a t of your own is still yours.
ˣ⁼u̲se< "Macros"
t ← 5
@ ˣt̲wice< "t + 1" 12
ᵐt̲wice< ← { @ e → "{ @ -> t := 2; t * (" c̲at e c̲at ") } @" }
ᵐw̲ith< : Char -> Char -> Char
The text on the right with it bound to the value of the expression on the left (an anaphoric macro: it is meant for your text, so it is declared below and hygiene leaves it as written).
ˣ⁼u̲se< "Macros"
"3 + 4" ˣw̲ith< "it * it" 49
ᵐw̲ith< ← { e body → "{ @ -> it := (" c̲at e c̲at "); " c̲at body c̲at " } @" }