diff --git a/src/jolt/clojure/edn.clj b/src/jolt/clojure/edn.clj index ea271b3..5181e99 100644 --- a/src/jolt/clojure/edn.clj +++ b/src/jolt/clojure/edn.clj @@ -10,10 +10,15 @@ ;; maps/vectors/lists. (Lists stay lists — EDN never evaluates them as code.) (defn- edn->value [x] (cond - (and (map? x) (= :jolt/set (get x :jolt/type))) (set (map edn->value (get x :value))) - ;; Only untagged structs are real maps; symbols/chars/tagged literals are also - ;; struct? (=> map?) but carry a :jolt/type and must pass through unchanged. - (and (map? x) (nil? (get x :jolt/type))) + ;; Reader FORMS are detected by :jolt/type tag, never by map? — strict map? + ;; (correctly) excludes tagged structs, so the old (and (map? x) ...) guard + ;; would skip them. + (= :jolt/set (get x :jolt/type)) (set (map edn->value (get x :value))) + ;; EDN built-in tagged elements (#uuid/#inst, plus registered readers): + ;; apply the data reader to the read form (no evaluation involved). + (= :jolt/tagged (get x :jolt/type)) + (__read-tagged (get x :tag) (edn->value (get x :form))) + (map? x) (into {} (map (fn [e] [(edn->value (key e)) (edn->value (val e))]) x)) (vector? x) (mapv edn->value x) (seq? x) (map edn->value x) diff --git a/src/jolt/evaluator.janet b/src/jolt/evaluator.janet index 6d743de..a860cb0 100644 --- a/src/jolt/evaluator.janet +++ b/src/jolt/evaluator.janet @@ -1112,6 +1112,15 @@ the-form)) the-form))) (ns-intern core "macroexpand-1" expand-1) + # Apply a registered data reader to an already-read form (EDN built-in tags + # #uuid/#inst and any registered reader). Throws on an unknown tag. + (ns-intern core "__read-tagged" + (fn [tag form] + (def data-readers (get (ctx :env) :data-readers)) + (def reader-fn (if data-readers (get data-readers tag))) + (if reader-fn + (reader-fn form) + (error (string "No reader function for tag " tag))))) # macroexpand: expand repeatedly until the head is no longer a macro (the # form's SUBFORMS are not expanded, matching Clojure). (ns-intern core "macroexpand" diff --git a/test/integration/clojure-stdlib-suite-test.janet b/test/integration/clojure-stdlib-suite-test.janet index 1b4417e..c98f8bc 100644 --- a/test/integration/clojure-stdlib-suite-test.janet +++ b/test/integration/clojure-stdlib-suite-test.janet @@ -15,7 +15,7 @@ # clojure.edn reads via clojure.core/read-string (opts/:eof + nil/blank) and # constructs set/nested values. Only #uuid remains (no real uuid type) — # jolt-b7y. Guard the passing subset. - ["clojure/edn_test/read_string.cljc" 49 false]]) + ["clojure/edn_test/read_string.cljc" 50 false]]) (def root "test/clojure-stdlib") (def per-file-timeout 6)