self-host: analyzer reaches full conformance parity via hybrid fallback
The Clojure analyzer + Janet back end now pass all 218 conformance cases (vs the interpreter) through the self-hosted pipeline: - host contract gains special? (the full special-form/uncompilable set), so the analyzer falls back for forms it doesn't compile instead of miscompiling them as calls; - qualified symbol refs that don't resolve to a var (janet/…, Math/…, host interop) and tagged literals (#"regex", #inst) and set literals throw uncompilable -> interpreter; - the back end's compile-and-eval is now hybrid: only the compile step is guarded, runtime errors propagate. Still interpreter-routed (coverage to grow next): loop/recur, recur in fn, try, sets, destructuring.
This commit is contained in:
parent
849449aada
commit
5624e99eb6
3 changed files with 55 additions and 14 deletions
|
|
@ -100,14 +100,21 @@
|
|||
|
||||
(defn- analyze-symbol [ctx form locals]
|
||||
(let [nm (h/sym-name form) ns (h/sym-ns form)]
|
||||
(if (and (nil? ns) (contains? locals nm))
|
||||
(ir/local nm)
|
||||
(let [r (h/resolve-global ctx form)]
|
||||
(case (:kind r)
|
||||
:var (ir/var-ref (:ns r) (:name r))
|
||||
:host (ir/host-ref (:name r))
|
||||
;; unresolved: a forward reference in the current ns; resolved at call time
|
||||
(ir/var-ref (h/current-ns ctx) nm))))))
|
||||
(cond
|
||||
;; local (only unqualified)
|
||||
(and (nil? ns) (contains? locals nm)) (ir/local nm)
|
||||
;; qualified: must resolve to a var, else interpret (handles janet/…,
|
||||
;; Math/…, and any host interop the back end doesn't model).
|
||||
ns (let [r (h/resolve-global ctx form)]
|
||||
(if (= :var (:kind r))
|
||||
(ir/var-ref (:ns r) (:name r))
|
||||
(uncompilable (str "qualified ref " ns "/" nm))))
|
||||
:else (let [r (h/resolve-global ctx form)]
|
||||
(case (:kind r)
|
||||
:var (ir/var-ref (:ns r) (:name r))
|
||||
:host (ir/host-ref (:name r))
|
||||
;; unresolved: forward reference in the current ns (resolved at call time)
|
||||
(ir/var-ref (h/current-ns ctx) nm))))))
|
||||
|
||||
(defn- analyze-list [ctx form locals]
|
||||
(let [items (vec (h/elements form))]
|
||||
|
|
@ -119,6 +126,9 @@
|
|||
(cond
|
||||
(and hname (not shadowed) (contains? handled hname))
|
||||
(analyze-special ctx hname items locals)
|
||||
;; A special form the analyzer doesn't compile -> interpreter.
|
||||
(and hname (not shadowed) (h/special? hname))
|
||||
(uncompilable (str "special form " hname))
|
||||
(and (h/sym? head) (not shadowed) (h/macro? ctx head))
|
||||
(analyze ctx (h/expand-1 ctx form) locals)
|
||||
:else
|
||||
|
|
@ -136,6 +146,8 @@
|
|||
(h/map? form) (ir/map-node (mapv (fn [p] [(analyze ctx (first p) locals)
|
||||
(analyze ctx (second p) locals)])
|
||||
(h/map-pairs form)))
|
||||
(h/set? form) (ir/set-node (mapv #(analyze ctx % locals) (h/set-items form)))
|
||||
(h/set? form) (uncompilable "set literal")
|
||||
(h/list? form) (analyze-list ctx form locals)
|
||||
:else (ir/const form))))
|
||||
;; Anything else (tagged literals like #"regex"/#inst, unknown shapes) is
|
||||
;; host-specific or not a value the back end can embed — interpret it.
|
||||
:else (uncompilable "unsupported form"))))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue