Closed noprompt closed 5 years ago
So is the idea here that
{:tag :cat,
:elements ({:tag :lit, :value X}
{:tag :lit, :value Y}
{:tag :lit, :value Z})}
should be turned into
{:tag :lit
:value '(X Y Z)}
Before being turned into IR?
Or did you have some other implementation in mind?
@jimmyhmiller Yeah that's the idea. I've created a branch for this work if you want to take a look at it. Essentially we need to change the final case in expand-node
.
@@ -1700,10 +1739,12 @@
:arguments [as (dissoc x :as)]})
x)
;; else
- x))
+ (if (literal? x)
+ {:tag :lit
+ :value (lit-form x)}
+ x)))
(r.syntax/rename-refs node)))
Where lit-form
converts a node into a literal.
(defn lit-form [node]
(case (r.syntax/tag node)
:cat
(map lit-form (:elements node))
:jsa
#?(:clj
(JSValue. (vec (lit-form (:prt node))))
:cljs
(into-array (lit-form (:prt node))))
:lit
(:value node)
:map
(into {}
(map (fn [[k v]]
[(lit-form k)
(lit-form v)]))
(:map node))
:prt
(concat (lit-form (:left node))
(lit-form (:right node)))
:quo
(:form node)
:vec
(into [] (lit-form (:prt node)))
:seq
(if-some [l (seq (lit-form (:prt node)))]
`(quote ~(apply list l))
())
:set
(into #{} (map lit-form (:elements node)))))
This is essentially the same as compile-ground
but without the :unq
clause.
The definition of literal?
also needs to be changed to
@@ -120,7 +120,7 @@
See also: compile-ground"
[node]
(and (r.syntax/ground? node)
- (not-any? (comp #{:map :set} r.syntax/tag)
+ (not-any? (comp #{:map :unq :set} r.syntax/tag)
(r.syntax/subnodes node))))
because an unquote node is technically not a literal because is determined at runtime.
This does appear to break a few tests, however.
A pattern like
will be parsed as
which will be compiled to the IR
which seems wasteful.
This should compile to an equality test.