Chez Phase 3 inc6b: runtime macros on the zero-Janet spine
The on-Chez analyzer (inc6a) skipped macros, so let/when/->/defn didn't
expand from source. Each core/stdlib defmacro now emits into the prelude as
(def-var! ns name <expander fn>) + (mark-macro! ns name); form-macro?/
form-expand-1 on Chez look up the macro flag (rt.ss var-macro-table) and
apply the expander to the unevaluated arg forms, and the analyzer re-analyzes
the result. The expander's syntax-quote template was lowered to construction
code at cross-compile time, so it builds the expansion via __sqcat/__sqvec/
__sqmap/__sqset/__sq1 (new host/chez/syntax-quote.ss) as Chez reader forms.
Emit the bare (fn ...), not (def NAME (fn ...)): analyzing a def would
host-intern! NAME as a non-macro stub in the build ctx, and that stub makes a
later (require '[stdlib-ns]) skip loading the real macro — with-pprint-dispatch
then resolved as a fn and returned its unexpanded template. Wrapping the
lambda in def-var! manually never interns NAME. Fuller build-ctx isolation
(so stdlib cases pass instead of crash) tracked in jolt-lpvi.
__sqset builds a real set VALUE, not the reader's tagged-set form — a runtime
`#{~@xs} must be a set, not a map. form-set? additionally recognizes a pset so
a macro template's #{...} expansion still re-analyzes as a set literal.
spine-test 35/35 (20 macro cases: when/when-not/let/->/->>/and/or/cond/if-not/
defn run zero-Janet from source). Prelude parity 2280->2295, 0 new divergences.
Full Janet gate green.
This commit is contained in:
parent
c2d977cadf
commit
d165198969
7 changed files with 193 additions and 31 deletions
|
|
@ -92,6 +92,17 @@
|
|||
(define jolt-kw-var-name (keyword #f "name"))
|
||||
(define (def-var-with-meta! ns name v m)
|
||||
(let ((c (def-var! ns name v))) (hashtable-set! var-meta-table c m) c))
|
||||
;; runtime-macro registry (jolt-r9lm, inc6b): a var whose root holds a macro
|
||||
;; expander fn is flagged here, so the ON-CHEZ analyzer's form-macro?/form-expand-1
|
||||
;; (host-contract.ss) expand it. The prelude emits each core/stdlib defmacro as a
|
||||
;; def-var! of its (cross-compiled) expander followed by (mark-macro! ns name).
|
||||
;; Keyed by cell (eq), like var-meta-table — survives a later (def name ...) that
|
||||
;; replaces the expander but keeps the same cell, matching Clojure (a defmacro IS a
|
||||
;; def whose var carries :macro).
|
||||
(define var-macro-table (make-eq-hashtable))
|
||||
(define (mark-macro! ns name)
|
||||
(let ((c (jolt-var ns name))) (hashtable-set! var-macro-table c #t) c))
|
||||
(define (macro-var? cell) (and cell (hashtable-ref var-macro-table cell #f) #t))
|
||||
;; declare / (def name) with no init: reserve the cell ONLY if absent. An
|
||||
;; existing root is left intact — Clojure's (def x) with no init does not clobber
|
||||
;; a prior binding (do (def x 7) (def x) x) => 7. Returns the cell either way.
|
||||
|
|
@ -308,3 +319,9 @@
|
|||
;; clojure.math (jolt-22vo): native flonum-math shims def-var!'d into the
|
||||
;; clojure.math ns. Self-contained (only def-var! + Chez math), order-independent.
|
||||
(load "host/chez/math.ss")
|
||||
|
||||
;; syntax-quote form builders (jolt-r9lm, inc6b): __sqcat/__sqvec/__sqmap/__sqset/
|
||||
;; __sq1, def-var!'d into clojure.core. A cross-compiled macro expander (analyzer
|
||||
;; on Chez, inc6b) calls these to build its expansion as reader forms. Needs the
|
||||
;; collection/seq layer + def-var!; order-independent past those.
|
||||
(load "host/chez/syntax-quote.ss")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue