From fc6392cc9e56c3933ac1fdcecb0cb6470b43135b Mon Sep 17 00:00:00 2001 From: Nathan Marz Date: Thu, 10 Sep 2015 23:09:19 -0400 Subject: [PATCH] implement pathed collectors and convert collect and collect-one --- src/com/rpl/specter.cljc | 29 +++++++++++++++++++++---- src/com/rpl/specter/impl.cljc | 41 +++++++++++++++++------------------ 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/src/com/rpl/specter.cljc b/src/com/rpl/specter.cljc index 8f939ca..1673975 100644 --- a/src/com/rpl/specter.cljc +++ b/src/com/rpl/specter.cljc @@ -137,6 +137,7 @@ latefns-sym (gensym "latefns") latefn-syms (vec (i/gensyms (count paths)))] (i/pathed-path* + i/paramspath* paths latefns-sym [latefn-syms latefns-sym] @@ -146,6 +147,7 @@ (defmacro variable-pathed-path [[latepaths-seq-sym paths-seq] & impls] (let [latefns-sym (gensym "latefns")] (i/pathed-path* + i/paramspath* paths-seq latefns-sym [] @@ -154,6 +156,19 @@ impls ))) +(defmacro pathed-collector [[name path] impl] + (let [latefns-sym (gensym "latefns") + latefn (gensym "latefn")] + (i/pathed-path* + i/paramscollector* + [path] + latefns-sym + [[latefn] latefns-sym] + [name `(~latefn ~i/PARAMS-SYM ~i/PARAMS-IDX-SYM)] + impl + ) + )) + ;; Built-in pathing and context operations (def ALL (i/->AllStructurePath)) @@ -273,11 +288,17 @@ (transform* [aset structure next-fn] (i/filter-transform aset structure next-fn))) -(defn collect [& selector] - (i/->SelectCollector select (i/comp-paths* selector))) +(defn collect [& path] + (pathed-collector [late path] + (collect* [this structure] + (compiled-select late structure) + ))) -(defn collect-one [& selector] - (i/->SelectCollector select-one (i/comp-paths* selector))) +(defn collect-one [& path] + (pathed-collector [late path] + (collect* [this structure] + (compiled-select-one late structure) + ))) ;;TODO: add this comment: diff --git a/src/com/rpl/specter/impl.cljc b/src/com/rpl/specter/impl.cljc index 2edf76d..beb1016 100644 --- a/src/com/rpl/specter/impl.cljc +++ b/src/com/rpl/specter/impl.cljc @@ -381,12 +381,30 @@ ~num-params ))) +(defn paramscollector* [post-bindings num-params [_ [_ structure-sym] & body]] + `(let [collector# (fn [~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~structure-sym next-fn#] + (let [~@post-bindings ~@[] ; to avoid syntax highlighting issues + c# (do ~@body)] + (next-fn# + ~PARAMS-SYM + (+ ~PARAMS-IDX-SYM ~num-params) + (conj vals# c#) + ~structure-sym) + ))] + (->ParamsNeededPath + (->TransformFunctions + RichPathExecutor + collector# + collector# ) + ~num-params + ))) + (defn num-needed-params [path] (if (instance? CompiledPath path) 0 (:num-needed-params path))) -(defn pathed-path* [paths-seq latefns-sym pre-bindings post-bindings impls] +(defn pathed-path* [builder paths-seq latefns-sym pre-bindings post-bindings impls] (let [num-params-sym (gensym "num-params")] `(let [paths# (map comp-paths* ~paths-seq) needed-params# (map num-needed-params paths#) @@ -403,32 +421,13 @@ offsets# paths#) ~@pre-bindings - ret# ~(paramspath* post-bindings num-params-sym impls) + ret# ~(builder post-bindings num-params-sym impls) ] (if (= 0 ~num-params-sym) (bind-params* ret# nil 0) ret# )))) - -(defn paramscollector* [bindings num-params [_ [_ structure-sym] & body]] - `(let [collector# (fn [~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~structure-sym next-fn#] - (let [~@bindings ~@[] ; to avoid syntax highlighting issues - c# (do ~@body)] - (next-fn# - ~PARAMS-SYM - (+ ~PARAMS-IDX-SYM ~num-params) - (conj vals# c#) - ~structure-sym) - ))] - (->ParamsNeededPath - (->TransformFunctions - RichPathExecutor - collector# - collector# ) - ~num-params - ))) - (defn make-param-retrievers [params] (->> params (map-indexed