 (defn- accept? [{:keys [::op]}]
   (= ::accept op))
 
-(defn- pcat* [{[p1 & pr :as ps] :ps,  [k1 & kr :as ks] :ks, [f1 & fr :as forms] :forms, ret :ret}]
+(defn- pcat* [{[p1 & pr :as ps] :ps,  [k1 & kr :as ks] :ks, [f1 & fr :as forms] :forms, ret :ret, rep+ :rep+}]
   (when (every? identity ps)
     (if (accept? p1)
       (let [rp (:ret p1)

            ::alt (alt* (map #(deriv % x) ps) ks forms)
            ::rep (rep* (deriv p1 x) p2 ret splice forms)))))

(defn- op-describe [p]
  ;;(prn {:op op :ks ks :forms forms})
  (let [{:keys [::op ps ks forms splice p1] :as p} (reg-resolve p)]
    (when p
      (case op
            ::accept nil
            nil p
            ::amp (list* 'clojure.spec/& (op-describe p1) forms)
            ::pcat (cons `cat (mapcat vector ks forms))
            ::alt (cons `alt (mapcat vector ks forms))
            ::rep (list (if splice `+ `*) forms)))))


        (if pr
          (pcat* {:ps pr :ks kr :forms fr :ret ret})
          (accept ret)))
      {::op ::pcat, :ps ps, :ret ret, :ks ks, :forms forms :rep+ rep+})))

(defn- pcat [& ps] (pcat* {:ps ps :ret []}))

