mutable deftype fields: (set! field val) in a method
deftype fields tagged ^:unsynchronized-mutable / ^:volatile-mutable can now be reassigned in place from a method, as on the JVM. A jrec stores fields as cons cells, so a new jolt-set-field! mutates the pair with set-cdr!. The deftype macro rewrites (set! mutable-field v) in a method body to (set! (.-field inst) v), and the analyzer compiles a (set! (.-field obj) v) target to jolt-set-field! — so both the rewritten symbol form and an explicit interop (set! (.-root this) v) go through one path. Field reads remain a snapshot at method entry, which is correct for the universal read-then-set pattern (a repeated set! of the same field in one call would read the entry value). Closes the set!-of-local SCI failures: SCI load 202 -> 205/218.
This commit is contained in:
parent
b9ab750983
commit
424ce75cf6
9 changed files with 416 additions and 371 deletions
|
|
@ -28,6 +28,16 @@
|
|||
(define (jrec-has? r k)
|
||||
(let loop ((ps (jrec-pairs r)))
|
||||
(cond ((null? ps) #f) ((jolt=2 (caar ps) k) #t) (else (loop (cdr ps))))))
|
||||
;; mutate a deftype's mutable field in place (jolt-c3q): the pairs are runtime
|
||||
;; cons cells, so set-cdr! updates the field. (set! field v) inside a method
|
||||
;; lowers to this; returns v, as set! does.
|
||||
(define (jolt-set-field! inst k v)
|
||||
(if (jrec? inst)
|
||||
(let loop ((ps (jrec-pairs inst)))
|
||||
(cond ((null? ps) (error #f "set! of an unknown field" k))
|
||||
((jolt=2 (caar ps) k) (set-cdr! (car ps) v) v)
|
||||
(else (loop (cdr ps)))))
|
||||
(error #f "set! of a field on a non-record" inst)))
|
||||
(define (jrec-replace pairs k v) ; replace existing field (keep order) or append
|
||||
(let loop ((ps pairs) (acc '()) (hit #f))
|
||||
(cond ((null? ps) (reverse (if hit acc (cons (cons k v) acc))))
|
||||
|
|
@ -329,6 +339,7 @@
|
|||
(def-var! "clojure.core" "register-protocol-methods!" register-protocol-methods!)
|
||||
(def-var! "clojure.core" "register-method" register-method)
|
||||
(def-var! "clojure.core" "register-inline-method" register-inline-method)
|
||||
(def-var! "jolt.host" "set-field!" jolt-set-field!)
|
||||
(def-var! "clojure.core" "protocol-dispatch" (lambda (pn mn obj rest) (protocol-dispatch pn mn obj rest)))
|
||||
(def-var! "clojure.core" "satisfies?" jolt-satisfies?)
|
||||
(def-var! "clojure.core" "extenders" extenders)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
;; run-sci.ss — SCI conformance: load borkdude/sci's own source (vendor/sci) through
|
||||
;; joltc and require its forms to compile+eval. A real-world Clojure-compatibility
|
||||
;; stress test. Pure Chez, no Janet. Floor-gated like the corpus: a regression below
|
||||
;; the floor (or the count today, 202/218) fails. Raise the floor as host gaps close
|
||||
;; the floor (or the count today, 205/218) fails. Raise the floor as host gaps close
|
||||
;; (the tail is genuine gaps — set! on vars, some macro/def shapes).
|
||||
;;
|
||||
;; chez --script host/chez/run-sci.ss
|
||||
;; JOLT_SCI_FLOOR=N override the floor (default 202)
|
||||
;; JOLT_SCI_FLOOR=N override the floor (default 205)
|
||||
;; SCI_VERBOSE=1 print each failing form's error
|
||||
(import (chezscheme))
|
||||
|
||||
|
|
@ -74,7 +74,7 @@
|
|||
load-order)
|
||||
|
||||
(printf "\nSCI load: ~a/~a forms ok (~a fail)\n" total-ok (+ total-ok total-fail) total-fail)
|
||||
(define floor (let ((s (getenv "JOLT_SCI_FLOOR"))) (if s (string->number s) 202)))
|
||||
(define floor (let ((s (getenv "JOLT_SCI_FLOOR"))) (if s (string->number s) 205)))
|
||||
(when (< total-ok floor)
|
||||
(printf "REGRESSION: ~a forms loaded < floor ~a\n" total-ok floor))
|
||||
(flush-output-port)
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue