;;;; Macros that write macros: a quasiquote inside a quasiquote. ;;;; ;;;; The outer quasiquote is desugared when the file is read, and the inner one ;;;; is data until the outer macro runs. What that macro answers is a defmacro ;;;; holding the inner quasiquote, which is desugared then, and the macro it ;;;; defines is compiled and called like one written by hand. ;; The inner ~x belongs to the inner quasiquote, so it is the generated ;; macro's own parameter and nothing the outer macro evaluates. (defmacro defsquare [name] `(defmacro ~name [x] `(* ~x ~x))) ;; ~~n reaches out two levels: n is evaluated when defadder runs, and what it ;; holds is pasted into the inner template as an expression the generated ;; macro evaluates. A Form constructor is such an expression, so the literal ;; arrives as one. (defmacro defadder [name n] `(defmacro ~name [x] `(+ ~x ~~n))) ;; ~@ inside the inner template is the inner macro's splice. (defmacro defsum [name] `(defmacro ~name [& xs] `(+ 0 ~@xs))) ;; Two levels down: a macro that writes a macro that writes a macro. (defmacro defsquarer [name] `(defmacro ~name [inner] `(defmacro ~inner [x] `(* ~x ~x)))) (defsquare sq) (defadder add5 (Form.Int {.i 5})) (defsum total) (defsquarer defsq2) (defsq2 sq2) (defn main [] i32 (print (sq 7)) (println "") (print (add5 10)) (println "") (print (total 1 2 3 4)) (println "") (print (sq2 9)) (println "") 0)