inline-next-fn implementation
This commit is contained in:
parent
21f117503e
commit
8d7c786fe9
4 changed files with 78 additions and 26 deletions
|
|
@ -328,6 +328,7 @@
|
||||||
In a transform, that subset in the original set is changed to the
|
In a transform, that subset in the original set is changed to the
|
||||||
new value of the subset."}
|
new value of the subset."}
|
||||||
subset
|
subset
|
||||||
|
{:inline-next-fn true}
|
||||||
[aset]
|
[aset]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (set/intersection structure aset)))
|
(next-fn (set/intersection structure aset)))
|
||||||
|
|
@ -344,6 +345,7 @@
|
||||||
In a transform, that submap in the original map is changed to the new
|
In a transform, that submap in the original map is changed to the new
|
||||||
value of the submap."}
|
value of the submap."}
|
||||||
submap
|
submap
|
||||||
|
{:inline-next-fn true}
|
||||||
[m-keys]
|
[m-keys]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (select-keys structure m-keys)))
|
(next-fn (select-keys structure m-keys)))
|
||||||
|
|
@ -371,7 +373,7 @@
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(n/walk-select afn next-fn structure))
|
(n/walk-select afn next-fn structure))
|
||||||
(transform* [this structure next-fn]
|
(transform* [this structure next-fn]
|
||||||
(n/codewalk-until afn next-fn structure)))
|
(i/codewalk-until afn next-fn structure)))
|
||||||
|
|
||||||
(defpathedfn subselect
|
(defpathedfn subselect
|
||||||
"Navigates to a sequence that contains the results of (select ...),
|
"Navigates to a sequence that contains the results of (select ...),
|
||||||
|
|
@ -397,6 +399,7 @@
|
||||||
(defnav
|
(defnav
|
||||||
^{:doc "Navigates to the specified key, navigating to nil if it does not exist."}
|
^{:doc "Navigates to the specified key, navigating to nil if it does not exist."}
|
||||||
keypath
|
keypath
|
||||||
|
{:inline-next-fn true}
|
||||||
[key]
|
[key]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (get structure key)))
|
(next-fn (get structure key)))
|
||||||
|
|
@ -407,6 +410,7 @@
|
||||||
(defnav
|
(defnav
|
||||||
^{:doc "Navigates to the key only if it exists in the map."}
|
^{:doc "Navigates to the key only if it exists in the map."}
|
||||||
must
|
must
|
||||||
|
{:inline-next-fn true}
|
||||||
[k]
|
[k]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(if (contains? structure k)
|
(if (contains? structure k)
|
||||||
|
|
@ -421,6 +425,7 @@
|
||||||
(defnav
|
(defnav
|
||||||
^{:doc "Navigates to result of running `afn` on the currently navigated value."}
|
^{:doc "Navigates to result of running `afn` on the currently navigated value."}
|
||||||
view
|
view
|
||||||
|
{:inline-next-fn true}
|
||||||
[afn]
|
[afn]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (afn structure)))
|
(next-fn (afn structure)))
|
||||||
|
|
@ -433,6 +438,7 @@
|
||||||
transforms, the transformed value then has `unparse-fn` run on
|
transforms, the transformed value then has `unparse-fn` run on
|
||||||
it to get the final value at this point."}
|
it to get the final value at this point."}
|
||||||
parser
|
parser
|
||||||
|
{:inline-next-fn true}
|
||||||
[parse-fn unparse-fn]
|
[parse-fn unparse-fn]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (parse-fn structure)))
|
(next-fn (parse-fn structure)))
|
||||||
|
|
@ -518,6 +524,7 @@
|
||||||
^{:doc "Keeps the element only if it matches the supplied predicate. This is the
|
^{:doc "Keeps the element only if it matches the supplied predicate. This is the
|
||||||
late-bound parameterized version of using a function directly in a path."}
|
late-bound parameterized version of using a function directly in a path."}
|
||||||
pred
|
pred
|
||||||
|
{:inline-next-fn true}
|
||||||
[afn]
|
[afn]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(if (afn structure) (next-fn structure) NONE))
|
(if (afn structure) (next-fn structure) NONE))
|
||||||
|
|
@ -546,6 +553,7 @@
|
||||||
^{:doc "Navigates to the provided val if the structure is nil. Otherwise it stays
|
^{:doc "Navigates to the provided val if the structure is nil. Otherwise it stays
|
||||||
navigated at the structure."}
|
navigated at the structure."}
|
||||||
nil->val
|
nil->val
|
||||||
|
{:inline-next-fn true}
|
||||||
[v]
|
[v]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (if (nil? structure) v structure)))
|
(next-fn (if (nil? structure) v structure)))
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
(:require [com.rpl.specter.protocols :as p]
|
(:require [com.rpl.specter.protocols :as p]
|
||||||
[clojure.string :as s]
|
[clojure.string :as s]
|
||||||
|
[clojure.walk :as walk]
|
||||||
#?(:clj [com.rpl.specter.defhelpers :as dh])
|
#?(:clj [com.rpl.specter.defhelpers :as dh])
|
||||||
#?(:clj [riddley.walk :as riddley]))
|
#?(:clj [riddley.walk :as riddley]))
|
||||||
|
|
||||||
|
|
@ -652,6 +653,14 @@
|
||||||
#?(:cljs (instance? cljs.core.LazySeq f))
|
#?(:cljs (instance? cljs.core.LazySeq f))
|
||||||
(list? f)))
|
(list? f)))
|
||||||
|
|
||||||
|
(defn codewalk-until [pred on-match-fn structure]
|
||||||
|
(if (pred structure)
|
||||||
|
(on-match-fn structure)
|
||||||
|
(let [ret (walk/walk (partial codewalk-until pred on-match-fn) identity structure)]
|
||||||
|
(if (and (fn-invocation? structure) (fn-invocation? ret))
|
||||||
|
(with-meta ret (meta structure))
|
||||||
|
ret))))
|
||||||
|
|
||||||
(defrecord LayeredNav [underlying])
|
(defrecord LayeredNav [underlying])
|
||||||
|
|
||||||
(defn layered-nav? [o] (instance? LayeredNav o))
|
(defn layered-nav? [o] (instance? LayeredNav o))
|
||||||
|
|
|
||||||
|
|
@ -62,13 +62,13 @@
|
||||||
`(let [~@binding-fn-declarations]
|
`(let [~@binding-fn-declarations]
|
||||||
~body)))
|
~body)))
|
||||||
|
|
||||||
(defmacro ^:no-doc rich-nav-with-bindings [num-params-code bindings & impls]
|
|
||||||
|
(defn- rich-nav-with-bindings-not-inlined [num-params-code bindings impls]
|
||||||
(let [{[[_ s-structure-sym s-next-fn-sym] & s-body] 'select*
|
(let [{[[_ s-structure-sym s-next-fn-sym] & s-body] 'select*
|
||||||
[[_ t-structure-sym t-next-fn-sym] & t-body] 'transform*}
|
[[_ t-structure-sym t-next-fn-sym] & t-body] 'transform*}
|
||||||
(determine-params-impls impls)
|
(determine-params-impls impls)
|
||||||
params-sym (gensym "params")
|
params-sym (gensym "params")
|
||||||
params-idx-sym (gensym "params-idx")]
|
params-idx-sym (gensym "params-idx")]
|
||||||
|
|
||||||
(operation-with-bindings
|
(operation-with-bindings
|
||||||
bindings
|
bindings
|
||||||
params-sym
|
params-sym
|
||||||
|
|
@ -95,6 +95,44 @@
|
||||||
structure#))]
|
structure#))]
|
||||||
~@t-body)))))))
|
~@t-body)))))))
|
||||||
|
|
||||||
|
(defn inline-next-fn [body next-fn-sym extra-params]
|
||||||
|
(i/codewalk-until
|
||||||
|
#(and (i/fn-invocation? %) (= next-fn-sym (first %)))
|
||||||
|
(fn [code]
|
||||||
|
(let [code (map #(inline-next-fn % next-fn-sym extra-params) code)]
|
||||||
|
(concat [next-fn-sym] extra-params (rest code))))
|
||||||
|
body))
|
||||||
|
|
||||||
|
(defn- rich-nav-with-bindings-inlined [num-params-code bindings impls]
|
||||||
|
(let [{[[_ s-structure-sym s-next-fn-sym] & s-body] 'select*
|
||||||
|
[[_ t-structure-sym t-next-fn-sym] & t-body] 'transform*}
|
||||||
|
(determine-params-impls impls)
|
||||||
|
params-sym (gensym "params")
|
||||||
|
params-idx-sym (gensym "params-idx")
|
||||||
|
vals-sym (gensym "vals")
|
||||||
|
next-params-idx-sym (gensym "next-params-idx")
|
||||||
|
s-body (inline-next-fn s-body s-next-fn-sym [params-sym next-params-idx-sym vals-sym])
|
||||||
|
t-body (inline-next-fn t-body t-next-fn-sym [params-sym next-params-idx-sym vals-sym])]
|
||||||
|
(operation-with-bindings
|
||||||
|
bindings
|
||||||
|
params-sym
|
||||||
|
params-idx-sym
|
||||||
|
(fn [binding-declarations]
|
||||||
|
`(reify RichNavigator
|
||||||
|
(~'rich-select* [this# ~params-sym ~params-idx-sym ~vals-sym ~s-structure-sym ~s-next-fn-sym]
|
||||||
|
(let [~@binding-declarations
|
||||||
|
~next-params-idx-sym (+ ~params-idx-sym ~num-params-code)]
|
||||||
|
~@s-body))
|
||||||
|
|
||||||
|
(~'rich-transform* [this# ~params-sym ~params-idx-sym ~vals-sym ~t-structure-sym ~t-next-fn-sym]
|
||||||
|
(let [~@binding-declarations
|
||||||
|
~next-params-idx-sym (+ ~params-idx-sym ~num-params-code)]
|
||||||
|
~@t-body)))))))
|
||||||
|
|
||||||
|
(defmacro ^:no-doc rich-nav-with-bindings [opts num-params-code bindings & impls]
|
||||||
|
(if (:inline-next-fn opts)
|
||||||
|
(rich-nav-with-bindings-inlined num-params-code bindings impls)
|
||||||
|
(rich-nav-with-bindings-not-inlined num-params-code bindings impls)))
|
||||||
|
|
||||||
|
|
||||||
(defmacro ^:no-doc collector-with-bindings [num-params-code bindings impl]
|
(defmacro ^:no-doc collector-with-bindings [num-params-code bindings impl]
|
||||||
|
|
@ -130,7 +168,10 @@
|
||||||
with other navigators without knowing the parameters. When precompiled with other
|
with other navigators without knowing the parameters. When precompiled with other
|
||||||
navigators, the resulting path takes in parameters for all navigators in the path
|
navigators, the resulting path takes in parameters for all navigators in the path
|
||||||
that needed parameters (in the order in which they were declared)."
|
that needed parameters (in the order in which they were declared)."
|
||||||
[params & impls]
|
[& impl]
|
||||||
|
(let [[opts params & impls] (if (map? (first impl))
|
||||||
|
impl
|
||||||
|
(cons {} impl))]
|
||||||
(if (empty? params)
|
(if (empty? params)
|
||||||
`(i/lean-compiled-path (lean-nav* ~@impls))
|
`(i/lean-compiled-path (lean-nav* ~@impls))
|
||||||
`(vary-meta
|
`(vary-meta
|
||||||
|
|
@ -140,11 +181,12 @@
|
||||||
{:type :lean
|
{:type :lean
|
||||||
:params-needed-path
|
:params-needed-path
|
||||||
(i/->ParamsNeededPath
|
(i/->ParamsNeededPath
|
||||||
(rich-nav-with-bindings ~(count params)
|
(rich-nav-with-bindings ~opts
|
||||||
|
~(count params)
|
||||||
~(delta-param-bindings params)
|
~(delta-param-bindings params)
|
||||||
~@impls)
|
~@impls)
|
||||||
|
|
||||||
~(count params))})))
|
~(count params))}))))
|
||||||
|
|
||||||
|
|
||||||
(defmacro collector
|
(defmacro collector
|
||||||
|
|
@ -214,7 +256,8 @@
|
||||||
(i/lean-compiled-path (lean-nav* ~@impls)))
|
(i/lean-compiled-path (lean-nav* ~@impls)))
|
||||||
|
|
||||||
(i/->ParamsNeededPath
|
(i/->ParamsNeededPath
|
||||||
(rich-nav-with-bindings ~total-params-sym
|
(rich-nav-with-bindings {}
|
||||||
|
~total-params-sym
|
||||||
~runtime-bindings
|
~runtime-bindings
|
||||||
~@impls)
|
~@impls)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -460,14 +460,6 @@
|
||||||
(walk/walk (partial walk-until pred on-match-fn) identity structure)))
|
(walk/walk (partial walk-until pred on-match-fn) identity structure)))
|
||||||
|
|
||||||
|
|
||||||
(defn codewalk-until [pred on-match-fn structure]
|
|
||||||
(if (pred structure)
|
|
||||||
(on-match-fn structure)
|
|
||||||
(let [ret (walk/walk (partial codewalk-until pred on-match-fn) identity structure)]
|
|
||||||
(if (and (i/fn-invocation? structure) (i/fn-invocation? ret))
|
|
||||||
(with-meta ret (meta structure))
|
|
||||||
ret))))
|
|
||||||
|
|
||||||
|
|
||||||
(def DISPENSE*
|
(def DISPENSE*
|
||||||
(i/no-params-rich-compiled-path
|
(i/no-params-rich-compiled-path
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue