Skip to content
Bill Hails edited this page Oct 19, 2024 · 9 revisions

There is now some very basic macro support implemented in the lambda conversion step (where we go from the abstract syntax tree to al lambda representation). It is little more than variable substitution at the moment, but still has some usefulness. For example in the preamble we now have:

macro and(a, b) { if (a) { b } else { false } }

infix left 30 "and" and;

Ans similar for the other logical operators. The expression true and false will first get re-written by the operator parser to and(true, false), then the macro expansion during lambda conversion rewrites that to if (true) { false } else { false }. Note this preserves the short circuiting of the and, e.g.

let
    fn a() { print "a called"; false }
    fn b() { print "b called"; true }
    fn c() { print "c called"; true }
in
    a() and b() or c();

prints:

a called
c called

There is also limited support for hygiene, the construct $variable inside of a macro will generate a fresh symbol if the symbol has not already been generated by that particular macro expansion, so all occurrences of i.e. $a within an individual body refer to the same variable, but nested macro invocations will generate fresh variables.

Clone this wiki locally