diff --git a/host/chez/bigdec.ss b/host/chez/bigdec.ss index fcc260d..f0a5192 100644 --- a/host/chez/bigdec.ss +++ b/host/chez/bigdec.ss @@ -66,10 +66,7 @@ ;; str drops the M; pr/pr-str keep it. (register-str-render! jbigdec? jbigdec->string) -(define %bd-pr-str jolt-pr-str) -(set! jolt-pr-str (lambda (x) (if (jbigdec? x) (string-append (jbigdec->string x) "M") (%bd-pr-str x)))) -(define %bd-pr-readable jolt-pr-readable) -(set! jolt-pr-readable (lambda (x) (if (jbigdec? x) (string-append (jbigdec->string x) "M") (%bd-pr-readable x)))) +(register-pr-arm! jbigdec? (lambda (x) (string-append (jbigdec->string x) "M"))) ;; class / decimal? (register-class-arm! jbigdec? (lambda (x) "java.math.BigDecimal")) diff --git a/host/chez/dyn-binding.ss b/host/chez/dyn-binding.ss index 5d6653e..5aad938 100644 --- a/host/chez/dyn-binding.ss +++ b/host/chez/dyn-binding.ss @@ -132,12 +132,7 @@ ;; var-cell keys hash/compare by ns/name (jolt=2 in vars.ss already compares ;; ns/name) — stable under root mutation, so a var works as a map key (with-redefs ;; builds (hash-map (var f) v); get-thread-bindings returns a var-keyed map). -(define %dyn-hash jolt-hash) -(set! jolt-hash - (lambda (x) - (if (var-cell? x) - (equal-hash (cons (var-cell-ns x) (var-cell-name x))) - (%dyn-hash x)))) +(register-hash-arm! var-cell? (lambda (x) (equal-hash (cons (var-cell-ns x) (var-cell-name x))))) ;; --- bind the host seams the overlay references ----------------------------- (def-var! "clojure.core" "push-thread-bindings" jolt-push-thread-bindings) diff --git a/host/chez/host-table.ss b/host/chez/host-table.ss index 3e27aa0..0ed61f5 100644 --- a/host/chez/host-table.ss +++ b/host/chez/host-table.ss @@ -153,10 +153,9 @@ (define (sorted-render x render) (if (htable-sorted-map? x) (sorted-map-render x render) (sorted-set-render x render))) -(define %h-pr-readable jolt-pr-readable) -(set! jolt-pr-readable (lambda (x) (if (htable-sorted? x) (sorted-render x jolt-pr-readable) (%h-pr-readable x)))) -(define %h-pr-str jolt-pr-str) -(set! jolt-pr-str (lambda (x) (if (htable-sorted? x) (sorted-render x jolt-pr-str) (%h-pr-str x)))) +;; sorted colls render in :seq order via the calling printer (str vs readable). +(register-pr-readable-arm! htable-sorted? (lambda (x) (sorted-render x jolt-pr-readable))) +(register-pr-str-arm! htable-sorted? (lambda (x) (sorted-render x jolt-pr-str))) (register-str-render! htable-sorted? (lambda (x) (sorted-render x jolt-str-render-one))) ;; --- protocol dispatch over builtins (extend-protocol Map/Set on sorted) ------ diff --git a/host/chez/inst-time.ss b/host/chez/inst-time.ss index 104e286..61c310c 100644 --- a/host/chez/inst-time.ss +++ b/host/chez/inst-time.ss @@ -244,10 +244,7 @@ (register-hash-arm! jinst? (lambda (x) (jolt-hash (jinst-ms x)))) (define (inst-pr i) (string-append "#inst \"" (inst-rfc3339 i) "\"")) -(define %it-pr-str jolt-pr-str) -(set! jolt-pr-str (lambda (x) (if (jinst? x) (inst-pr x) (%it-pr-str x)))) -(define %it-pr-readable jolt-pr-readable) -(set! jolt-pr-readable (lambda (x) (if (jinst? x) (inst-pr x) (%it-pr-readable x)))) +(register-pr-arm! jinst? inst-pr) (register-str-render! jinst? inst-rfc3339) (define %it-type jolt-type) diff --git a/host/chez/io.ss b/host/chez/io.ss index e8a84cf..ab9287b 100644 --- a/host/chez/io.ss +++ b/host/chez/io.ss @@ -487,17 +487,9 @@ ;; str / pr-str of a uri -> its string form. (register-str-render! (lambda (x) (and (jhost? x) (string=? (jhost-tag x) "uri"))) (lambda (x) (uri-field x 'string))) -(define %uri-pr-readable jolt-pr-readable) -(set! jolt-pr-readable - (lambda (x) (if (and (jhost? x) (string=? (jhost-tag x) "uri")) - (string-append "#object[java.net.URI \"" (uri-field x 'string) "\"]") - (%uri-pr-readable x)))) +(register-pr-readable-arm! (lambda (x) (and (jhost? x) (string=? (jhost-tag x) "uri"))) + (lambda (x) (string-append "#object[java.net.URI \"" (uri-field x 'string) "\"]"))) ;; class of the host value types defined by now (uri/uuid/file). -(define %uri-class jolt-class) -(set! jolt-class - (lambda (x) - (cond ((and (jhost? x) (string=? (jhost-tag x) "uri")) "java.net.URI") - ((juuid? x) "java.util.UUID") - ((jfile? x) "java.io.File") - (else (%uri-class x))))) -(def-var! "clojure.core" "class" jolt-class) +(register-class-arm! (lambda (x) (and (jhost? x) (string=? (jhost-tag x) "uri"))) (lambda (x) "java.net.URI")) +(register-class-arm! juuid? (lambda (x) "java.util.UUID")) +(register-class-arm! jfile? (lambda (x) "java.io.File")) diff --git a/host/chez/lazy-bridge.ss b/host/chez/lazy-bridge.ss index 0b2da74..86ed2df 100644 --- a/host/chez/lazy-bridge.ss +++ b/host/chez/lazy-bridge.ss @@ -65,10 +65,9 @@ (set! jolt-nth (case-lambda ((coll i) (if (jolt-lazyseq? coll) (%ls-nth (jolt-seq coll) i) (%ls-nth coll i))) ((coll i d) (if (jolt-lazyseq? coll) (%ls-nth (jolt-seq coll) i d) (%ls-nth coll i d))))) -(define %ls-pr-str jolt-pr-str) -(set! jolt-pr-str (lambda (x) (if (jolt-lazyseq? x) (%ls-pr-str (jolt-seq x)) (%ls-pr-str x)))) -(define %ls-pr-readable jolt-pr-readable) -(set! jolt-pr-readable (lambda (x) (if (jolt-lazyseq? x) (%ls-pr-readable (jolt-seq x)) (%ls-pr-readable x)))) +;; a lazy seq prints as its realized seq — force, then re-dispatch through the printer. +(register-pr-str-arm! jolt-lazyseq? (lambda (x) (jolt-pr-str (jolt-seq x)))) +(register-pr-readable-arm! jolt-lazyseq? (lambda (x) (jolt-pr-readable (jolt-seq x)))) (register-str-render! jolt-lazyseq? (lambda (x) (jolt-str-render-one (jolt-seq x)))) ;; seq? — a lazy seq IS a seq (predicates.ss's jolt-seq? predates the lazyseq diff --git a/host/chez/natives-misc.ss b/host/chez/natives-misc.ss index d610f72..80bb9a2 100644 --- a/host/chez/natives-misc.ss +++ b/host/chez/natives-misc.ss @@ -53,10 +53,7 @@ ;; str of a uuid -> the bare 36-char string; pr-str -> #uuid "…". (register-str-render! juuid? juuid-s) (define (juuid-pr u) (string-append "#uuid \"" (juuid-s u) "\"")) -(define %m-pr-str jolt-pr-str) -(set! jolt-pr-str (lambda (x) (if (juuid? x) (juuid-pr x) (%m-pr-str x)))) -(define %m-pr-readable jolt-pr-readable) -(set! jolt-pr-readable (lambda (x) (if (juuid? x) (juuid-pr x) (%m-pr-readable x)))) +(register-pr-arm! juuid? juuid-pr) ;; two uuids are = iff same string. (register-eq-arm! (lambda (a b) (or (juuid? a) (juuid? b))) (lambda (a b) (and (juuid? a) (juuid? b) (string=? (juuid-s a) (juuid-s b))))) @@ -83,10 +80,7 @@ ((jolt=2 k kw-tl-form) (jtagged-form coll)) (else d)))) (define (jtagged-pr t) (string-append "#" (jolt-pr-str (jtagged-tag t)) " " (jolt-pr-readable (jtagged-form t)))) -(define %m2-pr-str jolt-pr-str) -(set! jolt-pr-str (lambda (x) (if (jtagged? x) (jtagged-pr x) (%m2-pr-str x)))) -(define %m2-pr-readable jolt-pr-readable) -(set! jolt-pr-readable (lambda (x) (if (jtagged? x) (jtagged-pr x) (%m2-pr-readable x)))) +(register-pr-arm! jtagged? jtagged-pr) (def-var! "clojure.core" "tagged-literal" jolt-tagged-literal) ;; tagged-literal? is OVERLAY (reads :jolt/type) — asserted in post-prelude.ss. diff --git a/host/chez/natives-queue.ss b/host/chez/natives-queue.ss index c9170f8..f964bfa 100644 --- a/host/chez/natives-queue.ss +++ b/host/chez/natives-queue.ss @@ -44,8 +44,7 @@ ;; printing: render the elements as a parenthesized list (delegate to the seq path). (define (jolt-seq-or-empty x) (let ((s (jolt-seq x))) (if (jolt-nil? s) jolt-empty-list s))) -(define %q-pr-readable jolt-pr-readable) -(set! jolt-pr-readable (lambda (x) (if (jolt-queue? x) (%q-pr-readable (jolt-seq-or-empty x)) (%q-pr-readable x)))) +(register-pr-readable-arm! jolt-queue? (lambda (x) (jolt-pr-readable (jolt-seq-or-empty x)))) (register-str-render! jolt-queue? (lambda (x) (jolt-str-render-one (jolt-seq-or-empty x)))) ;; class / type / instance? recognize a queue. diff --git a/host/chez/ns.ss b/host/chez/ns.ss index e36c1bc..e4fdfdf 100644 --- a/host/chez/ns.ss +++ b/host/chez/ns.ss @@ -344,8 +344,5 @@ (def-var! "clojure.core" "*ns*" (intern-ns! "user")) ;; --- printer patches: a namespace renders as its name (str / pr-str / -e) ---- -(define %ns-pr-str jolt-pr-str) -(set! jolt-pr-str (lambda (x) (if (jns? x) (jns-name x) (%ns-pr-str x)))) -(define %ns-pr-readable jolt-pr-readable) -(set! jolt-pr-readable (lambda (x) (if (jns? x) (jns-name x) (%ns-pr-readable x)))) +(register-pr-arm! jns? jns-name) (register-str-render! jns? jns-name) diff --git a/host/chez/printing.ss b/host/chez/printing.ss index 8402f94..ae1a880 100644 --- a/host/chez/printing.ss +++ b/host/chez/printing.ss @@ -24,7 +24,16 @@ ((#\return) (cons #\r (cons #\\ acc))) (else (cons c acc)))))))) -(define (jolt-pr-readable x) +;; A host shim registers a type's readable rendering via register-pr-readable-arm!, +;; or register-pr-arm! for types whose str and readable forms match (most host types: +;; inst, uuid, record, var, …). Disjoint types, checked before the base cases. +(define jolt-pr-readable-arms '()) +(define (register-pr-readable-arm! pred render) + (set! jolt-pr-readable-arms (cons (cons pred render) jolt-pr-readable-arms))) +(define (register-pr-arm! pred render) + (register-pr-str-arm! pred render) + (register-pr-readable-arm! pred render)) +(define (jolt-pr-readable-base x) (cond ((string? x) (string-append "\"" (jolt-str-escape x) "\"")) ;; pr renders the infinities / NaN in READABLE form (##Inf reads back), unlike @@ -58,6 +67,11 @@ (if (jolt-nil? s) (reverse acc) (loop (jolt-seq (seq-more s)) (cons (jolt-pr-readable (seq-first s)) acc))))) ")")) (else (jolt-pr-str x)))) +(define (jolt-pr-readable x) + (let loop ((as jolt-pr-readable-arms)) + (cond ((null? as) (jolt-pr-readable-base x)) + (((caar as) x) ((cdar as) x)) + (else (loop (cdr as)))))) ;; __pr-str1: render ONE value readably (the overlay's pr-str joins these). (define (jolt-pr-str1 x) (jolt-pr-readable x)) diff --git a/host/chez/records.ss b/host/chez/records.ss index 2f94604..eb21e91 100644 --- a/host/chez/records.ss +++ b/host/chez/records.ss @@ -83,10 +83,7 @@ (define %r-jolt-conj1 jolt-conj1) (set! jolt-conj1 (lambda (coll x) (if (jrec? coll) (jolt-assoc1 coll (jolt-nth x 0) (jolt-nth x 1)) (%r-jolt-conj1 coll x)))) -(define %r-jolt-pr-str jolt-pr-str) -(set! jolt-pr-str (lambda (x) (if (jrec? x) (jrec-pr x) (%r-jolt-pr-str x)))) -(define %r-jolt-pr-readable jolt-pr-readable) -(set! jolt-pr-readable (lambda (x) (if (jrec? x) (jrec-pr x) (%r-jolt-pr-readable x)))) +(register-pr-arm! jrec? jrec-pr) ;; records are map? and coll? (Clojure: a record IS an associative map). The ;; predicates.ss vars hold a snapshot, so re-def-var! after extending. record? is diff --git a/host/chez/rt.ss b/host/chez/rt.ss index 5a0dae0..cd544b6 100644 --- a/host/chez/rt.ss +++ b/host/chez/rt.ss @@ -179,7 +179,13 @@ ;; bare nil renders as the empty string (a nil ELEMENT inside a collection still ;; prints "nil", which jolt-pr-str handles). (define (jolt-final-str x) (if (jolt-nil? x) "" (jolt-pr-str x))) -(define (jolt-pr-str x) +;; A host shim registers a type's str-style rendering via register-pr-str-arm! (or +;; register-pr-arm! in printing.ss for both printers at once) instead of +;; set!-wrapping jolt-pr-str. Disjoint types, checked before the base cases. +(define jolt-pr-str-arms '()) +(define (register-pr-str-arm! pred render) + (set! jolt-pr-str-arms (cons (cons pred render) jolt-pr-str-arms))) +(define (jolt-pr-str-base x) (cond ((jolt-nil? x) "nil") ((eq? x #t) "true") @@ -206,6 +212,11 @@ (if (jolt-nil? s) (reverse acc) (loop (jolt-seq (seq-more s)) (cons (jolt-pr-str (seq-first s)) acc))))) ")")) (else (format "~a" x)))) +(define (jolt-pr-str x) + (let loop ((as jolt-pr-str-arms)) + (cond ((null? as) (jolt-pr-str-base x)) + (((caar as) x) ((cdar as) x)) + (else (loop (cdr as)))))) ;; converters + string ops: str/subs/vec/keyword/symbol/compare/int/ ;; double/gensym — host-coupled seed natives def-var!'d into clojure.core. Loaded diff --git a/host/chez/transients.ss b/host/chez/transients.ss index ab045f9..5c40624 100644 --- a/host/chez/transients.ss +++ b/host/chez/transients.ss @@ -169,11 +169,7 @@ ;; Redefine the native get/count/contains?/nth (captured first) so the existing ;; emit lowerings unwrap a transient; non-transients are untouched. -(define %prev-jolt-get jolt-get) -(set! jolt-get - (case-lambda - ((coll k) (if (jolt-transient? coll) (t-get coll k jolt-nil) (%prev-jolt-get coll k))) - ((coll k d) (if (jolt-transient? coll) (t-get coll k d) (%prev-jolt-get coll k d))))) +(register-get-arm! jolt-transient? (lambda (coll k d) (t-get coll k d))) (define %prev-jolt-count jolt-count) (set! jolt-count (lambda (coll) (if (jolt-transient? coll) (t-count coll) (%prev-jolt-count coll)))) (define %prev-jolt-contains? jolt-contains?) diff --git a/host/chez/vars.ss b/host/chez/vars.ss index 1d53ed8..0876ba2 100644 --- a/host/chez/vars.ss +++ b/host/chez/vars.ss @@ -38,10 +38,7 @@ ;; pr-str / str of a var -> #'ns/name. (define (var->str v) (string-append "#'" (var-cell-ns v) "/" (var-cell-name v))) -(define %v-pr-str jolt-pr-str) -(set! jolt-pr-str (lambda (x) (if (var-cell? x) (var->str x) (%v-pr-str x)))) -(define %v-pr-readable jolt-pr-readable) -(set! jolt-pr-readable (lambda (x) (if (var-cell? x) (var->str x) (%v-pr-readable x)))) +(register-pr-arm! var-cell? var->str) (register-str-render! var-cell? var->str) ;; bound? — native (the overlay's (get v :root) is nil on a var-cell record).