renamed defparamspath and defparamscollector to defpath and defcollector, defpath without params now produces compiledpath directly, implemented protocolpaths

This commit is contained in:
Nathan Marz 2015-12-12 12:03:59 -05:00
parent 322e9ff303
commit fc51d70b0f
3 changed files with 120 additions and 41 deletions

View file

@ -5,8 +5,8 @@
[pathed-collector [pathed-collector
variable-pathed-path variable-pathed-path
fixed-pathed-path fixed-pathed-path
defparamscollector defcollector
defparamspath defpath
paramscollector paramscollector
paramspath paramspath
]] ]]
@ -16,8 +16,8 @@
[pathed-collector [pathed-collector
variable-pathed-path variable-pathed-path
fixed-pathed-path fixed-pathed-path
defparamscollector defcollector
defparamspath defpath
paramscollector paramscollector
paramspath]] paramspath]]
) )
@ -143,7 +143,7 @@
(def FIRST (comp-paths (i/->PosStructurePath first i/set-first))) (def FIRST (comp-paths (i/->PosStructurePath first i/set-first)))
(defparamspath (defpath
^{:doc "Uses start-fn and end-fn to determine the bounds of the subsequence ^{:doc "Uses start-fn and end-fn to determine the bounds of the subsequence
to select when navigating. Each function takes in the structure as input."} to select when navigating. Each function takes in the structure as input."}
srange-dynamic srange-dynamic
@ -154,7 +154,7 @@
(i/srange-transform structure (start-fn structure) (end-fn structure) next-fn) (i/srange-transform structure (start-fn structure) (end-fn structure) next-fn)
)) ))
(defparamspath (defpath
^{:doc "Navigates to the subsequence bound by the indexes start (inclusive) ^{:doc "Navigates to the subsequence bound by the indexes start (inclusive)
and end (exclusive)"} and end (exclusive)"}
srange srange
@ -169,7 +169,7 @@
(def END (srange-dynamic count count)) (def END (srange-dynamic count count))
(defparamspath (defpath
^{:doc "Navigates to the specified subset (by taking an intersection). ^{:doc "Navigates to the specified subset (by taking an intersection).
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."}
@ -185,7 +185,7 @@
(set/union newset)) (set/union newset))
))) )))
(defparamspath (defpath
walker walker
[afn] [afn]
(select* [this structure next-fn] (select* [this structure next-fn]
@ -193,7 +193,7 @@
(transform* [this structure next-fn] (transform* [this structure next-fn]
(i/walk-until afn next-fn structure))) (i/walk-until afn next-fn structure)))
(defparamspath (defpath
codewalker codewalker
[afn] [afn]
(select* [this structure next-fn] (select* [this structure next-fn]
@ -225,14 +225,14 @@
))) )))
(defparamspath keypath [key] (defpath keypath [key]
(select* [this structure next-fn] (select* [this structure next-fn]
(next-fn (get structure key))) (next-fn (get structure key)))
(transform* [this structure next-fn] (transform* [this structure next-fn]
(assoc structure key (next-fn (get structure key))) (assoc structure key (next-fn (get structure key)))
)) ))
(defparamspath view [afn] (defpath view [afn]
(select* [this structure next-fn] (select* [this structure next-fn]
(next-fn (afn structure))) (next-fn (afn structure)))
(transform* [this structure next-fn] (transform* [this structure next-fn]
@ -309,7 +309,7 @@
(transform* [aset structure next-fn] (transform* [aset structure next-fn]
(i/filter-transform aset structure next-fn))) (i/filter-transform aset structure next-fn)))
(defparamspath (defpath
^{: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
@ -319,7 +319,7 @@
(transform* [this structure next-fn] (transform* [this structure next-fn]
(i/filter-transform afn structure next-fn))) (i/filter-transform afn structure next-fn)))
(defparamspath (defpath
^{: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
@ -345,7 +345,7 @@
(compiled-select-one late structure) (compiled-select-one late structure)
))) )))
(defparamscollector (defcollector
^{:doc ^{:doc
"Adds an external value to the collected vals. Useful when additional arguments "Adds an external value to the collected vals. Useful when additional arguments
are required to the transform function that would otherwise require partial are required to the transform function that would otherwise require partial

View file

@ -553,3 +553,25 @@
(if (afn structure) (if (afn structure)
(next-fn structure) (next-fn structure)
structure)) structure))
(defn compiled-selector [^com.rpl.specter.impl.CompiledPath path]
(-> path .-transform-fns .-selector))
(defn compiled-transformer [^com.rpl.specter.impl.CompiledPath path]
(-> path .-transform-fns .-transformer))
(defn params-needed-selector [^com.rpl.specter.impl.ParamsNeededPath path]
(-> path .-transform-fns .-selector))
(defn params-needed-transformer [^com.rpl.specter.impl.ParamsNeededPath path]
(-> path .-transform-fns .-transformer))
(defn extend-protocolpath* [protpath-prot extensions]
(let [extensions (partition 2 extensions)
m (-> protpath-prot :sigs keys first)]
(doseq [[atype apath] extensions]
;;TODO: validate that the path has the correct number of args
(let [p (comp-paths* apath)]
(extend atype protpath-prot {m (fn [_] p)})
))))

View file

@ -18,31 +18,40 @@
(let [[[[_ s-structure-sym s-next-fn-sym] & select-body] (let [[[[_ s-structure-sym s-next-fn-sym] & select-body]
[[_ t-structure-sym t-next-fn-sym] & transform-body]] [[_ t-structure-sym t-next-fn-sym] & transform-body]]
(determine-params-impls impl1 impl2)] (determine-params-impls impl1 impl2)]
`(->ParamsNeededPath (if (= 0 num-params)
(->TransformFunctions `(no-params-compiled-path
RichPathExecutor (->TransformFunctions
(fn [~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~s-structure-sym next-fn#] StructurePathExecutor
(let [~s-next-fn-sym (fn [structure#] (fn [~s-structure-sym ~s-next-fn-sym]
(next-fn# ~@select-body)
~PARAMS-SYM (fn [~t-structure-sym ~t-next-fn-sym]
(+ ~PARAMS-IDX-SYM ~num-params) ~@transform-body)
vals# ))
structure#)) `(->ParamsNeededPath
~@bindings] (->TransformFunctions
~@select-body RichPathExecutor
)) (fn [~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~s-structure-sym next-fn#]
(fn [~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~t-structure-sym next-fn#] (let [~s-next-fn-sym (fn [structure#]
(let [~t-next-fn-sym (fn [structure#] (next-fn#
(next-fn# ~PARAMS-SYM
~PARAMS-SYM (+ ~PARAMS-IDX-SYM ~num-params)
(+ ~PARAMS-IDX-SYM ~num-params) vals#
vals# structure#))
structure#)) ~@bindings]
~@bindings] ~@select-body
~@transform-body ))
))) (fn [~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~t-structure-sym next-fn#]
~num-params (let [~t-next-fn-sym (fn [structure#]
))) (next-fn#
~PARAMS-SYM
(+ ~PARAMS-IDX-SYM ~num-params)
vals#
structure#))
~@bindings]
~@transform-body
)))
~num-params
))))
(defn paramscollector* [post-bindings num-params [_ [_ structure-sym] & body]] (defn paramscollector* [post-bindings num-params [_ [_ structure-sym] & body]]
`(let [collector# (fn [~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~structure-sym next-fn#] `(let [collector# (fn [~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~structure-sym next-fn#]
@ -130,10 +139,10 @@
(paramscollector* retrieve-params num-params impl) (paramscollector* retrieve-params num-params impl)
)) ))
(defmacro defparamspath [name & body] (defmacro defpath [name & body]
`(def ~name (paramspath ~@body))) `(def ~name (paramspath ~@body)))
(defmacro defparamscollector [name & body] (defmacro defcollector [name & body]
`(def ~name (paramscollector ~@body))) `(def ~name (paramscollector ~@body)))
(defmacro fixed-pathed-path (defmacro fixed-pathed-path
@ -190,3 +199,51 @@
) )
)) ))
(defn- protpath-sym [name]
(-> name (str "-prot") symbol))
(defmacro defprotocolpath [name params]
(let [prot-name (protpath-sym name)
m (-> name (str "-retrieve") symbol)
num-params (count params)
ssym (gensym "structure")
sargs [ssym (gensym "next-fn")]
rargs [(gensym "params") (gensym "pidx") (gensym "vals") ssym (gensym "next-fn")]
retrieve `(~m ~ssym)
]
`(do
(defprotocol ~prot-name (~m [structure#]))
(def ~name
(if (= ~num-params 0)
(no-params-compiled-path
(->TransformFunctions
StructurePathExecutor
(fn ~sargs
(let [path# ~retrieve
selector# (compiled-selector path#)]
(selector# ~@sargs)
))
(fn ~sargs
(let [path# ~retrieve
transformer# (compiled-transformer path#)]
(transformer# ~@sargs)
))))
(->ParamsNeededPath
(->TransformFunctions
RichPathExecutor
(fn ~rargs
(let [path# ~retrieve
selector# (params-needed-selector path#)]
(selector# ~@rargs)
))
(fn ~rargs
(let [path# ~retrieve
transformer# (params-needed-transformer path#)]
(transformer# ~@rargs)
)))
~num-params
)
)))))
(defmacro extend-protocolpath [protpath & extensions]
`(extend-protocolpath* ~(protpath-sym protpath) ~(vec extensions)))