diff --git a/src/expand.clj b/src/expand.clj index a4fe9a5..2e6bc74 100644 --- a/src/expand.clj +++ b/src/expand.clj @@ -18,7 +18,7 @@ (s/def ::pattern (s/or :var (s/and symbol? - (comp not #{'... '_})) + #(not= '... %)) :lit ::literal :list (s/and seq? (s/cat :leading (s/* ::pattern) @@ -158,20 +158,26 @@ (comment (transcribe (unify '((a ...) ...) - '((1 2) (3 4))) - '((a ...) ...))) + '((1 2) (3 4) (5 6))) + '(begin (a ...) ...)) + (strip-ellipsis + '[:ellipsis ([:ellipsis (1 2)] [:ellipsis (3 4)] [:ellipsis (5 6)])] + 2)) -(defn transcribe* [depth index unification template] +(defn- strip-ellipsis [unif ellipsis-depth] + (match unif + [:ellipsis p] + (if (< 0 ellipsis-depth) + (map #(strip-ellipsis % (dec ellipsis-depth)) p) + (throw (ex-info "나쁜 점점점" {}))) + :else unif)) + +(defn- transcribe* [ellipsis-depth unification template] (match template [:var x] (match (get unification x) - [:ellipsis p] - (if (< 0 depth) - (if (seq? p) - (recur (dec depth) index - (assoc unification x - (nth p index)))) - (throw (ex-info "ellipsis bad" {}))) + ([:ellipsis _] :as p) + (strip-ellipsis p ellipsis-depth) (_ :guard nil?) #_(throw (ex-info "unbound" {:symbol x})) @@ -180,14 +186,15 @@ p p) [:list ts] - (->> (for [[i t] (map-indexed (fn [i x] [i x]) ts)] - (match t - [:ellipsis t*] (transcribe* (inc depth) i unification t*) - :else [(transcribe* depth i unification t)])) - (apply concat)))) + (do #_ #dbg (+ 0 0) + (->> (for [t ts] + (match t + [:ellipsis t*] (transcribe* (inc ellipsis-depth) unification t*) + :else [(transcribe* ellipsis-depth unification t)])) + (apply concat))))) (defn transcribe [unification template] - (transcribe* 0 0 unification (s/conform ::template template))) + (transcribe* 0 unification (s/conform ::template template))) diff --git a/test/expand_test.clj b/test/expand_test.clj index cee6a01..92256e2 100644 --- a/test/expand_test.clj +++ b/test/expand_test.clj @@ -107,4 +107,7 @@ '((x y) ...) '(x ... y ...) '(1 2 3 4) '(1 2 3 4) - '(x ...) '(x ...))) + '(x ...) '(x ...) + + '(concat (1 2) (3 4) (5 6)) '((1 2) (3 4) (5 6)) + '((a ...) ...) '(concat (a ...) ...)))