From 097bcf6a118954d60e26a2035e7702c91c17eecc Mon Sep 17 00:00:00 2001 From: Jason Jackson Date: Sun, 13 May 2012 12:41:44 -0400 Subject: [PATCH][BUILD] map matching always checks for presence of key, even if wildcard matching on value Signed-off-by: Jason Jackson --- src/main/clojure/clojure/core/match.clj | 21 +++++-- src/test/clojure/clojure/core/match/test/core.clj | 65 ++++++++++++++++++++- 2 files changed, 78 insertions(+), 8 deletions(-) diff --git a/src/main/clojure/clojure/core/match.clj b/src/main/clojure/clojure/core/match.clj index 4fc0954..c595682 100644 --- a/src/main/clojure/clojure/core/match.clj +++ b/src/main/clojure/clojure/core/match.clj @@ -128,7 +128,10 @@ (.valAt this k not-found))) (defn val-at* - ([m k] (val-at m k nil)) + ([m k] (let [val (val-at m k ::not-found)] + (if (= val ::not-found) + (throw backtrack) + val))) ([m k not-found] (val-at m k not-found))) (defn val-at-expr [& args] @@ -295,8 +298,8 @@ (conj bindings [sym bind-expr]) bindings) bindings (if (named-wildcard-pattern? p) - (conj bindings [(sym p) bind-expr]) - bindings)] + (conj bindings [(sym p) bind-expr]) + bindings)] (PatternRow. (drop-nth ps n) action bindings))) IVecMod @@ -849,8 +852,10 @@ (defn ^WildcardPattern wildcard-pattern ([] (WildcardPattern. '_ nil)) ([sym] - {:pre [(symbol? sym)]} - (WildcardPattern. sym nil))) + {:pre [(symbol? sym)]} + (if (= sym '_) + (WildcardPattern. (gensym) nil) + (WildcardPattern. sym nil)))) (defn wildcard-pattern? [x] (instance? WildcardPattern x)) @@ -1011,7 +1016,9 @@ (to-source* [this ocr] (if *clojurescript* `(or (satisfies? cljs.core.ILookup ~ocr)) - `(or (instance? clojure.lang.ILookup ~ocr) (satisfies? IMatchLookup ~ocr)))) + `(or + (instance? clojure.lang.ILookup ~ocr) + (satisfies? IMatchLookup ~ocr)))) Object (toString [_] (str m " :only " (or (:only _meta) []))) @@ -1758,4 +1765,4 @@ (let [bindvars# (take-nth 2 bindings)] `(let ~bindings (match [~@bindvars#] - ~@body)))) \ No newline at end of file + ~@body)))) diff --git a/src/test/clojure/clojure/core/match/test/core.clj b/src/test/clojure/clojure/core/match/test/core.clj index 65f6165..4fc0cb1 100644 --- a/src/test/clojure/clojure/core/match/test/core.clj +++ b/src/test/clojure/clojure/core/match/test/core.clj @@ -76,11 +76,74 @@ (is (= (let [x {:a 1 :b 1}] (match [x] [{:a _ :b 2}] :a0 - [{:a 1 :c _}] :a1 + [{:a 1 :b 1}] :a1 + [{:c 3 :d _ :e 4}] :a2 + :else [])) + :a1))) + +(deftest map-pattern-match-2 + (is (= (let [x {:a 1 :b 1}] + (match [x] + [{:a _ :b 1}] :a0 + [{:a 1 :b _}] :a1 + [{:c 3 :d _ :e 4}] :a2 + :else [])) + :a0))) + +(deftest map-pattern-match-3 + (is (= (let [x {:a 1 :b 1 :c 1}] + (match [x] + [{:a _ :b 2}] :a0 + [{:a 1 :b _}] :a1 + [{:c 3 :d _ :e 4}] :a2 + :else [])) + :a1))) + +(deftest map-pattern-match-4 + (is (= (let [x {:a 1 :b 1}] + (match [x] + [{:a _ :b 2}] :a0 + [{:a _ :b _}] :a1 [{:c 3 :d _ :e 4}] :a2 :else [])) :a1))) +(deftest map-pattern-match-5 + (is (= (let [x {:a 1}] + (match [x] + [{:a 1 :b 1}] :a0 + [{:a _ :b _}] :a1 + [{:c 3 :d _ :e 4}] :a2 + :else [])) + []))) + +(deftest map-pattern-match-6 + (is (= (let [x {:a 1 :b 1}] + (match [x] + [{:b 1}] :a0 + [{:a _ :b _}] :a1 + [{:a _ :b _}] :a2 + :else [])) + :a0))) + +(deftest map-pattern-match-7 + (is (= (let [x {:a 1 :b 1}] + (match [x] + [{}] :a0 + [{:a _ :b _}] :a1 + [{:a 1 :b 1}] :a2 + :else [])) + :a0))) + +(deftest map-pattern-match-8 + (is (= (let [x {:a 1 :b 1}] + (match [x] + [{:x nil :y nil}] :a0 + [{:a _ :b _}] :a1 + [{:a 1 :b 1}] :a2 + :else [])) + :a1))) + (deftest map-pattern-match-only-1 (is (= (let [x {:a 1 :b 2}] (match [x] -- 1.7.4.4