diff --git a/src/main/cljs/cljs/core.cljs b/src/main/cljs/cljs/core.cljs index b8d4a79534..af9a35cfb8 100644 --- a/src/main/cljs/cljs/core.cljs +++ b/src/main/cljs/cljs/core.cljs @@ -9650,7 +9650,7 @@ reduces them without incurring seq initialization" (take-while (mk-bound-fn sc start-test start-key) (if ((mk-bound-fn sc end-test end-key) e) s (next s)))))) -(deftype RangeChunk [start step count] +(deftype IntegerRangeChunk [start step count] ICounted (-count [coll] count) @@ -9669,7 +9669,7 @@ reduces them without incurring seq initialization" (-drop-first [coll] (if (<= count 1) (throw (js/Error. "-drop-first of empty chunk")) - (RangeChunk. (+ start step) step (dec count))))) + (IntegerRangeChunk. (+ start step) step (dec count))))) (deftype RangeIterator [^:mutable i end step] Object @@ -9682,7 +9682,7 @@ reduces them without incurring seq initialization" (set! i (+ i step)) ret))) -(deftype Range [meta start end step ^:mutable chunk ^:mutable chunk-next ^:mutable __hash] +(deftype IntegerRange [meta start end step ^:mutable chunk ^:mutable chunk-next ^:mutable __hash] Object (toString [coll] (pr-str* coll)) @@ -9701,18 +9701,18 @@ reduces them without incurring seq initialization" (let [count (-count coll)] (if (> count 32) (do - (set! chunk-next (Range. nil (+ start (* step 32)) end step nil nil nil)) - (set! chunk (RangeChunk. start step 32))) - (set! chunk (RangeChunk. start step count)))))) + (set! chunk-next (IntegerRange. nil (+ start (* step 32)) end step nil nil nil)) + (set! chunk (IntegerRangeChunk. start step 32))) + (set! chunk (IntegerRangeChunk. start step count)))))) ICloneable - (-clone [_] (Range. meta start end step chunk chunk-next __hash)) + (-clone [_] (IntegerRange. meta start end step chunk chunk-next __hash)) IWithMeta (-with-meta [rng new-meta] (if (identical? new-meta meta) rng - (Range. new-meta start end step chunk chunk-next __hash))) + (IntegerRange. new-meta start end step chunk chunk-next __hash))) IMeta (-meta [rng] meta) @@ -9736,9 +9736,9 @@ reduces them without incurring seq initialization" (-next [rng] (if (pos? step) (when (< (+ start step) end) - (Range. nil (+ start step) end step nil nil nil)) + (IntegerRange. nil (+ start step) end step nil nil nil)) (when (> (+ start step) end) - (Range. nil (+ start step) end step nil nil nil)))) + (IntegerRange. nil (+ start step) end step nil nil nil)))) IChunkedSeq (-chunked-first [rng] @@ -9796,6 +9796,113 @@ reduces them without incurring seq initialization" (recur (+ i step) ret))) ret)))) +(es6-iterable IntegerRange) + +(deftype Range [meta start end step ^:mutable chunk ^:mutable chunk-next ^:mutable __hash] + Object + (toString [coll] + (pr-str* coll)) + (equiv [this other] + (-equiv this other)) + (indexOf [coll x] + (-indexOf coll x 0)) + (indexOf [coll x start] + (-indexOf coll x start)) + (lastIndexOf [coll x] + (-lastIndexOf coll x (count coll))) + (lastIndexOf [coll x start] + (-lastIndexOf coll x start)) + (forceChunk [coll] + (when (nil? chunk) + (let [arr (make-array 32) + val (loop [n 0 val start] + (if (< n 32) + (do + (aset arr n val) + (let [n (inc n) + val (+ val step)] + (if (if (pos? step) (< val end) (> val end)) + (recur n val) + (set! chunk (array-chunk arr 0 n))))) + val))] + (when (nil? chunk) + (set! chunk (array-chunk arr 0 32)) + (when (if (pos? step) (< val end) (> val end)) + (set! chunk-next (Range. nil val end step nil nil nil))))))) + + ICloneable + (-clone [_] (Range. meta start end step chunk chunk-next __hash)) + + IWithMeta + (-with-meta [rng new-meta] + (if (identical? new-meta meta) + rng + (Range. new-meta start end step chunk chunk-next __hash))) + + IMeta + (-meta [rng] meta) + + ISeqable + (-seq [rng] rng) + + ISeq + (-first [rng] start) + (-rest [rng] + (let [s (-next rng)] + (if (nil? s) + () + s))) + + IIterable + (-iterator [_] + (RangeIterator. start end step)) + + INext + (-next [rng] + (if (pos? step) + (when (< (+ start step) end) + (Range. nil (+ start step) end step nil nil nil)) + (when (> (+ start step) end) + (Range. nil (+ start step) end step nil nil nil)))) + + IChunkedSeq + (-chunked-first [rng] + (.forceChunk rng) + chunk) + (-chunked-rest [rng] + (.forceChunk rng) + (if (nil? chunk-next) + () + chunk-next)) + + IChunkedNext + (-chunked-next [rng] + (seq (-chunked-rest rng))) + + ICollection + (-conj [rng o] (cons o rng)) + + IEmptyableCollection + (-empty [rng] (.-EMPTY List)) + + ISequential + IEquiv + (-equiv [rng other] (equiv-sequential rng other)) + + IHash + (-hash [rng] (caching-hash rng hash-ordered-coll __hash)) + + IReduce + (-reduce [rng f] (seq-reduce f rng)) + (-reduce [rng f init] + (loop [i start ret init] + (if (if (pos? step) (< i end) (> i end)) + (let [ret (f ret i)] + (if (reduced? ret) + @ret + (recur (+ i step) ret))) + ret)))) + (es6-iterable Range) (defn range @@ -9810,12 +9917,16 @@ reduces them without incurring seq initialization" (pos? step) (if (<= end start) () - (Range. nil start end step nil nil nil)) + (if (and (integer? start) (integer? end) (integer? step)) + (IntegerRange. nil start end step nil nil nil) + (Range. nil start end step nil nil nil))) (neg? step) (if (>= end start) () - (Range. nil start end step nil nil nil)) + (if (and (integer? start) (integer? end) (integer? step)) + (IntegerRange. nil start end step nil nil nil) + (Range. nil start end step nil nil nil))) :else (if (== end start) @@ -10429,6 +10540,9 @@ reduces them without incurring seq initialization" Range (-pr-writer [coll writer opts] (pr-sequential-writer writer pr-writer "(" " " ")" opts coll)) + IntegerRange + (-pr-writer [coll writer opts] (pr-sequential-writer writer pr-writer "(" " " ")" opts coll)) + Cycle (-pr-writer [coll writer opts] (pr-sequential-writer writer pr-writer "(" " " ")" opts coll)) diff --git a/src/test/cljs/cljs/collections_test.cljs b/src/test/cljs/cljs/collections_test.cljs index 2c63d297a0..f41ce78217 100644 --- a/src/test/cljs/cljs/collections_test.cljs +++ b/src/test/cljs/cljs/collections_test.cljs @@ -9,6 +9,10 @@ (ns cljs.collections-test (:refer-clojure :exclude [iter]) (:require [cljs.test :refer-macros [deftest testing is are run-tests]] + [clojure.test.check :as tc] + [clojure.test.check.clojure-test :refer-macros [defspec]] + [clojure.test.check.generators :as gen] + [clojure.test.check.properties :as prop :include-macros true] [clojure.string :as s] [clojure.set :as set])) @@ -141,10 +145,18 @@ (is (= #{1} (disj #{1 2 3} 2 3))) (is (nil? (disj nil :foo))))) +(defspec integerrange-equals-range 100 + (prop/for-all [start gen/int + end gen/int + step gen/s-pos-int] + (= (Range. nil start end step nil nil nil) + (IntegerRange. nil start end step nil nil nil)))) + (deftest test-range (testing "Testing Range" ;; Range (is (= (range 0 10 3) (list 0 3 6 9))) + (is (= (range 2.5) '(0 1 2))) (is (= (count (range 0 10 3)) 4)) (is (= (range 0 -10 -3) (list 0 -3 -6 -9))) (is (= (count (range 0 -10 -3)) 4)) @@ -163,6 +175,45 @@ (is (= (count (range 0 0 0)) 0)) (is (= (take 3 (range 1 0 0)) (list 1 1 1))) (is (= (take 3 (range 3 1 0)) (list 3 3 3))) + (is (not (counted? (range)))) + (is (counted? (range 0 10 1))) + (is (not (counted? (range 0.1 10 1)))) + (is (chunked-seq? (range 0 10 1))) + (is (chunked-seq? (range 0.1 10 1))) + (is (= (range 0.5 8 1.2) '(0.5 1.7 2.9 4.1 5.3 6.5 7.7))) + (is (= (range 0.5 -4 -2) '(0.5 -1.5 -3.5))) + (is (= (reduce + (range 0 100)) 4950)) + (is (= (reduce + 0 (range 0 100)) 4950)) + (is (= (reduce + (range 0.1 100)) 4960)) + (is (= (reduce + 0 (range 0.1 100)) 4960)) + (is (= (reduce + (map inc (range 0 100 1))) 5050)) + (is (= (reduce + 0 (map inc (range 0 100 1))) 5050)) + (is (= (reduce + (map inc (range 0 100 0.1))) 51051)) + (is (= (reduce + 0 (map inc (range 0 100 0.1))) 51051)) + (is (= (reduce + (range 0 3.1 0.1)) 46.500000000000014)) + (is (= (reduce + 0 (range 0 3.1 0.1)) 46.500000000000014)) + (is (= (reduce + (range 0 3.2 0.1)) 49.600000000000016)) + (is (= (reduce + 0 (range 0 3.2 0.1)) 49.600000000000016)) + (is (= (reduce + (range 0 3.3 0.1)) 52.80000000000002)) + (is (= (reduce + 0 (range 0 3.3 0.1)) 52.80000000000002)) + (is (= (reduce + (range 0 -3.1 -0.1)) -46.500000000000014)) + (is (= (reduce + 0 (range 0 -3.1 -0.1)) -46.500000000000014)) + (is (= (reduce + (range 0 -3.2 -0.1)) -49.600000000000016)) + (is (= (reduce + 0 (range 0 -3.2 -0.1)) -49.600000000000016)) + (is (= (reduce + (range 0 -3.3 -0.1)) -52.80000000000002)) + (is (= (reduce + 0 (range 0 -3.3 -0.1)) -52.80000000000002)) + (is (= (reduce + (map inc (range 0 3.1 0.1))) 77.50000000000001)) + (is (= (reduce + 0 (map inc (range 0 3.1 0.1))) 77.50000000000001)) + (is (= (reduce + (map inc (range 0 3.2 0.1))) 81.60000000000002)) + (is (= (reduce + 0 (map inc (range 0 3.2 0.1))) 81.60000000000002)) + (is (= (reduce + (map inc (range 0 3.3 0.1))) 85.80000000000003)) + (is (= (reduce + 0 (map inc (range 0 3.3 0.1))) 85.80000000000003)) + (is (= (reduce + (map inc (range 0 -3.1 -0.1))) -15.500000000000012)) + (is (= (reduce + 0 (map inc (range 0 -3.1 -0.1))) -15.500000000000012)) + (is (= (reduce + (map inc (range 0 -3.2 -0.1))) -17.600000000000016)) + (is (= (reduce + 0 (map inc (range 0 -3.2 -0.1))) -17.600000000000016)) + (is (= (reduce + (map inc (range 0 -3.3 -0.1))) -19.80000000000002)) + (is (= (reduce + 0 (map inc (range 0 -3.3 -0.1))) -19.80000000000002)) )) (deftest test-cycle diff --git a/src/test/cljs/cljs/core_test.cljs b/src/test/cljs/cljs/core_test.cljs index 6223e5c26a..ff38f8abc8 100644 --- a/src/test/cljs/cljs/core_test.cljs +++ b/src/test/cljs/cljs/core_test.cljs @@ -621,16 +621,6 @@ (is (= (meta (with-meta (reify IFoo (foo [this] :foo)) {:foo :bar})) {:foo :bar}))) - -(defprotocol Slashy (/ [_])) - -(extend-type string - Slashy - (/ [_] "result")) - -(deftest test-protocol-with-slash - (is (= "result" (/ "")))) - (let [x "original"] (defn original-closure-stmt [] x)) @@ -1818,4 +1808,10 @@ (deftest test-cljs-3202 (is (= :/ (keyword "/"))) - (is (= (hash :/) (hash (keyword "/"))))) \ No newline at end of file + (is (= (hash :/) (hash (keyword "/"))))) + +(deftest test-cljs-3270 + (is (== 10 (count (range 0 (+ 1 (/ 9)) (/ 9)))))) + +(deftest test-cljs-3271 + (is (== 0.6 (nth (range 0 1 0.1) 6)))) diff --git a/src/test/cljs/cljs/extend_to_native_test.cljs b/src/test/cljs/cljs/extend_to_native_test.cljs index 378451d15b..e0d7446b5f 100644 --- a/src/test/cljs/cljs/extend_to_native_test.cljs +++ b/src/test/cljs/cljs/extend_to_native_test.cljs @@ -135,3 +135,12 @@ (is (= :p (test-seqable 1))) (extend-type string IReduce (-reduce [_ _] :q)) (is (= :q (test-reduceable "a")))) + +(defprotocol Slashy (/ [_])) + +(extend-type string + Slashy + (/ [_] "result")) + +(deftest test-protocol-with-slash + (is (= "result" (/ ""))))