macroexpand-first analyzer order; one macro path; defmacro/letfn fixes
The analyzer checked special forms before expanding macros, the reverse of the canonical read -> macroexpand -> analyze order (Clojure/CLJS analyze-seq). Move macroexpansion to the front of analyze-list. Knock-on fixes: - letfn was both a (broken) macro expanding to let* AND a primitive special (analyze-letfn, proper letrec*). Macroexpand-first surfaced the macro, breaking mutual recursion; remove the macro, keep letfn a primitive. - defmacro is now compiled by the analyzer (a :set-var-style :defmacro node that defs the expander fn via the fn macro — so destructuring arglists desugar — and marks the var a macro), so a non-top-level (when … (defmacro …)) works. The runtime spine's separate top-level defmacro interception is removed: one path. SCI load 162 -> 202/218.
This commit is contained in:
parent
e6ee17b055
commit
f18ae3bd46
8 changed files with 402 additions and 383 deletions
|
|
@ -117,14 +117,9 @@
|
|||
result
|
||||
(let ((r (jolt-compile-eval-form (car fs) cur)))
|
||||
(loop (cdr fs) r (chez-current-ns))))))
|
||||
;; runtime defmacro: def the expander fn + mark the var a macro so subsequent
|
||||
;; forms expand it (hc-macro? reads var-macro-table). Mirrors emit-image.ss
|
||||
;; ei-emit-ns.
|
||||
((ce-macro-form? form)
|
||||
(let-values (((nm fn-form) (ce-defmacro->fn form)))
|
||||
(def-var! ns nm (jolt-compile-eval-form fn-form ns))
|
||||
(mark-macro! ns nm)
|
||||
jolt-nil))
|
||||
;; defmacro is compiled like any other form — the analyzer lowers it to a def
|
||||
;; of the expander fn + (mark-macro! …) so subsequent forms expand it. One
|
||||
;; macro-expansion path (no separate spine interception).
|
||||
(else
|
||||
(eval (read (open-input-string (jolt-analyze-emit-form form ns)))
|
||||
(interaction-environment)))))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue