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
|
|
@ -171,6 +171,14 @@
|
|||
(ns-intern (ctx-find-ns ctx ns-name) nm)
|
||||
nil)
|
||||
|
||||
# Open-world (late-binding) analysis: when set on the ctx env, an unresolved
|
||||
# symbol emits a var-ref against the compile ns (resolved at runtime) instead of
|
||||
# punting to the interpreter. The Chez back end (host/chez/driver) sets it: it has
|
||||
# no interpreter to punt to, and a forward reference to a runtime-interned var
|
||||
# (e.g. defmulti's setup call) must lower to a var-deref. Off everywhere else, so
|
||||
# the normal compiler keeps its strict 'Unable to resolve symbol' behavior.
|
||||
(defn h-late-bind? [ctx] (truthy? (get (ctx :env) :late-bind-unresolved?)))
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Installation: bind these fns as vars in the `jolt.host` namespace so jolt-core
|
||||
# can call them. Idempotent per context.
|
||||
|
|
@ -270,7 +278,8 @@
|
|||
"host-intern!" h-intern!
|
||||
"inline-enabled?" h-inline-enabled? "inline-ir" h-inline-ir
|
||||
"record-type?" h-record-type? "form-position" h-form-position
|
||||
"record-ctor-key" h-record-ctor-key "record-shapes" h-record-shapes})
|
||||
"record-ctor-key" h-record-ctor-key "record-shapes" h-record-shapes
|
||||
"late-bind?" h-late-bind?})
|
||||
|
||||
(defn install! [ctx]
|
||||
(def ns (ctx-find-ns ctx "jolt.host"))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue