core: pr/prn/pr-str/print/println to the overlay; pr-str escapes strings now

Round 6 of the seed shrink (the printer round, scoped by the perf wall). The
five wrappers move to 20-coll over two new host seams: __write (push a string
to *out*) and __pr-str1 (render one value readably). The renderer itself
stays in the seed — it's representation-coupled (pvec/phm/phs/sorted
internals) and shared with the hot str, and rendering through overlay calls
would pay the per-element call cost everywhere big values get printed.
print-method as a real multimethod is follow-up work.

The new spec rows caught a renderer bug: string bodies were never escaped, so
(pr-str "a\"b") didn't round-trip through the reader. pr-render now
escapes quote/backslash/control chars per Clojure.
This commit is contained in:
Yogthos 2026-06-11 14:12:12 -04:00
parent 5cac9efd4e
commit 1de5ede246
3 changed files with 60 additions and 41 deletions

View file

@ -54,3 +54,16 @@
["line-seq empty" "nil" "(with-in-str \"\" (seq (line-seq *in*)))"]
["line-seq is lazy seq" "true" "(with-in-str \"a\\nb\" (seq? (line-seq *in*)))"]
["line-seq count" "3" "(with-in-str \"1\\n2\\n3\" (count (line-seq *in*)))"])
# The print family is overlay now (seed-shrink round 6), over the __write /
# __pr-str1 host seams: pr is readable, print is str semantics, *-ln appends.
(defspec "io / print family (overlay)"
["pr-str multi-arg spacing" "\"\\\"a\\\" [1 2] :k\"" "(pr-str \"a\" [1 2] :k)"]
["pr-str zero args" "\"\"" "(pr-str)"]
["pr-str escapes" "\"\\\"a\\\\\\\"b\\\"\"" "(pr-str \"a\\\"b\")"]
["print is unreadable" "\"a b\"" "(with-out-str (print \"a\" \"b\"))"]
["println appends newline" "\"x 1\\n\"" "(with-out-str (println \"x\" 1))"]
["prn is readable + newline" "\"[1 \\\"s\\\"]\\n\"" "(with-out-str (prn [1 \"s\"]))"]
["pr writes no newline" "\"\\\\a\"" "(with-out-str (pr \\a))"]
["print nil arg" "\"\"" "(with-out-str (print nil))"]
["prn keyword" "\":k\\n\"" "(with-out-str (prn :k))"])