Well first of all, macro parsing in lisp usually happens in the parser itself, I.E. when it reaches a set of expressions it is executing as it encounters them, in a typed version I’m unsure how that will go.
Find instances of defmacro .
Find invocations of each of those macros.
If executed as encountered then a defmacro I’d imagine would just become like a function like normal (Elixir does defmacro as compiling to a function with a MACRO- prefix and another argument).
Convert the output of the parser into an Erie abstract syntax tree.
I’m torn on this, by keeping it a typed tree as much as possible you can know more inside the macro about what is going on, but by keeping it untyped you can be much more free-flowing with the code, with potentially much worse error messages, hmm…
Support “unquoting” somehow.
In Lisps’s unquot’ing is usually just the unquote call, so (quote (a b (unquote (quote c)) d) is handling by the quote call itself as just an ‘escaped’ name. Technically quote is a macro (or rather, a special form) that just takes its single argument as AST, transforms nested unquote's in it to inline sets, then just returns it. A lisp read-macro watches for prefix ’ and ` and just replace it and the following single expression with a (quote ...) and (unquote ...) wrapping respectively.
Replace the macros in the AST with their results.
Yep, just calling the macro function at compile-time. Elixir did itself hard by allowing calling macro’s defined in the same module. ^.^;
It became apparent pretty quickly on the implementation that this would be the right move. Or at the very least, using the same code. I would like to allow macros defined anywhere to be executed anywhere, so I think I’ll need to essentially parse the code twice. First to find the macros, and second to execute them in place.