Conformance: SimpleDateFormat parse + read over host readers

- java.text.SimpleDateFormat.parse parses the RFC1123/1036/asctime patterns
  (day/month names, 2-digit-year sliding window, tz token), and .format renders
  z/Z/X timezone tokens (GMT/+0000/Z) instead of emitting them literally. Date
  gains toLocalDate/toLocalDateTime/before/after/equals. Fixes ring.util.time.
- read / read+string work over a host java.io reader (StringReader wrapped in a
  PushbackReader): drain, parse one form, push the tail back. Fixes cuerdas
  istr / << string interpolation (and selmer's <<), which read embedded forms
  from the template via (read pushback-reader).
This commit is contained in:
Yogthos 2026-06-22 18:02:25 -04:00
parent d83175b8c2
commit c7bbdea11d
4 changed files with 146 additions and 0 deletions

View file

@ -130,6 +130,23 @@
(define (reader-jhost? x)
(and (jhost? x) (member (jhost-tag x) '("string-reader" "pushback-reader"))))
;; Refill a host reader so subsequent read/slurp see `s` (the unconsumed tail).
(define (reader-refill! r s)
(cond
((string=? (jhost-tag r) "string-reader")
(vector-set! (jhost-state r) 0 s) (vector-set! (jhost-state r) 1 0))
((string=? (jhost-tag r) "pushback-reader")
(vector-set! (jhost-state r) 0 (host-new "StringReader" s))
(vector-set! (jhost-state r) 1 '()))))
;; Read ONE form from a host reader (StringReader/PushbackReader): drain the
;; remaining chars, parse one form, push the tail back. -> (values form found?).
;; (read r) over a java.io reader — cuerdas' interpolation reads this way.
(define (host-reader-read-form r)
(let* ((s (drain-reader r)) (pr (jolt-parse-next s)))
(if (jolt-nil? pr)
(begin (reader-refill! r "") (values jolt-nil #f))
(begin (reader-refill! r (jolt-nth pr 1)) (values (jolt-nth pr 0) #t)))))
;; clojure.edn/read over a reader (jolt-uicd): the overlay edn.clj's drain-reader is
;; janet/type-coupled, so on Chez we drain the jhost reader to a string and read the
;; first EDN form (read-string). Re-asserted over the prelude in post-prelude.ss.