Chez Phase 1 (increment 3q): multimethod dispatch + late-bind
host/chez/multimethods.ss implements the multimethod runtime: defmulti/defmethod expand to defmulti-setup/defmethod-setup calls (+ get-method/methods/ remove-method/prefer-method/prefers). A jolt-multifn record carries its dispatch fn and a jolt=-keyed method table; jolt-invoke dispatches it (exact match, then isa?/hierarchy with prefer-method, then :default), reusing the overlay's isa?/derive/make-hierarchy. The multifn's ns comes from a runtime chez-current-ns (default user; the prelude load sets clojure.core for print-method/print-dup). Two emit-side changes were needed: - late-bind (:late-bind-unresolved? ctx flag, default OFF): defmulti expands to a bare-symbol setup call, so the analyzer doesn't intern the name and a forward reference '(area ...)' after '(defmulti area ...)' in one form was 'Unable to resolve symbol'. The strict compiler punts these to the interpreter; the Chez back end has none, so the flag lowers an unresolved symbol to a var-ref against the compile ns (open-world -e semantics). Set only by the Chez make-ctx / jolt-chez; the main compiler keeps strict resolution (host_iface late-bind? defaults nil). - a :var call head now routes through jolt-invoke, since a late-bound var can hold a multifn (or keyword/coll IFn), not just a procedure. Transparent for procedures; the hot self-recursive call is a :local known-proc, stays direct. Class-based dispatch ((class x)/String) deferred (needs deftype/class subsystem). Parity 1506 -> 1530/2497, 0 new divergences. emit-test 302/302. Full janet gate green (the analyzer flag is off there; suite flakiness under parallel load only).
This commit is contained in:
parent
e51cc2e47e
commit
02139af0a1
10 changed files with 279 additions and 8 deletions
|
|
@ -29,8 +29,13 @@
|
|||
(and (r 0) (zero? (r 1))))
|
||||
|
||||
(defn make-ctx []
|
||||
"A compile-mode jolt ctx (the analyzer pipeline is only built under :compile?)."
|
||||
(api/init {:compile? true}))
|
||||
"A compile-mode jolt ctx (the analyzer pipeline is only built under :compile?).
|
||||
Late-bind unresolved symbols: the Chez back end has no interpreter to punt to,
|
||||
so a forward reference to a runtime-interned var (defmulti/defmethod's setup
|
||||
call) lowers to a var-deref instead of failing to compile (jolt-9ls5)."
|
||||
(def ctx (api/init {:compile? true}))
|
||||
(put (get ctx :env) :late-bind-unresolved? true)
|
||||
ctx)
|
||||
|
||||
(defn- parse-all [src]
|
||||
(def out @[])
|
||||
|
|
@ -138,10 +143,15 @@
|
|||
(string
|
||||
"(import (chezscheme))\n"
|
||||
"(load \"host/chez/rt.ss\")\n"
|
||||
# the prelude's defmultis (print-method/print-dup) must land in clojure.core,
|
||||
# not the default user ns (jolt-9ls5); set the multimethod current-ns around
|
||||
# the prelude load, then restore it to user for the program form.
|
||||
"(set-chez-ns! \"clojure.core\")\n"
|
||||
"(load " (string/format "%j" prelude-path) ")\n"
|
||||
# native-wins overrides for overlay predicates that read :jolt/type (char?,
|
||||
# atom?) — must load AFTER the prelude's own def-var! to take effect.
|
||||
"(load \"host/chez/post-prelude.ss\")\n"
|
||||
"(set-chez-ns! \"user\")\n"
|
||||
"(printf \"~a\\n\" (jolt-final-str " final-scm "))\n"))
|
||||
|
||||
(defn eval-e-with-prelude
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue