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.

source

Statements and definitions

ᵐw̲hen< : Char -> Char -> Char

macro · line 16

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

macro · line 24

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

macro · line 34

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

macro · line 45

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

macro · line 54 · binds it

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 " } @" }