core: variadic bit ops, set? covers sorted sets, if rejects extra forms

Three canonical-conformance fixes from the post-shrink batch:

- bit-and/bit-or/bit-xor/bit-and-not get Clojure's variadic arities as
  20-coll shells folding the binary host ops (now __bit-* seams). 2-arg call
  sites still compile to the native janet op via the backend's native-ops
  table. The passes.clj constant-fold table now names the seams — the public
  fns are overlay and don't exist when the compiler loads (this briefly broke
  every compile-mode init).

- core-set? recognizes the :jolt/sorted-set representation (jolt-dpn):
  (set? (sorted-set 1)) was false, and ifn? on sorted sets inherited the bug.

- (if) / (if test) / (if test then else extra) throw in both the analyzer
  and the interpreter — spec 03-special-forms X1, now marked verified.

Suite 4704 -> 4706; bench and the greeter example benchmark are flat.
This commit is contained in:
Yogthos 2026-06-11 17:04:26 -04:00
parent 621dc8e310
commit c6f6b7deb7
9 changed files with 84 additions and 16 deletions

View file

@ -17,6 +17,25 @@
;; even?/odd? stay in the seed: (filter even? ...) is idiomatic-hot and the
;; overlay versions cost an extra call layer per element (seq-pipe bench 4x).
;; Variadic bit ops — canonical Clojure arities folding the binary host op
;; (__bit-* seams). 2-arg call sites still compile to the native janet op via
;; the backend's native-ops table, so the binary fast path is unchanged.
(defn bit-and
([x y] (__bit-and x y))
([x y & more] (reduce __bit-and (__bit-and x y) more)))
(defn bit-or
([x y] (__bit-or x y))
([x y & more] (reduce __bit-or (__bit-or x y) more)))
(defn bit-xor
([x y] (__bit-xor x y))
([x y & more] (reduce __bit-xor (__bit-xor x y) more)))
(defn bit-and-not
([x y] (__bit-and-not x y))
([x y & more] (reduce __bit-and-not (__bit-and-not x y) more)))
;; The printing family, over two host seams: __write (push a string to *out*)
;; and __pr-str1 (render ONE value readably). The renderer itself stays host —
;; it's representation-coupled (pvec/phm/phs/sorted internals) and shared with

View file

@ -133,11 +133,15 @@
(defn- analyze-special [ctx op items env]
(case op
"quote" (quote-node (second items))
"if" (if-node (analyze ctx (nth items 1) env)
(analyze ctx (nth items 2) env)
(if (> (count items) 3)
(analyze ctx (nth items 3) env)
(const nil)))
"if" (do
;; 2 or 3 argument forms only (spec 03-special-forms X1)
(when (or (< (count items) 3) (> (count items) 4))
(throw (str "Wrong number of args (" (dec (count items)) ") passed to: if")))
(if-node (analyze ctx (nth items 1) env)
(analyze ctx (nth items 2) env)
(if (> (count items) 3)
(analyze ctx (nth items 3) env)
(const nil))))
"do" (analyze-seq ctx (rest items) env)
"throw" (throw-node (analyze ctx (nth items 1) env))
"def" (let [name-sym (nth items 1)]

View file

@ -17,7 +17,10 @@
"<" < ">" > "<=" <= ">=" >= "=" =
"inc" inc "dec" dec
"mod" mod "rem" rem "quot" quot
"bit-and" bit-and "bit-or" bit-or "bit-xor" bit-xor})
;; the __bit-* seams: the PUBLIC bit fns are 20-coll variadic shells now,
;; which don't exist yet when this ns loads. Folding stays 2-arg (a 3+-arg
;; constant call throws arity inside the fold and is left for runtime).
"bit-and" __bit-and "bit-or" __bit-or "bit-xor" __bit-xor})
(defn- const? [n] (= :const (get n :op)))
(defn- const-num? [n] (and (const? n) (number? (get n :val))))