higher order parameterized builder working, implemented filterer
This commit is contained in:
parent
56ba5a5b8d
commit
efd4f2ee9a
2 changed files with 71 additions and 94 deletions
|
|
@ -128,31 +128,11 @@
|
||||||
`(def ~name (paramspath ~@body)))
|
`(def ~name (paramspath ~@body)))
|
||||||
|
|
||||||
(defmacro params-paramspath [bindings & impls]
|
(defmacro params-paramspath [bindings & impls]
|
||||||
(let [quoted-bindings (->> bindings
|
(i/params-paramspath* (partition 2 bindings) impls))
|
||||||
(partition 2)
|
|
||||||
(map (fn [[sym path-sym]]
|
|
||||||
[`(quote ~sym) `(quote ~(gensym "path")) path-sym]
|
|
||||||
)))]
|
|
||||||
`(i/params-paramspath* ~quoted-bindings (quote ~impls))
|
|
||||||
))
|
|
||||||
|
|
||||||
|
;;TODO: needs to parameterize if necessary according to its path
|
||||||
(defn filterer [& path]
|
;; same for selected?, not-selected?, transformed, collect, collect-one,
|
||||||
(let [path (i/comp-paths* path)]
|
;; cond-path, multi-path
|
||||||
(params-paramspath [late path]
|
|
||||||
(select* [this structure next-fn]
|
|
||||||
;; same code
|
|
||||||
)
|
|
||||||
(transform* [this structure next-fn]
|
|
||||||
;; same code
|
|
||||||
))))
|
|
||||||
|
|
||||||
|
|
||||||
;;TODO: figure out how to express higher order selectors like filterer, selected?, cond-path
|
|
||||||
;; - if keep params-idx in compiledpath too, then:
|
|
||||||
;; - needs to emit paramsneeded if it needs params
|
|
||||||
;; - at runtime, it converts internal selector into CompiledPath with
|
|
||||||
;; the current params/params-idx
|
|
||||||
;;TODO: figure out how to express srange in terms of srange-dynamic
|
;;TODO: figure out how to express srange in terms of srange-dynamic
|
||||||
;; - will need selector and transformer to call into shared functions
|
;; - will need selector and transformer to call into shared functions
|
||||||
;;TODO: get rid of KeyPath
|
;;TODO: get rid of KeyPath
|
||||||
|
|
@ -181,26 +161,21 @@
|
||||||
|
|
||||||
(defn codewalker [afn] (i/->CodeWalkerStructurePath afn))
|
(defn codewalker [afn] (i/->CodeWalkerStructurePath afn))
|
||||||
|
|
||||||
;;TODO: needs to parameterize if necessary according to its path
|
(defn filterer [& path]
|
||||||
;; same for selected?, not-selected?, transformed, collect, collect-one,
|
(params-paramspath [late (i/comp-paths* path)]
|
||||||
;; cond-path, multi-path
|
(select* [this structure next-fn]
|
||||||
;; TODO: but should only become a late bound object if its internal path
|
(->> structure (filter #(i/selected?* late %)) doall next-fn))
|
||||||
;; is parameterized
|
(transform* [this structure next-fn]
|
||||||
;; want an interface that gives regular structure path interface but
|
(let [[filtered ancestry] (i/filter+ancestry late structure)
|
||||||
;; creates the right thing
|
;; the vec is necessary so that we can get by index later
|
||||||
|
;; (can't get by index for cons'd lists)
|
||||||
|
next (vec (next-fn filtered))]
|
||||||
|
(reduce (fn [curr [newi oldi]]
|
||||||
|
(assoc curr oldi (get next newi)))
|
||||||
|
(vec structure)
|
||||||
|
ancestry))
|
||||||
|
)))
|
||||||
|
|
||||||
; (higherorderparamspath [late1 path1
|
|
||||||
; late2 path2
|
|
||||||
; late3 path3]
|
|
||||||
; (select* [this structure next-fn]
|
|
||||||
; (compiled-select late1 ...)
|
|
||||||
; ;;TODO: if its multiple paths... where to do the index manipulation...?
|
|
||||||
; ;;could take in another arg of "latebound paths" that can then be used internally...
|
|
||||||
; ;; but if nothing was higher order, then its just direct
|
|
||||||
; ;; this never directly accesses params
|
|
||||||
; ))
|
|
||||||
|
|
||||||
(defn filterer [& path] (i/->FilterStructurePath (i/comp-paths* path)))
|
|
||||||
|
|
||||||
(defparamspath keypath [key]
|
(defparamspath keypath [key]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,6 @@
|
||||||
[clojure.string :as s])
|
[clojure.string :as s])
|
||||||
)
|
)
|
||||||
|
|
||||||
(def ^:dynamic *tmp-closure*)
|
|
||||||
(defn closed-code [closure body]
|
|
||||||
(let [lv (mapcat #(vector % `(*tmp-closure* '~%))
|
|
||||||
(keys closure))]
|
|
||||||
(binding [*tmp-closure* closure]
|
|
||||||
(eval `(let [~@lv] ~body)))))
|
|
||||||
|
|
||||||
(defprotocol PathComposer
|
(defprotocol PathComposer
|
||||||
(comp-paths* [paths]))
|
(comp-paths* [paths]))
|
||||||
|
|
||||||
|
|
@ -335,10 +328,7 @@
|
||||||
(defn paramspath* [bindings num-params [impl1 impl2]]
|
(defn paramspath* [bindings num-params [impl1 impl2]]
|
||||||
(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)]
|
||||||
|
|
||||||
params-sym (gensym "params")
|
|
||||||
params-idx-sym (gensym "params-idx")]
|
|
||||||
`(->ParamsNeededPath
|
`(->ParamsNeededPath
|
||||||
(->TransformFunctions
|
(->TransformFunctions
|
||||||
RichPathExecutor
|
RichPathExecutor
|
||||||
|
|
@ -371,28 +361,57 @@
|
||||||
(:num-needed-params path)))
|
(:num-needed-params path)))
|
||||||
|
|
||||||
(defn params-paramspath* [bindings impls]
|
(defn params-paramspath* [bindings impls]
|
||||||
(let [num-params-seq (->> bindings
|
(let [bindings (->> bindings
|
||||||
(map last)
|
(map (fn [[late-sym path]]
|
||||||
(map num-needed-params)
|
{:late-sym late-sym
|
||||||
(reductions +)
|
:path path
|
||||||
(cons 0))
|
:path-sym (gensym "path")
|
||||||
num-params (last num-params-seq)
|
:offset-sym (gensym "offset")
|
||||||
closure (->> bindings (map rest) (into {}))
|
:latebind-sym (gensym "latebind")}))
|
||||||
make-paths (->> bindings
|
(reduce
|
||||||
(map (fn [offset [late-sym path-sym path]]
|
(fn [bindings binding]
|
||||||
[late-sym
|
(if (empty? bindings)
|
||||||
(if (instance? CompiledPath path)
|
[(assoc binding :offset 0)]
|
||||||
path-sym
|
(let [last-binding (last bindings)]
|
||||||
`(bind-params ~path-sym ~PARAMS-SYM (+ ~PARAMS-IDX-SYM ~offset))
|
(conj bindings
|
||||||
)
|
(assoc binding
|
||||||
])
|
:offset
|
||||||
num-params-seq)
|
`(+ ~(:offset-sym last-binding)
|
||||||
(apply concat))
|
(num-needed-params ~(:path-sym last-binding)))
|
||||||
params-needed-path (closed-code closure (paramspath* make-paths num-params impls))]
|
))
|
||||||
(if (= num-params 0)
|
)))
|
||||||
(bind-params params-needed-path nil 0)
|
[]))
|
||||||
params-needed-path)
|
binding-decls (mapcat (fn [b] [(:path-sym b) (:path b)]) bindings)
|
||||||
))
|
offset-decls (mapcat (fn [b] [(:offset-sym b) (:offset b)]) bindings)
|
||||||
|
needed-params (map (fn [b] `(num-needed-params ~(:path-sym b))) bindings)
|
||||||
|
latefn-decls (mapcat
|
||||||
|
(fn [b]
|
||||||
|
[(:latebind-sym b)
|
||||||
|
`(if (instance? CompiledPath ~(:path-sym b))
|
||||||
|
(fn [params# params-idx#] ~(:path-sym b))
|
||||||
|
(fn [params# params-idx#]
|
||||||
|
(bind-params ~(:path-sym b)
|
||||||
|
params#
|
||||||
|
(+ params-idx#
|
||||||
|
~(:offset-sym b)))
|
||||||
|
))
|
||||||
|
])
|
||||||
|
bindings)
|
||||||
|
|
||||||
|
num-params-sym (gensym "num-params")
|
||||||
|
latebindings (mapcat
|
||||||
|
(fn [b]
|
||||||
|
[(:late-sym b) `(~(:latebind-sym b) ~PARAMS-SYM ~PARAMS-IDX-SYM)])
|
||||||
|
bindings)]
|
||||||
|
`(let [~@binding-decls
|
||||||
|
~@offset-decls
|
||||||
|
~num-params-sym (+ ~@needed-params)
|
||||||
|
~@latefn-decls
|
||||||
|
ret# ~(paramspath* latebindings num-params-sym impls)]
|
||||||
|
(if (= 0 ~num-params-sym)
|
||||||
|
(bind-params ret# nil 0)
|
||||||
|
ret#
|
||||||
|
))))
|
||||||
|
|
||||||
;; cell implementation idea taken from prismatic schema library
|
;; cell implementation idea taken from prismatic schema library
|
||||||
(defprotocol PMutableCell
|
(defprotocol PMutableCell
|
||||||
|
|
@ -502,7 +521,7 @@
|
||||||
(get-cell ret)
|
(get-cell ret)
|
||||||
))
|
))
|
||||||
|
|
||||||
(defn- filter+ancestry [path aseq]
|
(defn filter+ancestry [path aseq]
|
||||||
(let [aseq (vec aseq)]
|
(let [aseq (vec aseq)]
|
||||||
(reduce (fn [[s m :as orig] i]
|
(reduce (fn [[s m :as orig] i]
|
||||||
(let [e (get aseq i)
|
(let [e (get aseq i)
|
||||||
|
|
@ -573,23 +592,6 @@
|
||||||
(transform* [^CodeWalkerStructurePath this structure next-fn]
|
(transform* [^CodeWalkerStructurePath this structure next-fn]
|
||||||
(codewalk-until (.-afn this) next-fn structure)))
|
(codewalk-until (.-afn this) next-fn structure)))
|
||||||
|
|
||||||
|
|
||||||
(deftype FilterStructurePath [path])
|
|
||||||
|
|
||||||
(extend-protocol p/StructurePath
|
|
||||||
FilterStructurePath
|
|
||||||
(select* [^FilterStructurePath this structure next-fn]
|
|
||||||
(->> structure (filter #(selected?* (.-path this) %)) doall next-fn))
|
|
||||||
(transform* [^FilterStructurePath this structure next-fn]
|
|
||||||
(let [[filtered ancestry] (filter+ancestry (.-path this) structure)
|
|
||||||
;; the vec is necessary so that we can get by index later
|
|
||||||
;; (can't get by index for cons'd lists)
|
|
||||||
next (vec (next-fn filtered))]
|
|
||||||
(reduce (fn [curr [newi oldi]]
|
|
||||||
(assoc curr oldi (get next newi)))
|
|
||||||
(vec structure)
|
|
||||||
ancestry))))
|
|
||||||
|
|
||||||
(deftype SelectCollector [sel-fn selector])
|
(deftype SelectCollector [sel-fn selector])
|
||||||
|
|
||||||
(extend-protocol p/Collector
|
(extend-protocol p/Collector
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue