read-string constructs sets; format %x lowercase; extend/extends? on nil

read-string/read now return real sets for #{...} literals (top-level and
nested) instead of the reader's {:jolt/type :jolt/set} form — the data
seams convert set forms to sets (recursing, preserving metadata and source
map-key order); clojure.edn already did this. The compiler keeps reading
via the raw reader, so set literals in code stay forms the analyzer lowers.

format %x now emits lowercase hex (Chez number->string is uppercase); %X
unchanged.

extend and extends? handle a nil target type (host tag "nil"), matching
extend-type — protocols can be extended to nil via the function form, not
just the macro.

Found porting transit/data.json and shaking out aero.
This commit is contained in:
Yogthos 2026-06-24 14:03:47 -04:00
parent e74b940db5
commit c26fd175f2
8 changed files with 604 additions and 534 deletions

View file

@ -316,8 +316,8 @@
{:suite "reader" :expr "(= [1 2 3] (read-string \"[1 2 3]\"))" :expected "true"}
{:suite "reader" :expr "(= (quote (+ 1 2)) (read-string \"(+ 1 2)\"))" :expected "true"}
{:suite "reader" :expr "(= {:a 1 :b 2} (read-string \"{:a 1 :b 2}\"))" :expected "true"}
{:suite "reader" :expr "(:value (read-string \"#{1 2 3}\"))" :expected "[1 2 3]"}
{:suite "reader" :expr "(= :jolt/set (:jolt/type (read-string \"#{1 2 3}\")))" :expected "true"}
{:suite "reader" :expr "(set? (read-string \"#{1 2 3}\"))" :expected "true"}
{:suite "reader" :expr "(= #{1 2 3} (read-string \"#{1 2 3}\"))" :expected "true"}
{:suite "reader" :expr "(= [1 [2 3] {:k :v}] (read-string \"[1 [2 3] {:k :v}]\"))" :expected "true"}
{:suite "reader" :expr "(= (quote (quote x)) (read-string \"'x\"))" :expected "true"}
{:suite "reader" :expr "(= (quote (clojure.core/deref a)) (read-string \"@a\"))" :expected "true"}