implemented declarepath/providepath
This commit is contained in:
parent
1905157c3c
commit
dd6dafc390
4 changed files with 67 additions and 10 deletions
|
|
@ -6,6 +6,7 @@
|
|||
* Fix replace-in to work with value collection
|
||||
* Added STAY selector
|
||||
* Added stay-then-continue and continue-then-stay selectors which enable pre-order/post-order traversals
|
||||
* Added declarepath and providepath, which enable arbitrary recursive or mutually recursive paths
|
||||
|
||||
## 0.9.1
|
||||
* Fixed reflection in protocol path code
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@
|
|||
fixed-pathed-path
|
||||
defcollector
|
||||
defpath
|
||||
paramscollector
|
||||
paramspath
|
||||
]]
|
||||
)
|
||||
(:use [com.rpl.specter.protocols :only [StructurePath]]
|
||||
|
|
@ -17,9 +15,7 @@
|
|||
variable-pathed-path
|
||||
fixed-pathed-path
|
||||
defcollector
|
||||
defpath
|
||||
paramscollector
|
||||
paramspath]]
|
||||
defpath]]
|
||||
)
|
||||
(:require [com.rpl.specter.impl :as i]
|
||||
[clojure.set :as set])
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@
|
|||
(apply concat)))
|
||||
|
||||
|
||||
(defmacro paramspath
|
||||
(defmacro path
|
||||
"Defines a StructurePath with late bound parameters. This path can be precompiled
|
||||
with other selectors without knowing the parameters. When precompiled with other
|
||||
selectors, the resulting selector takes in parameters for all selectors in the path
|
||||
|
|
@ -120,7 +120,7 @@
|
|||
))
|
||||
|
||||
(defmacro paramsfn [params [structure-sym] & impl]
|
||||
`(paramspath ~params
|
||||
`(path ~params
|
||||
(~'select* [this# structure# next-fn#]
|
||||
(let [afn# (fn [~structure-sym] ~@impl)]
|
||||
(filter-select afn# structure# next-fn#)
|
||||
|
|
@ -143,7 +143,7 @@
|
|||
))
|
||||
|
||||
(defmacro defpath [name & body]
|
||||
`(def ~name (paramspath ~@body)))
|
||||
`(def ~name (path ~@body)))
|
||||
|
||||
(defmacro defcollector [name & body]
|
||||
`(def ~name (paramscollector ~@body)))
|
||||
|
|
@ -247,5 +247,39 @@
|
|||
)
|
||||
)))))
|
||||
|
||||
|
||||
(defn declared-name [name]
|
||||
(symbol (str name "-declared")))
|
||||
|
||||
(defmacro declarepath [name]
|
||||
(let [declared (declared-name name)
|
||||
rargs [(gensym "params") (gensym "pidx") (gensym "vals")
|
||||
(gensym "structure") (gensym "next-fn")]]
|
||||
`(do
|
||||
(declare ~declared)
|
||||
(def ~name
|
||||
(no-params-compiled-path
|
||||
(->TransformFunctions
|
||||
RichPathExecutor
|
||||
(fn ~rargs
|
||||
(let [selector# (compiled-selector ~declared)]
|
||||
(selector# ~@rargs)
|
||||
))
|
||||
(fn ~rargs
|
||||
(let [transformer# (compiled-transformer ~declared)]
|
||||
(transformer# ~@rargs)
|
||||
))))
|
||||
))))
|
||||
|
||||
(defmacro providepath [name apath]
|
||||
`(def ~(declared-name name)
|
||||
(update-in (comp-paths* ~apath)
|
||||
[:transform-fns]
|
||||
coerce-tfns-rich)
|
||||
))
|
||||
|
||||
;;TODO: hmm... not sure how to proxy it as don't know if its paramsneeded/compiler or rich/regular
|
||||
;;could require later definition to be done with "defproxiedpath" or wrapped in proxied-path
|
||||
|
||||
(defmacro extend-protocolpath [protpath & extensions]
|
||||
`(extend-protocolpath* ~protpath ~(protpath-sym protpath) ~(vec extensions)))
|
||||
|
|
|
|||
|
|
@ -3,12 +3,16 @@
|
|||
[cljs.test :refer [is deftest]]
|
||||
[cljs.test.check.cljs-test :refer [defspec]]
|
||||
[com.rpl.specter.cljs-test-helpers :refer [for-all+]]
|
||||
[com.rpl.specter.macros :refer [paramsfn defprotocolpath defpath extend-protocolpath]])
|
||||
[com.rpl.specter.macros
|
||||
:refer [paramsfn defprotocolpath defpath extend-protocolpath
|
||||
declarepath providepath]])
|
||||
(:use
|
||||
#+clj [clojure.test :only [deftest is]]
|
||||
#+clj [clojure.test.check.clojure-test :only [defspec]]
|
||||
#+clj [com.rpl.specter.test-helpers :only [for-all+]]
|
||||
#+clj [com.rpl.specter.macros :only [paramsfn defprotocolpath defpath extend-protocolpath]]
|
||||
#+clj [com.rpl.specter.macros
|
||||
:only [paramsfn defprotocolpath defpath extend-protocolpath
|
||||
declarepath providepath]]
|
||||
|
||||
)
|
||||
|
||||
|
|
@ -589,6 +593,28 @@
|
|||
(s/select (s/continue-then-stay s/ALL odd?) [1 2 3])))
|
||||
)
|
||||
|
||||
|
||||
(declarepath MyWalker)
|
||||
|
||||
(providepath MyWalker
|
||||
(s/if-path vector?
|
||||
(s/if-path [s/FIRST #(= :abc %)]
|
||||
(s/continue-then-stay s/ALL MyWalker)
|
||||
[s/ALL MyWalker]
|
||||
)))
|
||||
|
||||
(deftest recursive-path-test
|
||||
(is (= [9 1 10 3 1]
|
||||
(s/select [MyWalker s/ALL number?]
|
||||
[:bb [:aa 34 [:abc 10 [:ccc 9 8 [:abc 9 1]]]] [:abc 1 [:abc 3]]])
|
||||
))
|
||||
(is (= [:bb [:aa 34 [:abc 11 [:ccc 9 8 [:abc 10 2]]]] [:abc 2 [:abc 4]]]
|
||||
(s/transform [MyWalker s/ALL number?] inc
|
||||
[:bb [:aa 34 [:abc 10 [:ccc 9 8 [:abc 9 1]]]] [:abc 1 [:abc 3]]])
|
||||
))
|
||||
)
|
||||
|
||||
|
||||
#+clj
|
||||
(deftest large-params-test
|
||||
(let [path (apply s/comp-paths (repeat 25 s/keypath))
|
||||
|
|
|
|||
Loading…
Reference in a new issue