Chez Phase 2 (inc H): volatiles + sequence/transduce
sequence and transduce were seed natives nil on the prelude; the stateful transducer arities (take-nth/map-indexed/partition-by, overlay) drive a volatile via volatile!/vswap!/vreset!/deref, also unshimmed — so the whole (sequence xform coll) / (transduce xform f coll) surface crashed. natives-xform.ss: native volatiles (a jvol record + volatile!/vreset!/ vswap!/volatile? + a deref arm); transduce/sequence built on the existing into-xform / reduce-seq. The overlay vreset!/vswap!/volatile? drive a volatile through ref-put!/:jolt/type (tagged-table only), so they're overridden natively in post-prelude.ss. driver.janet: drain each chez pipe to EOF instead of a single ev/read. A program with a stdout side effect (newline) flushes in two writes and a lone ev/read sometimes caught only the first chunk, dropping the trailing value — an intermittent gate divergence. Now reads until the pipe closes. Prelude parity 1886 -> 1898, 0 new divergences. Floor raised to 1898.
This commit is contained in:
parent
e434a7d352
commit
6581df2d17
5 changed files with 83 additions and 7 deletions
|
|
@ -66,6 +66,16 @@
|
|||
(def final-scm (emit/emit (backend/analyze-form ctx (in forms (- n 1)))))
|
||||
(emit/program def-scm final-scm))
|
||||
|
||||
# Drain a pipe to EOF. A single (ev/read pipe N) can return BEFORE the child has
|
||||
# flushed everything — a program with a stdout side effect (newline/print) flushes
|
||||
# in two writes, and the first ev/read sometimes catches only the first chunk, so
|
||||
# the trailing real value is lost (intermittent gate divergence). Loop until EOF.
|
||||
(defn- drain [pipe]
|
||||
(def b @"")
|
||||
(var c (ev/read pipe 0x10000))
|
||||
(while c (buffer/push b c) (set c (ev/read pipe 0x10000)))
|
||||
(string b))
|
||||
|
||||
(defn run-on-chez
|
||||
"Compile `src` and run it on Chez; returns [exit-code stdout stderr]."
|
||||
[ctx src &opt scheme-out]
|
||||
|
|
@ -73,10 +83,10 @@
|
|||
(def path (or scheme-out "/tmp/chez-jolt-prog.ss"))
|
||||
(spit path prog)
|
||||
(def proc (os/spawn ["chez" "--script" path] :p {:out :pipe :err :pipe}))
|
||||
(def out (ev/read (proc :out) 0x100000))
|
||||
(def err (ev/read (proc :err) 0x100000))
|
||||
(def out (drain (proc :out)))
|
||||
(def err (drain (proc :err)))
|
||||
(def code (os/proc-wait proc))
|
||||
[code (string/trim (if out (string out) "")) (string/trim (if err (string err) ""))])
|
||||
[code (string/trim out) (string/trim err)])
|
||||
|
||||
# --- clojure.core prelude assembly (jolt-9ziu) --------------------------------
|
||||
# The -e-capable jolt-chez path: emit EVERY non-macro clojure.core form across
|
||||
|
|
@ -172,7 +182,7 @@
|
|||
path (or scheme-out (string "/tmp/jolt-chez-e-" (os/getpid) ".ss"))]
|
||||
(spit path prog)
|
||||
(def proc (os/spawn ["chez" "--script" path] :p {:out :pipe :err :pipe}))
|
||||
(def out (ev/read (proc :out) 0x100000))
|
||||
(def err (ev/read (proc :err) 0x100000))
|
||||
(def out (drain (proc :out)))
|
||||
(def err (drain (proc :err)))
|
||||
(def code (os/proc-wait proc))
|
||||
[code (string/trim (if out (string out) "")) (string/trim (if err (string err) ""))])))
|
||||
[code (string/trim out) (string/trim err)])))
|
||||
|
|
|
|||
51
host/chez/natives-xform.ss
Normal file
51
host/chez/natives-xform.ss
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
;; volatiles + sequence / transduce (jolt-cf1q.3, jolt-xjx6) — the transducer
|
||||
;; application surface.
|
||||
;;
|
||||
;; `sequence` and `transduce` are seed natives that were jolt-nil on the prelude.
|
||||
;; The stateful transducer arities (take-nth/map-indexed/partition-by/dedupe/
|
||||
;; distinct, all overlay) use volatile!/vswap!/vreset!/deref, also unshimmed — so
|
||||
;; the whole (sequence xform coll) / (transduce xform f coll) surface crashed.
|
||||
;;
|
||||
;; Volatiles are a native mutable box (jvol) — the overlay vreset!/vswap! drive a
|
||||
;; volatile through jolt.host/ref-put!+get, but a Chez volatile is a record, not a
|
||||
;; tagged table, so those overlay versions are overridden natively in
|
||||
;; post-prelude.ss. transduce/sequence build on the existing into-xform / reduce-
|
||||
;; seq machinery (natives-seq.ss / seq.ss). Loaded after those + atoms.ss (deref).
|
||||
|
||||
;; --- volatiles ---------------------------------------------------------------
|
||||
(define-record-type jvol (fields (mutable v)) (nongenerative chez-jvol-v1))
|
||||
(define (jolt-volatile! x) (make-jvol x))
|
||||
(define (jolt-vreset! vol x) (jvol-v-set! vol x) x)
|
||||
(define (jolt-vswap! vol f . args)
|
||||
(let ((nv (apply jolt-invoke f (jvol-v vol) args))) (jvol-v-set! vol nv) nv))
|
||||
(define (jolt-volatile-pred? x) (jvol? x))
|
||||
;; deref reads a volatile too (partition-all/-by transducers @-deref their box).
|
||||
(define %xf-deref jolt-deref)
|
||||
(set! jolt-deref (lambda (x) (if (jvol? x) (jvol-v x) (%xf-deref x))))
|
||||
|
||||
(def-var! "clojure.core" "volatile!" jolt-volatile!)
|
||||
(def-var! "clojure.core" "deref" jolt-deref)
|
||||
|
||||
;; --- transduce / sequence ----------------------------------------------------
|
||||
;; (transduce xform f coll) / (transduce xform f init coll): build the transformed
|
||||
;; reducing fn (xform f), reduce it over coll (reduce-seq honors `reduced`), then
|
||||
;; run the completion (1-arg) arity. The 3-arg init defaults to (f) — the rf's
|
||||
;; 0-arity, e.g. (+) = 0, (conj) = [].
|
||||
(define jolt-transduce
|
||||
(case-lambda
|
||||
((xform f coll) (jolt-transduce xform f (jolt-invoke f) coll))
|
||||
((xform f init coll)
|
||||
(let* ((xf (jolt-invoke xform f))
|
||||
(res (reduce-seq xf init (jolt-seq coll))))
|
||||
(jolt-invoke xf res)))))
|
||||
|
||||
;; (sequence coll) -> a seq; (sequence xform coll) -> coll transformed by xform.
|
||||
;; Materialized eagerly through into-xform then seq'd (corpus inputs are finite; a
|
||||
;; fully-lazy pull is future work). Honors reduced via into-xform/reduce-seq.
|
||||
(define jolt-sequence
|
||||
(case-lambda
|
||||
((coll) (jolt-seq coll))
|
||||
((xform coll) (jolt-seq (into-xform (jolt-vector) xform coll)))))
|
||||
|
||||
(def-var! "clojure.core" "transduce" jolt-transduce)
|
||||
(def-var! "clojure.core" "sequence" jolt-sequence)
|
||||
|
|
@ -13,3 +13,9 @@
|
|||
;; override.)
|
||||
(def-var! "clojure.core" "char?" jolt-char-pred?)
|
||||
(def-var! "clojure.core" "atom?" jolt-atom?)
|
||||
;; volatiles: a Chez volatile is a jvol record, but the overlay vreset!/vswap!/
|
||||
;; volatile? drive it via jolt.host/ref-put!+get / :jolt/type (tagged-table only).
|
||||
;; Override with the native versions (defined in natives-xform.ss).
|
||||
(def-var! "clojure.core" "vreset!" jolt-vreset!)
|
||||
(def-var! "clojure.core" "vswap!" jolt-vswap!)
|
||||
(def-var! "clojure.core" "volatile?" jolt-volatile-pred?)
|
||||
|
|
|
|||
|
|
@ -212,3 +212,8 @@
|
|||
;; iterate/cycle/dedupe/take-nth/keep/interpose/reductions/tree-seq/lazy-cat).
|
||||
;; Loaded LAST so %ls-seq captures the fully-extended (sorted-aware) jolt-seq.
|
||||
(load "host/chez/lazy-bridge.ss")
|
||||
|
||||
;; volatiles + sequence / transduce (jolt-xjx6, Phase 2): native volatile boxes +
|
||||
;; the transduce/sequence entry points over into-xform/reduce-seq. After
|
||||
;; natives-seq.ss (into-xform), seq.ss (reduce-seq) + atoms.ss (deref).
|
||||
(load "host/chez/natives-xform.ss")
|
||||
|
|
|
|||
|
|
@ -176,8 +176,12 @@
|
|||
# referential lazy-cat (fib) stays productive. Unblocks repeat/iterate/cycle/
|
||||
# dedupe/take-nth/keep/interpose/reductions/map-indexed/distinct/interleave/
|
||||
# tree-seq->flatten/partition-all/lazy-cat) 1886.
|
||||
# Phase 2 inc H (jolt-xjx6: native volatiles (jvol) + sequence/transduce over the
|
||||
# existing into-xform/reduce-seq — unblocks (sequence xform coll), (transduce
|
||||
# xform f coll), and the stateful transducer xforms take-nth/map-indexed/
|
||||
# partition-by that drive a volatile) 1898.
|
||||
# Strided runs scale down.
|
||||
(def base-floor (scan-number (or (os/getenv "JOLT_CHEZ_PRELUDE_FLOOR") "1886")))
|
||||
(def base-floor (scan-number (or (os/getenv "JOLT_CHEZ_PRELUDE_FLOOR") "1898")))
|
||||
(def floor (if (os/getenv "JOLT_CORPUS_LIMIT") 0 base-floor))
|
||||
(when (or (> (length diverged) 0) (< pass floor))
|
||||
(printf "REGRESSION: pass %d < floor %d or %d new divergence(s)" pass floor (length diverged)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue