edn: port read-string onto the reader; fix special-form ns shadowing
clojure.edn/read-string now delegates to clojure.core/read-string (the reader-based special form — parses, never evals) via a private helper, with the opts-map :eof arity and nil/blank-input handling. 43 -> 47 in the stdlib battery. This required an evaluator fix: special forms were matched by name only, so clojure.edn/read-string dispatched the core read-string SPECIAL FORM instead of the var. Now a head qualified to a non-core namespace resolves to its var; only unqualified or clojure.core-qualified heads are special forms. Conformance 218/218 all modes; full suite green. Remaining edn gaps (jolt-b7y): set literals read as a set FORM not a constructed set, and #uuid has no real type.
This commit is contained in:
parent
fc88ecdc74
commit
1bd676c242
3 changed files with 31 additions and 12 deletions
|
|
@ -1,13 +1,27 @@
|
|||
; Jolt Standard Library: clojure.edn
|
||||
; EDN reading and writing (stubs using the Jolt reader).
|
||||
;; clojure.edn — reading EDN data. Delegates to the Jolt reader via
|
||||
;; clojure.core/read-string (which parses, never evaluates — safe for EDN), and
|
||||
;; adds the opts-map arity with :eof plus nil/blank-input handling.
|
||||
(ns clojure.edn
|
||||
"Reading EDN data."
|
||||
(:require [clojure.string :as cstr]))
|
||||
|
||||
;; Private helper, NOT named read-string: an unqualified (read-string …) call
|
||||
;; dispatches the core read-string SPECIAL FORM (by name, regardless of ns), so
|
||||
;; the 1-arity can't delegate to the 2-arity through that name.
|
||||
(defn- read-edn [opts s]
|
||||
(if (or (nil? s) (cstr/blank? s))
|
||||
(get opts :eof nil)
|
||||
(clojure.core/read-string s)))
|
||||
|
||||
(defn read-string
|
||||
[s]
|
||||
(let [ctx ((get (dyn :current-env) (symbol "init")))]
|
||||
((get (dyn :current-env) (symbol "eval-string")) ctx s)))
|
||||
"Reads one object from the string s. Returns the :eof option value (default
|
||||
nil) for nil or blank input. opts is an options map; :eof sets the value
|
||||
returned at end of input."
|
||||
([s] (read-edn {} s))
|
||||
([opts s] (read-edn opts s)))
|
||||
|
||||
(defn read
|
||||
"Reads the next line from reader and parses one EDN object from it."
|
||||
[reader]
|
||||
(let [line ((get (dyn :current-env) (symbol "file/read")) reader :line)]
|
||||
(when line
|
||||
(read-string line))))
|
||||
(when line (read-string line))))
|
||||
|
|
|
|||
|
|
@ -611,9 +611,13 @@
|
|||
(defn- eval-list
|
||||
[ctx bindings form]
|
||||
(def first-form (first form))
|
||||
# Safe name extraction: non-symbol heads (e.g. keywords) fall through to default
|
||||
# Safe name extraction: non-symbol heads (e.g. keywords) fall through to default.
|
||||
# A head qualified to a NON-core namespace (e.g. clojure.edn/read-string) must
|
||||
# resolve to that var, not the like-named clojure.core special form — so only
|
||||
# unqualified or clojure.core-qualified heads dispatch as special forms.
|
||||
(def name (if (and (struct? first-form) (= :symbol (first-form :jolt/type)))
|
||||
(first-form :name)
|
||||
(let [ns (first-form :ns)]
|
||||
(if (or (nil? ns) (= ns "clojure.core")) (first-form :name) nil))
|
||||
nil))
|
||||
(match name
|
||||
"quote" (in form 1)
|
||||
|
|
|
|||
|
|
@ -12,9 +12,10 @@
|
|||
[["clojure/walk_test/walk.cljc" 34 true]
|
||||
["clojure/zip_test/zip.cljc" 33 true]
|
||||
["clojure/data_test/diff.cljc" 61 true]
|
||||
# clojure.edn is still a stub (no opts/:eof arity, broken set/nil handling);
|
||||
# tracked separately. Guard its current passing subset so it can't regress.
|
||||
["clojure/edn_test/read_string.cljc" 43 false]])
|
||||
# clojure.edn now reads via clojure.core/read-string with opts/:eof + nil/blank
|
||||
# handling. The remaining 3 fails are sets (the reader yields a set FORM, not a
|
||||
# constructed set) and #uuid — tracked in jolt-b7y. Guard the passing subset.
|
||||
["clojure/edn_test/read_string.cljc" 47 false]])
|
||||
|
||||
(def root "test/clojure-stdlib")
|
||||
(def per-file-timeout 6)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue