flan/test/programs/macro-gensym-rounds.flan

25 lines
903 B
Plaintext

;;;; Two gensyms from two macro modules are never the same name.
;;;;
;;;; `outer` calls `baked` in its body, so `baked` is compiled in a round of
;;;; its own and `outer`'s body is expanded against that module before `outer`
;;;; is compiled. The gensym `baked` draws there becomes a literal in
;;;; `outer`'s code; the one `outer` draws itself comes from the later module
;;;; the program is expanded with. `main` comes first so that its expansion is
;;;; that module's first draw. Were the two the same name, the second binding
;;;; would shadow the first and this would print 200.
(defn main [] i32
(println (outer 1))
0)
;; Expands to code that builds the symbol this expansion drew.
(defmacro baked []
(match (gensym)
(Form.Sym s) `(Form.Sym {.s ~(Form.Str {.s s})})
_ `(form-nil)))
(defmacro outer [a]
(let [g (baked)
h (gensym)]
`(let [~g ~a ~h 100] (+ ~g ~h))))