A set literal reaches a macro as a set value
#{...} reads as the tagged set-form for the analyzer, but a macro saw that
map instead of a set (set? false / map? true, unlike a vector). hc-expand-1
now converts a set-form argument to a real set before calling the expander, so
(set? arg)/conj/seq work — hiccup's compiler introspects a literal set this way
(str (html #{"<>"}) was empty, now #{"<>"}). Elements stay as
read; a deeply-nested set literal inside another form is left for the analyzer.
hiccup 382->383. Jolt-side unit guards (macro def+use in one form isn't
JVM-portable).
This commit is contained in:
parent
bd645a68d6
commit
5cd8d15ae7
2 changed files with 16 additions and 1 deletions
|
|
@ -203,10 +203,22 @@
|
||||||
dst))
|
dst))
|
||||||
dst))
|
dst))
|
||||||
|
|
||||||
|
;; A set literal reads as the tagged set-form {:jolt/type :jolt/set :value [...]}
|
||||||
|
;; for the analyzer, but a macro must see a real set value (Clojure parity, so
|
||||||
|
;; (set? arg) / seq / conj work — hiccup's compiler does this). Convert a set-form
|
||||||
|
;; argument to a set; elements stay as read (a deeply-nested set literal inside
|
||||||
|
;; another form is rarer and left for the analyzer).
|
||||||
|
(define (hc-macro-arg x)
|
||||||
|
(if (rdr-set-form? x)
|
||||||
|
(let ((items (jolt-get x rdr-kw-value)))
|
||||||
|
(let loop ((i 0) (s empty-pset))
|
||||||
|
(if (fx>=? i (pvec-count items)) s
|
||||||
|
(loop (fx+ i 1) (pset-conj s (pvec-nth-d items i jolt-nil))))))
|
||||||
|
x))
|
||||||
(define (hc-expand-1 ctx form)
|
(define (hc-expand-1 ctx form)
|
||||||
(let* ((items (seq->list form))
|
(let* ((items (seq->list form))
|
||||||
(head (car items))
|
(head (car items))
|
||||||
(args (cdr items))
|
(args (map hc-macro-arg (cdr items)))
|
||||||
(expander (var-cell-root (hc-resolve-cell ctx head))))
|
(expander (var-cell-root (hc-resolve-cell ctx head))))
|
||||||
(hc-propagate-pos form (apply jolt-invoke expander args))))
|
(hc-propagate-pos form (apply jolt-invoke expander args))))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -567,4 +567,7 @@
|
||||||
{:suite "deftype-map" :expr "(do (deftype Op [s]) [(map? (->Op 1)) (record? (->Op 1)) (coll? (->Op 1))])" :expected "[false false false]"}
|
{:suite "deftype-map" :expr "(do (deftype Op [s]) [(map? (->Op 1)) (record? (->Op 1)) (coll? (->Op 1))])" :expected "[false false false]"}
|
||||||
{:suite "deftype-map" :expr "(do (deftype Lc [xs] clojure.lang.Counted (count [_] (count xs)) clojure.lang.Seqable (seq [_] (seq xs))) [(coll? (->Lc [1 2])) (count (->Lc [1 2])) (vec (seq (->Lc [1 2])))])" :expected "[true 2 [1 2]]"}
|
{:suite "deftype-map" :expr "(do (deftype Lc [xs] clojure.lang.Counted (count [_] (count xs)) clojure.lang.Seqable (seq [_] (seq xs))) [(coll? (->Lc [1 2])) (count (->Lc [1 2])) (vec (seq (->Lc [1 2])))])" :expected "[true 2 [1 2]]"}
|
||||||
{:suite "deftype-map" :expr "(do (defrecord Dr [a b]) [(map? (->Dr 1 2)) (record? (->Dr 1 2)) (coll? (->Dr 1 2))])" :expected "[true true true]"}
|
{:suite "deftype-map" :expr "(do (defrecord Dr [a b]) [(map? (->Dr 1 2)) (record? (->Dr 1 2)) (coll? (->Dr 1 2))])" :expected "[true true true]"}
|
||||||
|
{:suite "macro-args" :expr "(do (defmacro sm [x] [(set? x) (map? x)]) (sm #{1 2}))" :expected "[true false]"}
|
||||||
|
{:suite "macro-args" :expr "(do (defmacro ws [x] (conj x :z)) (= #{1 :z} (ws #{1})))" :expected "true"}
|
||||||
|
{:suite "macro-args" :expr "(do (defmacro vm [x] (vector? x)) (vm [1 2]))" :expected "true"}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue