Chez Phase 1 (increment 3g): letfn + declare/def-no-init
Closes the last two non-host-interop prelude emit gaps. letfn now analyzes to a :let node flagged :letrec — the binding fns are bound into the env together before any spec is analyzed, so siblings and self resolve. The Chez back end lowers it to letrec*; the Janet back end punts it at emit (its sequential let* can't express the mutual recursion — same interpreter fallback as before, just decided at emit-ir instead of analyze). (def x) with no init (declare) analyzes to a :def with :no-init instead of punting. Chez reserves the var cell via declare-var! (which doesn't clobber an existing root — (do (def x 7) (def x) x) => 7); the Janet back end still punts to the interpreter, which interns a genuinely-unbound var. fallback-zero-test now checks emit-ir too, not just analyze-form, so the real compile-vs-interpret decision is what it asserts (letfn/def-no-init analyze but the Janet back end punts them). letfn stays in must-punt with an updated note. Prelude emit reach 342 -> 348/355 (40-lazy now 13/13); Chez subset 664 -> 672, 0 divergences; emit-test 110 -> 117. Full gate green.
This commit is contained in:
parent
930800f9a6
commit
0f7d2753a8
8 changed files with 119 additions and 31 deletions
|
|
@ -21,8 +21,13 @@
|
|||
(def ctx (init-cached))
|
||||
|
||||
(defn- analyzes? [s]
|
||||
# true if the analyzer produced IR (compiled), false if it punted/uncompilable.
|
||||
(def r (protect (backend/analyze-form ctx (parse-string s))))
|
||||
# true if the form COMPILES end to end (analyzer IR + back end emit), false if
|
||||
# it punts to the interpreter. Checks emit-ir too, not just analyze-form: letfn
|
||||
# and (def x) with no init now ANALYZE to IR, but the Janet back end punts them
|
||||
# at emit time (sequential let* can't express mutual recursion; an unbound var
|
||||
# is not a compiled value) — so analyze-form alone would miss the real
|
||||
# compile-vs-interpret decision that compile-and-eval makes.
|
||||
(def r (protect (backend/emit-ir ctx (backend/analyze-form ctx (parse-string s)))))
|
||||
(and (r 0) true))
|
||||
|
||||
# --- Must compile: pure, non-stateful value production. NONE may punt. ---
|
||||
|
|
@ -80,8 +85,11 @@
|
|||
# defmacro — definitional host seam (the EXPANDERS are compiled;
|
||||
# see backend/recompile-macros!)
|
||||
# set! — host var-cell mutation special
|
||||
# letfn — needs letrec IR (sequential let* can't express mutual
|
||||
# recursion); permanent-interpret unless the IR gains it
|
||||
# letfn — analyzes to a :letrec IR node now (inc 3g), but the Janet
|
||||
# back end still punts it at emit: its sequential let* can't
|
||||
# express the mutual recursion. The Chez back end DOES
|
||||
# compile it (letrec*). Janet stays interpret until emit-let
|
||||
# gains a letrec lowering.
|
||||
# eval — compile-and-run entry (also loader stateful-head?)
|
||||
# . / new / Foo. / — thin host-interop heads the back end doesn't model
|
||||
# .method
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue