Clean up codebase: rename stdlib layer, strip porting residue, fix tooling
Rename src/jolt -> stdlib (the runtime-loaded layer; jolt-core stays the seed-baked layer) and update the loader / emit-image / doc paths. Drop dead code: the spike/ experiments, the duplicate clojuredocs-export.edn (json moves to tools/), the Janet-era jolt.http binding, and the orphaned persistent_vector.clj whose ns/path didn't even match. Strip porting residue from comments and docstrings across host/chez, jolt-core, stdlib, tests, and docs: internal issue ids, "Phase N" markers, and the "vs Janet" historical exposition, leaving present-tense descriptions and the real JVM-Clojure semantic contrasts. Same pass over the corpus suite labels. The seed is unchanged (docstrings/comments aren't emitted), so the self-host fixpoint and corpus are untouched. Port tools/spec_coverage.py off the dead janet probe to bin/joltc and regenerate coverage.md; drop the dead :host/janet rule from certify.clj and regenerate the conformance profile. Add docs/host-interop.md (the JVM shims and how to register your own host class from a library) and a writing-style note in CLAUDE.md. Stabilize the four racy concurrency corpus cases (future-cancel and agent send/send-off): give the future a sleeping body and the agent a slow action, so cancel reliably catches an in-flight future and deref reliably reads the pre-update snapshot. They certify deterministically now, so drop their :flaky allowlist entries and the orphaned legend.
This commit is contained in:
parent
c18f8087f0
commit
33eff7c7d8
112 changed files with 970 additions and 1621 deletions
|
|
@ -1,8 +1,8 @@
|
|||
(ns jolt.analyzer
|
||||
"Portable Clojure analyzer: reader form -> host-neutral IR (see jolt.ir).
|
||||
|
||||
Pure jolt-core — depends only on the host contract (jolt.host) and IR
|
||||
constructors (jolt.ir), never on Janet. The contract fns are referred unqualified
|
||||
Depends only on the host contract (jolt.host) and IR
|
||||
constructors (jolt.ir). The contract fns are referred unqualified
|
||||
(host form predicates are `form-*` to avoid colliding with clojure.core), so the
|
||||
bootstrap can compile this namespace via its plain :var path. ctx is an opaque
|
||||
host handle threaded to the contract fns; the analyzer never inspects it.
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
(defn- add-locals [env names] (update env :locals #(reduce conj % names)))
|
||||
(defn- with-recur [env name] (assoc env :recur name))
|
||||
|
||||
;; Type hints (jolt-94n). The reader keeps ^hint metadata on the binding symbol.
|
||||
;; Type hints. The reader keeps ^hint metadata on the binding symbol.
|
||||
;; Two hints resolve to the :struct fast path (a constant-keyword lookup skips
|
||||
;; the :jolt/type guard and emits a bare get): ^:struct (a plain struct/record
|
||||
;; map) and ^TypeName where TypeName is a defrecord/deftype (its instances are
|
||||
|
|
@ -138,7 +138,7 @@
|
|||
;; param an ordinary positional slot (holding the collected seq), so recur
|
||||
;; is a self-call carrying the rest seq directly — Clojure semantics.
|
||||
;; The recur target doubles as the COMPILED FN'S NAME, which is what a
|
||||
;; janet stack trace shows — so carry the Clojure ns/fn-name (jolt-2o7.1):
|
||||
;; host stack trace shows — so carry the Clojure ns/fn-name:
|
||||
;; an error inside app.deep/level3 traces as _r$app.deep/level3--N
|
||||
;; (report-error demangles the _r$/--N wrapper). gen-name's counter
|
||||
;; keeps recur targets unique per compilation unit.
|
||||
|
|
@ -215,7 +215,7 @@
|
|||
;; the arity :rest key above). Assoc'ing them nil-when-absent would give the
|
||||
;; node a nil-valued key, which makes it a phm in jolt's map representation
|
||||
;; and forces the back end to densify it (norm-node) before reading :op — the
|
||||
;; map-nil-representation trap Phase 2 cleaned up for def/fn/arity nodes. The
|
||||
;; map-nil-representation trap, also avoided for def/fn/arity nodes. The
|
||||
;; back end reads each key with a nil-safe (node :k) and gates on it, so an
|
||||
;; absent key is indistinguishable from a present-nil one.
|
||||
(let [n {:op :try :body (analyze-seq ctx @body env)}
|
||||
|
|
@ -282,13 +282,13 @@
|
|||
(let [nm (form-sym-name name-sym)
|
||||
cur (compile-ns ctx)
|
||||
;; (def name docstring value): docstring is form 2, value form 3.
|
||||
;; Matches the interpreter; without this the docstring was taken
|
||||
;; as the value and the real init dropped (jolt-6ym).
|
||||
;; Matches the interpreter; otherwise the docstring is taken as
|
||||
;; the value and the real init dropped.
|
||||
has-doc (and (> (count items) 3) (string? (nth items 2)))
|
||||
val-form (nth items (if has-doc 3 2))
|
||||
base0 (or (form-sym-meta name-sym) {})
|
||||
;; resolve a ^Type hint to its canonical class name at def
|
||||
;; time (jolt-a1ir), as the JVM compiler does: ^String ->
|
||||
;; time, as the JVM compiler does: ^String ->
|
||||
;; java.lang.String. A record/unknown hint is left untouched.
|
||||
tag (get base0 :tag)
|
||||
tag-name (cond (form-sym? tag) (form-sym-name tag)
|
||||
|
|
@ -365,7 +365,7 @@
|
|||
:else (uncompilable "set! of an unsupported target")))
|
||||
(uncompilable (str "special form " op))))
|
||||
|
||||
;; Host interop method call (jolt-0kf5). `(.method target arg*)` — a head that
|
||||
;; Host interop method call. `(.method target arg*)` — a head that
|
||||
;; starts with "." but not ".-" (field access stays punted). Analyzes to a
|
||||
;; :host-call node; the Chez back end lowers it to a jolt-host-call dispatch.
|
||||
(defn- method-head? [nm]
|
||||
|
|
@ -391,11 +391,11 @@
|
|||
|
||||
;; `(Class. args*)` and `(new Class args*)` -> a :host-new node carrying the class
|
||||
;; token and the analyzed args. The Chez back end lowers it to a runtime
|
||||
;; constructor dispatch (jolt-avt6).
|
||||
;; constructor dispatch.
|
||||
(defn- analyze-ctor [ctx class args env]
|
||||
(host-new class (mapv #(analyze ctx % env) args)))
|
||||
|
||||
;; jolt.ffi/__cfn (jolt-ffi): the low-level foreign-function form a jolt library
|
||||
;; jolt.ffi/__cfn: the low-level foreign-function form a jolt library
|
||||
;; uses (via the jolt.ffi/foreign-fn macro) to bind native code. Shape:
|
||||
;; (jolt.ffi/__cfn "c_symbol" [:argtype ...] :rettype) ; non-blocking
|
||||
;; (jolt.ffi/__cfn "c_symbol" [:argtype ...] :rettype :blocking) ; may block
|
||||
|
|
@ -417,8 +417,7 @@
|
|||
;; A symbol member whose name starts with "-" is a field read; otherwise it is a
|
||||
;; method (call with the trailing args). Both lower to a :host-call carrying the
|
||||
;; member name verbatim (the leading "-" survives so the runtime dispatcher reads
|
||||
;; it as a field). The Chez back end dispatches it through record-method-dispatch
|
||||
;; (jolt-kuic).
|
||||
;; it as a field). The Chez back end dispatches it through record-method-dispatch.
|
||||
(defn- analyze-dot [ctx items env]
|
||||
(when (< (count items) 3)
|
||||
(throw (str "Malformed (. target member ...) form")))
|
||||
|
|
@ -457,15 +456,15 @@
|
|||
(var-ref (:ns r) (:name r))
|
||||
;; A non-var qualified ref `Class/member` is a host class static
|
||||
;; (Math/sqrt, Long/MAX_VALUE, System/getenv). The Chez back end
|
||||
;; lowers it to a runtime static dispatch (jolt-avt6).
|
||||
;; lowers it to a runtime static dispatch.
|
||||
(host-static ns nm)))
|
||||
:else (let [r (resolve-global ctx form)]
|
||||
(case (:kind r)
|
||||
:var (var-ref (:ns r) (:name r))
|
||||
:host (host-ref (:name r))
|
||||
;; :unresolved — previously emitted a var-ref that auto-interned
|
||||
;; an UNBOUND var, so a typo'd symbol died later as 'Cannot call
|
||||
;; nil as a function' with no hint which symbol (jolt-2o7.3).
|
||||
;; :unresolved — emitting a var-ref here would auto-intern an
|
||||
;; UNBOUND var, so a typo'd symbol would die later as 'Cannot call
|
||||
;; nil as a function' with no hint which symbol.
|
||||
;; Punt to the interpreter: its resolver raises Clojure's
|
||||
;; 'Unable to resolve symbol' when the form actually runs (at
|
||||
;; eval for top-level forms, at call for fn bodies). A punt
|
||||
|
|
@ -524,7 +523,7 @@
|
|||
(and hname (not shadowed) (form-special? hname))
|
||||
(uncompilable (str "special form " hname))
|
||||
:else
|
||||
;; stamp the list form's source offset onto the :invoke (jolt-fqy)
|
||||
;; stamp the list form's source offset onto the :invoke
|
||||
;; so the success checker can report file:line:col. nil when the
|
||||
;; reader did not record it (synthetic/macro-built forms).
|
||||
(let [n (invoke (analyze ctx head env)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue