refactor: rename dynamic-vars.ss, extract natives-format.ss (jolt-7dkx)
Two small clarity moves from the review: - dynamic-vars.ss -> dynamic-var-defaults.ss. It holds the default VALUES of a few core dynamic vars (*clojure-version*, *assert*, …); the near-identical dyn-binding.ss holds the binding-stack machinery. The names were easy to confuse. - Pull the ~60-line %-format engine out of the natives-misc.ss grab-bag into natives-format.ss (its ->long/pad-left/fmt-float helpers were local to it). rt.ss loads + MODULES.md updated. Runtime .ss, no re-mint; make test green, format + the dynamic vars verified.
This commit is contained in:
parent
960d8b6e24
commit
43a0da4dd0
5 changed files with 77 additions and 69 deletions
|
|
@ -26,10 +26,10 @@ composed and where a given `.ss` fits.
|
||||||
- **Value model**: `values.ss` (nil/numbers/keywords/symbols), `collections.ss`
|
- **Value model**: `values.ss` (nil/numbers/keywords/symbols), `collections.ss`
|
||||||
(persistent vec + HAMT map/set), `seq.ss` + `lazy-bridge.ss` (seqs, lazy-seqs),
|
(persistent vec + HAMT map/set), `seq.ss` + `lazy-bridge.ss` (seqs, lazy-seqs),
|
||||||
`transients.ss`, `records.ss` + `records-interop.ss`.
|
`transients.ss`, `records.ss` + `records-interop.ss`.
|
||||||
- **Native `clojure.core` shims**: `natives-*.ss` (array/coll/meta/misc/num/parity/
|
- **Native `clojure.core` shims**: `natives-*.ss` (array/coll/format/meta/misc/num/
|
||||||
queue/seq/str/xform), plus `predicates.ss`, `converters.ss`, `printing.ss`.
|
queue/reader/seq/str/transduce), plus `predicates.ss`, `converters.ss`, `printing.ss`.
|
||||||
- **Vars / namespaces / dynamics**: `vars.ss`, `ns.ss`, `dyn-binding.ss` (the
|
- **Vars / namespaces / dynamics**: `vars.ss`, `ns.ss`, `dyn-binding.ss` (the
|
||||||
thread-local binding stack), `dynamic-vars.ss` (a few `*…*` constant defaults),
|
thread-local binding stack), `dynamic-var-defaults.ss` (a few `*…*` constant defaults),
|
||||||
`atoms.ss`, `multimethods.ss`.
|
`atoms.ss`, `multimethods.ss`.
|
||||||
- **Host interop**: `host-class.ss` (class tokens + method dispatch),
|
- **Host interop**: `host-class.ss` (class tokens + method dispatch),
|
||||||
`host-static.ss` (interop registry core) + `host-static-methods.ss` (`Class/member`
|
`host-static.ss` (interop registry core) + `host-static-methods.ss` (`Class/member`
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
;; dynamic vars — the handful of clojure.core dynamic vars that aren't emitted into
|
;; dynamic-var-defaults.ss — default values for the handful of clojure.core dynamic
|
||||||
;; the prelude. These two are plain constants; *ns* (a namespace object) needs a
|
;; vars that aren't emitted into the prelude (*clojure-version*, *assert*, …). Plain
|
||||||
;; value type with get-see-through and map?=false and is tracked separately. Loaded
|
;; constant def-var!s; *ns* (a namespace object) needs a value type with
|
||||||
|
;; get-see-through and map?=false and is tracked separately. The binding-stack
|
||||||
|
;; machinery (binding / var-set / thread-bound?) lives in dyn-binding.ss. Loaded
|
||||||
;; from rt.ss after the value model + def-var!.
|
;; from rt.ss after the value model + def-var!.
|
||||||
|
|
||||||
;; *clojure-version* — a map {:major 1 :minor 11 :incremental 0 :qualifier nil}.
|
;; *clojure-version* — a map {:major 1 :minor 11 :incremental 0 :qualifier nil}.
|
||||||
62
host/chez/natives-format.ss
Normal file
62
host/chez/natives-format.ss
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
;; natives-format.ss — a small %-format engine for clojure.core `format` over the
|
||||||
|
;; all-flonum number model: %d (integer), %s (str), %f / %.Nf (fixed-point), %x/%X
|
||||||
|
;; (hex int), %o (octal), %c (char int), %b (boolean), %% (literal). Enough for the
|
||||||
|
;; corpus, not the full Java Formatter spec. Loaded after natives-misc.ss (uses
|
||||||
|
;; jolt-str-render-one via converters + jolt-truthy?).
|
||||||
|
|
||||||
|
(define (->long x) (exact (truncate x)))
|
||||||
|
(define (pad-left s n c) (if (fx>=? (string-length s) n) s (string-append (make-string (fx- n (string-length s)) c) s)))
|
||||||
|
(define (fmt-float x prec)
|
||||||
|
(let* ((neg (< x 0)) (ax (abs x))
|
||||||
|
(scale (expt 10 prec))
|
||||||
|
(scaled (round (* (inexact ax) scale)))
|
||||||
|
(i (exact (truncate (/ scaled scale))))
|
||||||
|
(frac (exact (truncate (- scaled (* i scale))))))
|
||||||
|
(string-append (if neg "-" "")
|
||||||
|
(number->string i)
|
||||||
|
(if (fx>? prec 0) (string-append "." (pad-left (number->string frac) prec #\0)) ""))))
|
||||||
|
(define (jolt-format fmt . args)
|
||||||
|
(let ((out (open-output-string)))
|
||||||
|
(let loop ((i 0) (as args))
|
||||||
|
(if (fx>=? i (string-length fmt))
|
||||||
|
(get-output-string out)
|
||||||
|
(let ((c (string-ref fmt i)))
|
||||||
|
(if (char=? c #\%)
|
||||||
|
;; parse a directive: %[-][0][width][.prec]conv
|
||||||
|
(let scan ((j (fx+ i 1)) (left #f) (zero #f) (width #f) (prec #f) (seen-dot #f))
|
||||||
|
(let ((d (string-ref fmt j)))
|
||||||
|
(cond
|
||||||
|
((char=? d #\%) (write-char #\% out) (loop (fx+ j 1) as))
|
||||||
|
((and (not seen-dot) (not width) (char=? d #\-))
|
||||||
|
(scan (fx+ j 1) #t zero width prec seen-dot))
|
||||||
|
((and (not seen-dot) (not width) (char=? d #\0))
|
||||||
|
(scan (fx+ j 1) left #t width prec seen-dot))
|
||||||
|
((char=? d #\.) (scan (fx+ j 1) left zero width 0 #t))
|
||||||
|
((and (char>=? d #\0) (char<=? d #\9))
|
||||||
|
(if seen-dot
|
||||||
|
(scan (fx+ j 1) left zero width (fx+ (fx* (or prec 0) 10) (fx- (char->integer d) 48)) seen-dot)
|
||||||
|
(scan (fx+ j 1) left zero (fx+ (fx* (or width 0) 10) (fx- (char->integer d) 48)) prec seen-dot)))
|
||||||
|
(else
|
||||||
|
(let* ((a (if (null? as) jolt-nil (car as)))
|
||||||
|
(rest (if (null? as) '() (cdr as)))
|
||||||
|
(s (case d
|
||||||
|
((#\d) (number->string (->long a)))
|
||||||
|
((#\s) (jolt-str-render-one a))
|
||||||
|
((#\f) (fmt-float a (or prec 6)))
|
||||||
|
((#\x) (number->string (->long a) 16))
|
||||||
|
((#\X) (string-upcase (number->string (->long a) 16)))
|
||||||
|
((#\o) (number->string (->long a) 8))
|
||||||
|
((#\b) (if (jolt-truthy? a) "true" "false"))
|
||||||
|
((#\c) (string (integer->char (->long a))))
|
||||||
|
(else (string #\% d))))
|
||||||
|
;; pad to width: left-justify with spaces, else right-justify
|
||||||
|
;; (zero-pad only a right-justified number).
|
||||||
|
(s (if (and width (fx<? (string-length s) width))
|
||||||
|
(let ((p (fx- width (string-length s))))
|
||||||
|
(if left (string-append s (make-string p #\space))
|
||||||
|
(string-append (make-string p (if (and zero (memv d '(#\d #\f #\x #\X #\o))) #\0 #\space)) s)))
|
||||||
|
s)))
|
||||||
|
(display s out)
|
||||||
|
(loop (fx+ j 1) rest))))))
|
||||||
|
(begin (write-char c out) (loop (fx+ i 1) as))))))))
|
||||||
|
(def-var! "clojure.core" "format" jolt-format)
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
;; misc scalar natives — UUID, format/printf, tagged-literal, bigint.
|
;; misc scalar natives — UUID, tagged-literal, bigint, and the hash API. (format /
|
||||||
|
;; printf moved to natives-format.ss.)
|
||||||
;;
|
;;
|
||||||
;; Loaded after the printers (pr-str of a uuid is #uuid "…") and converters
|
;; Loaded after the printers (pr-str of a uuid is #uuid "…") and converters
|
||||||
;; (jolt-str-render-one for %s / str of a uuid).
|
;; (jolt-str-render-one for %s / str of a uuid).
|
||||||
|
|
@ -84,67 +85,6 @@
|
||||||
(def-var! "clojure.core" "tagged-literal" jolt-tagged-literal)
|
(def-var! "clojure.core" "tagged-literal" jolt-tagged-literal)
|
||||||
;; tagged-literal? is OVERLAY (reads :jolt/type) — asserted in post-prelude.ss.
|
;; tagged-literal? is OVERLAY (reads :jolt/type) — asserted in post-prelude.ss.
|
||||||
|
|
||||||
;; --- format / printf ---------------------------------------------------------
|
|
||||||
;; A small %-format engine over the all-flonum number model: %d (integer), %s
|
|
||||||
;; (str), %f / %.Nf (fixed-point), %x/%X (hex int), %o (octal), %c (char int),
|
|
||||||
;; %b (boolean), %% (literal). Enough for the corpus; not the full Java spec.
|
|
||||||
(define (->long x) (exact (truncate x)))
|
|
||||||
(define (pad-left s n c) (if (fx>=? (string-length s) n) s (string-append (make-string (fx- n (string-length s)) c) s)))
|
|
||||||
(define (fmt-float x prec)
|
|
||||||
(let* ((neg (< x 0)) (ax (abs x))
|
|
||||||
(scale (expt 10 prec))
|
|
||||||
(scaled (round (* (inexact ax) scale)))
|
|
||||||
(i (exact (truncate (/ scaled scale))))
|
|
||||||
(frac (exact (truncate (- scaled (* i scale))))))
|
|
||||||
(string-append (if neg "-" "")
|
|
||||||
(number->string i)
|
|
||||||
(if (fx>? prec 0) (string-append "." (pad-left (number->string frac) prec #\0)) ""))))
|
|
||||||
(define (jolt-format fmt . args)
|
|
||||||
(let ((out (open-output-string)))
|
|
||||||
(let loop ((i 0) (as args))
|
|
||||||
(if (fx>=? i (string-length fmt))
|
|
||||||
(get-output-string out)
|
|
||||||
(let ((c (string-ref fmt i)))
|
|
||||||
(if (char=? c #\%)
|
|
||||||
;; parse a directive: %[-][0][width][.prec]conv
|
|
||||||
(let scan ((j (fx+ i 1)) (left #f) (zero #f) (width #f) (prec #f) (seen-dot #f))
|
|
||||||
(let ((d (string-ref fmt j)))
|
|
||||||
(cond
|
|
||||||
((char=? d #\%) (write-char #\% out) (loop (fx+ j 1) as))
|
|
||||||
((and (not seen-dot) (not width) (char=? d #\-))
|
|
||||||
(scan (fx+ j 1) #t zero width prec seen-dot))
|
|
||||||
((and (not seen-dot) (not width) (char=? d #\0))
|
|
||||||
(scan (fx+ j 1) left #t width prec seen-dot))
|
|
||||||
((char=? d #\.) (scan (fx+ j 1) left zero width 0 #t))
|
|
||||||
((and (char>=? d #\0) (char<=? d #\9))
|
|
||||||
(if seen-dot
|
|
||||||
(scan (fx+ j 1) left zero width (fx+ (fx* (or prec 0) 10) (fx- (char->integer d) 48)) seen-dot)
|
|
||||||
(scan (fx+ j 1) left zero (fx+ (fx* (or width 0) 10) (fx- (char->integer d) 48)) prec seen-dot)))
|
|
||||||
(else
|
|
||||||
(let* ((a (if (null? as) jolt-nil (car as)))
|
|
||||||
(rest (if (null? as) '() (cdr as)))
|
|
||||||
(s (case d
|
|
||||||
((#\d) (number->string (->long a)))
|
|
||||||
((#\s) (jolt-str-render-one a))
|
|
||||||
((#\f) (fmt-float a (or prec 6)))
|
|
||||||
((#\x) (number->string (->long a) 16))
|
|
||||||
((#\X) (string-upcase (number->string (->long a) 16)))
|
|
||||||
((#\o) (number->string (->long a) 8))
|
|
||||||
((#\b) (if (jolt-truthy? a) "true" "false"))
|
|
||||||
((#\c) (string (integer->char (->long a))))
|
|
||||||
(else (string #\% d))))
|
|
||||||
;; pad to width: left-justify with spaces, else right-justify
|
|
||||||
;; (zero-pad only a right-justified number).
|
|
||||||
(s (if (and width (fx<? (string-length s) width))
|
|
||||||
(let ((p (fx- width (string-length s))))
|
|
||||||
(if left (string-append s (make-string p #\space))
|
|
||||||
(string-append (make-string p (if (and zero (memv d '(#\d #\f #\x #\X #\o))) #\0 #\space)) s)))
|
|
||||||
s)))
|
|
||||||
(display s out)
|
|
||||||
(loop (fx+ j 1) rest))))))
|
|
||||||
(begin (write-char c out) (loop (fx+ i 1) as))))))))
|
|
||||||
(def-var! "clojure.core" "format" jolt-format)
|
|
||||||
|
|
||||||
;; --- hash family (24-bit masked so int? holds) -------------------------------
|
;; --- hash family (24-bit masked so int? holds) -------------------------------
|
||||||
;; The public hash API over jolt-hash (values.ss). hash-ordered/-unordered-coll
|
;; The public hash API over jolt-hash (values.ss). hash-ordered/-unordered-coll
|
||||||
;; fold the element hashes the way Clojure's IHash mixers do.
|
;; fold the element hashes the way Clojure's IHash mixers do.
|
||||||
|
|
|
||||||
|
|
@ -272,7 +272,7 @@
|
||||||
|
|
||||||
;; dynamic vars: *clojure-version* / *unchecked-math* constants the host
|
;; dynamic vars: *clojure-version* / *unchecked-math* constants the host
|
||||||
;; binds natively. After collections.ss (jolt-hash-map) + def-var!.
|
;; binds natively. After collections.ss (jolt-hash-map) + def-var!.
|
||||||
(load "host/chez/dynamic-vars.ss")
|
(load "host/chez/dynamic-var-defaults.ss")
|
||||||
|
|
||||||
;; host tables + sorted collections: jolt.host/tagged-table/
|
;; host tables + sorted collections: jolt.host/tagged-table/
|
||||||
;; ref-put!/ref-get + the 25-sorted tier's runtime (sorted-map/sorted-set routed
|
;; ref-put!/ref-get + the 25-sorted tier's runtime (sorted-map/sorted-set routed
|
||||||
|
|
@ -302,6 +302,10 @@
|
||||||
;; in post-prelude.ss.
|
;; in post-prelude.ss.
|
||||||
(load "host/chez/natives-misc.ss")
|
(load "host/chez/natives-misc.ss")
|
||||||
|
|
||||||
|
;; format / printf: the %-directive engine. After natives-misc.ss + converters.ss
|
||||||
|
;; (jolt-str-render-one).
|
||||||
|
(load "host/chez/natives-format.ss")
|
||||||
|
|
||||||
;; namespaces: the namespace value model — find-ns/ns-name/
|
;; namespaces: the namespace value model — find-ns/ns-name/
|
||||||
;; all-ns/the-ns/create-ns/in-ns/ns-publics/ns-map/ns-interns/ns-aliases/resolve/
|
;; all-ns/the-ns/create-ns/in-ns/ns-publics/ns-map/ns-interns/ns-aliases/resolve/
|
||||||
;; find-var/ns-unmap/*ns*, over the var-table + chez-current-ns. Loaded LAST: needs
|
;; find-var/ns-unmap/*ns*, over the var-table + chez-current-ns. Loaded LAST: needs
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue