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
variable-pathed-path
fixed-pathed-path
defparamscollector
defparamspath
defcollector
defpath
paramscollector
paramspath
]]
@ -16,8 +16,8 @@
[pathed-collector
variable-pathed-path
fixed-pathed-path
defparamscollector
defparamspath
defcollector
defpath
paramscollector
paramspath]]
)
@ -143,7 +143,7 @@
(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
to select when navigating. Each function takes in the structure as input."}
srange-dynamic
@ -154,7 +154,7 @@
(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)
and end (exclusive)"}
srange
@ -169,7 +169,7 @@
(def END (srange-dynamic count count))
(defparamspath
(defpath
^{:doc "Navigates to the specified subset (by taking an intersection).
In a transform, that subset in the original set is changed to the
new value of the subset."}
@ -185,7 +185,7 @@
(set/union newset))
)))
(defparamspath
(defpath
walker
[afn]
(select* [this structure next-fn]
@ -193,7 +193,7 @@
(transform* [this structure next-fn]
(i/walk-until afn next-fn structure)))
(defparamspath
(defpath
codewalker
[afn]
(select* [this structure next-fn]
@ -225,14 +225,14 @@
)))
(defparamspath keypath [key]
(defpath keypath [key]
(select* [this structure next-fn]
(next-fn (get structure key)))
(transform* [this structure next-fn]
(assoc structure key (next-fn (get structure key)))
))
(defparamspath view [afn]
(defpath view [afn]
(select* [this structure next-fn]
(next-fn (afn structure)))
(transform* [this structure next-fn]
@ -309,7 +309,7 @@
(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
late-bound parameterized version of using a function directly in a path."}
pred
@ -319,7 +319,7 @@
(transform* [this 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
navigated at the structure."}
nil->val
@ -345,7 +345,7 @@
(compiled-select-one late structure)
)))
(defparamscollector
(defcollector
^{:doc
"Adds an external value to the collected vals. Useful when additional arguments
are required to the transform function that would otherwise require partial

View file

@ -553,3 +553,25 @@
(if (afn structure)
(next-fn 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]
[[_ t-structure-sym t-next-fn-sym] & transform-body]]
(determine-params-impls impl1 impl2)]
`(->ParamsNeededPath
(->TransformFunctions
RichPathExecutor
(fn [~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~s-structure-sym next-fn#]
(let [~s-next-fn-sym (fn [structure#]
(next-fn#
~PARAMS-SYM
(+ ~PARAMS-IDX-SYM ~num-params)
vals#
structure#))
~@bindings]
~@select-body
))
(fn [~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~t-structure-sym next-fn#]
(let [~t-next-fn-sym (fn [structure#]
(next-fn#
~PARAMS-SYM
(+ ~PARAMS-IDX-SYM ~num-params)
vals#
structure#))
~@bindings]
~@transform-body
)))
~num-params
)))
(if (= 0 num-params)
`(no-params-compiled-path
(->TransformFunctions
StructurePathExecutor
(fn [~s-structure-sym ~s-next-fn-sym]
~@select-body)
(fn [~t-structure-sym ~t-next-fn-sym]
~@transform-body)
))
`(->ParamsNeededPath
(->TransformFunctions
RichPathExecutor
(fn [~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~s-structure-sym next-fn#]
(let [~s-next-fn-sym (fn [structure#]
(next-fn#
~PARAMS-SYM
(+ ~PARAMS-IDX-SYM ~num-params)
vals#
structure#))
~@bindings]
~@select-body
))
(fn [~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~t-structure-sym next-fn#]
(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]]
`(let [collector# (fn [~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~structure-sym next-fn#]
@ -130,10 +139,10 @@
(paramscollector* retrieve-params num-params impl)
))
(defmacro defparamspath [name & body]
(defmacro defpath [name & body]
`(def ~name (paramspath ~@body)))
(defmacro defparamscollector [name & body]
(defmacro defcollector [name & body]
`(def ~name (paramscollector ~@body)))
(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)))