jolt/host/chez/jolt-chez.janet
Yogthos c90c4cb610 Chez Phase 2 (inc Q): Java class statics + constructors (jolt-avt6)
Lower host class interop on the Chez back end. The analyzer now turns a
non-var qualified ref `Class/member` into a :host-static node and a
`(Class. ...)` / `(new Class ...)` form into a :host-new node (ir.clj
gains both, with walker support). The Janet back end punts both to the
interpreter, so its behavior is unchanged (verified: dot-form, `..`
threading, shadowed `new`, and all interop still resolve via fallback).

The Chez emit lowers a value ref to host-static-ref, a call head to
host-static-call, and a constructor to host-new. host/chez/host-static.ss
is the runtime registry these resolve against — the Chez port of the
seed's class-statics / class-ctors / tagged-methods (java_base.janet +
host_io.janet), restricted to the java.lang/util/net/io surface portable
cljc code calls: Math, System (getenv/getProperty/exit/currentTimeMillis),
Long, Integer, Boolean, Character, String, Thread, Class, Pattern
(compile/quote/MULTILINE), URLEncoder/Decoder, Base64, the Number method
surface (byteValue/intValue/...), plus the StringBuilder, StringWriter,
StringReader, PushbackReader, HashMap, StringTokenizer, BigInteger,
String, MapEntry, and exception constructors. Constructed objects are
jhost records dispatched through record-method-dispatch.

Also: emit now evaluates collection-literal elements left-to-right
(emit-ordered) — Chez evaluates call args right-to-left, which had been
swapping side-effecting elements in [(read r) (read r)] and map literals.
This un-allowlisted the 6 eval-order corpus cases (the read-line trio +
the three map-construction cases). Removed `.write` from the
jolt-host-call fast-path so a StringWriter routes through dispatch.

java.time formatting, edn/read-over-readers, and slurp/with-open over
readers are deferred to a follow-up.

Corpus parity 2078 -> 2134 (floor raised), 0 new divergences; the
print-method builtin-override case is allowlisted (same multimethod gap,
newly reachable now that StringWriter constructs). emit-test 326/326,
_javastatic 51/51, conformance 355x3, full jpm test green.
2026-06-18 23:24:01 -04:00

56 lines
2.5 KiB
Text

# -e-capable jolt-chez (jolt-9ziu): the Option-2 back end as a runnable CLI.
#
# Analysis runs on Janet (the portable analyzer); EXECUTION runs on Chez with the
# full clojure.core assembled as a Scheme prelude (driver/emit-core-prelude). The
# prelude is assembled once and cached on disk keyed by a fingerprint of the core
# sources + the Chez RT/emitter, so repeated invocations (e.g. the run-corpus.janet
# gate, one subprocess per case) reuse it.
#
# Usage (the run-corpus.janet boundary): jolt-chez -e "EXPR"
# Run from the repo root (the prelude loads host/chez/rt.ss by relative path).
(import ../../src/jolt/api :as api)
(import ./driver :as d)
(defn- fingerprint []
# Hash the inputs that shape the prelude: the core tiers + the emitter + the
# Chez RT shims. Any change invalidates the cached prelude.
(def parts @[])
(each tf d/core-tier-files
(array/push parts (slurp (string "jolt-core/clojure/core/" tf ".clj"))))
(each f ["host/chez/emit.janet" "host/chez/driver.janet" "host/chez/rt.ss"
"host/chez/values.ss" "host/chez/collections.ss" "host/chez/seq.ss"
"host/chez/atoms.ss" "host/chez/predicates.ss" "host/chez/regex.ss"
"host/chez/ns.ss" "host/chez/post-prelude.ss" "host/chez/natives-meta.ss"
"host/chez/natives-str.ss" "host/chez/records.ss"
"host/chez/host-static.ss"
"src/jolt/clojure/string.clj"]
(array/push parts (slurp f)))
(string/slice (string (hash (string/join parts))) 0))
(defn- ensure-prelude [ctx]
(def dir (or (os/getenv "JOLT_IMAGE_CACHE_DIR") (os/getenv "TMPDIR") "/tmp"))
(def path (string dir "/jolt-chez-prelude-" (fingerprint) ".ss"))
(unless (os/stat path)
(def [scm _ _] (d/emit-core-prelude ctx))
(spit path scm))
path)
(defn main [& argv]
# argv: [script "-e" EXPR]
(def args (drop 1 argv))
(unless (and (= (length args) 2) (= (first args) "-e"))
(eprint "usage: jolt-chez -e EXPR")
(os/exit 2))
(def src (in args 1))
(def ctx (api/init-cached {:compile? true}))
# late-bind unresolved symbols (no interpreter to punt to) so defmulti/defmethod
# forward references lower to a var-deref (jolt-9ls5), matching d/make-ctx.
(put (get ctx :env) :late-bind-unresolved? true)
(def prelude-path (ensure-prelude ctx))
(def [code out err] (d/eval-e-with-prelude ctx src prelude-path))
(when (= code :emit-err)
(eprint "jolt-chez: cannot compile: " out)
(os/exit 1))
(unless (= "" out) (print out))
(unless (= "" err) (eprint err))
(os/exit code))