JVM-semantics fixes and small cleanups

- take-last / drop-last return seqs, not vectors: take-last wraps in seq; drop-last
  is the JVM (map (fn [x _] x) coll (drop n coll)) form (lazy, () when empty).
- cycle is lazy ((lazy-seq (concat coll (cycle coll)))) so it no longer counts its
  argument and terminates on a lazy/infinite input.
- fold's foldable-call catch uses :default, matching the rest of jolt-core and
  also catching a raw host condition from a folding primitive.
- alts! rejects non-channel ports with a clear error (put specs / :default are
  unsupported) instead of crashing inside ac-poll!.
- Misc: drop the unreachable second getCause clause; jolt-nth on a string raises
  'nth "index out of bounds" like the vector branch; name the inline fixpoint cap;
  bld-sh-capture rejoins lines with newlines; clarify a couple of comments.
This commit is contained in:
Yogthos 2026-06-23 01:36:51 -04:00
parent 524d4cd8d1
commit 14547bd1d5
11 changed files with 642 additions and 616 deletions

View file

@ -32,6 +32,10 @@
(declare analyze)
;; Special forms analyze-special has a dispatch arm for — the subset of the host
;; contract's reserved words (jolt.host/form-special?) the analyzer lowers itself.
;; The two differ deliberately (e.g. interop heads like `new`/`.` are reserved but
;; analyzed in analyze-list), so keep them in sync by intent, not by equality.
(def ^:private handled
#{"quote" "if" "do" "def" "fn*" "let*" "loop*" "recur" "throw" "try"
"syntax-quote" "var" "letfn" "set!" "defmacro"})

View file

@ -23,6 +23,10 @@
reset-escapes! collected-escapes
set-check-mode! take-diags!]]))
;; Cap on inline -> flatten -> scalar-replace -> const-fold iterations. Each pass
;; sets `dirty` when it rewrote something; the loop stops at a clean pass or here.
(def ^:private inline-fixpoint-cap 8)
(defn run-passes
"All passes, in order. The back end applies this to every analyzed form. When
inlining is enabled for the unit (user code under direct-linking),
@ -41,7 +45,7 @@
opt (loop [i 0 n (const-fold node)]
(reset! dirty false)
(let [n2 (const-fold (scalar-replace (flatten-lets (inline-node n ctx))))]
(if (and @dirty (< i 8))
(if (and @dirty (< i inline-fixpoint-cap))
(recur (inc i) n2)
n2)))]
;; a final const-fold after inference propagates any predicate folded to a

View file

@ -46,7 +46,9 @@
folded (when (and ff (pos? (count args)) (every? const-num? args))
(try
{:op :const :val (apply ff (mapv (fn [a] (get a :val)) args))}
(catch Exception e nil)))]
;; :default (not Exception) — match the rest of jolt-core and
;; also catch a raw host condition from a folding primitive.
(catch :default e nil)))]
(or folded n))
(= op :if)