Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd9c2b52

Browse files
committed
* create Integer type so the you can pass 1N into cljs.core fns w/o blowing up
* Integer implements @@toPrimitive so that math operations work* more tests
1 parent6443339 commitd9c2b52

File tree

4 files changed

+106
-49
lines changed

4 files changed

+106
-49
lines changed

‎src/main/cljs/cljs/core.cljs

Lines changed: 85 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,20 @@
250250
(.isArray js/Array x)
251251
(instance? js/Array x)))
252252

253+
(declareInteger)
254+
253255
(defn ^booleannumber?
254256
"Returns true if x is a JavaScript Number or BigInt"
255257
[x]
256258
(or (cljs.core/js-number? x)
257-
(cljs.core/bigint? x)))
259+
(cljs.core/bigint? x)
260+
(instance? Integer x)))
261+
262+
(defn ^booleanbigint?
263+
"Returns true if x is a JavaScript Number or BigInt"
264+
[x]
265+
(or (cljs.core/bigint? x)
266+
(instance? Integer x)))
258267

259268
(defnnot
260269
"Returns true if x is logical false, false otherwise."
@@ -342,8 +351,12 @@
342351

343352
(if (and (exists? js/Symbol)
344353
(identical? (goog/typeOf js/Symbol)"function"))
345-
(defITER_SYMBOL (.-iterator js/Symbol))
346-
(defITER_SYMBOL"@@iterator"))
354+
(do
355+
(defITER_SYMBOL (.-iterator js/Symbol))
356+
(defTO_PRIM_SYMBOL (.-toPrimitive js/Symbol)))
357+
(do
358+
(defITER_SYMBOL"@@iterator")
359+
(defTO_PRIM_SYMBOL"@@toPrimitive")))
347360

348361
(def ^{:jsdoc ["@enum {string}"]}
349362
CHAR_MAP
@@ -1016,46 +1029,38 @@
10161029
(and (<= n js/Number.MAX_SAFE_INTEGER)
10171030
(>= n js/Number.MIN_SAFE_INTEGER)))
10181031

1032+
(declarehash)
1033+
1034+
(defnhash-bigint [n]
1035+
(if (safe-value? n)
1036+
(hash (js/Number. n))
1037+
(hash-string (.toString n32))))
1038+
1039+
(defnhash-number [n]
1040+
(if ^boolean (js/isFinite n)
1041+
(js-mod (Math/floor n)2147483647)
1042+
(case n
1043+
##Inf2146435072
1044+
##-Inf-1048576
1045+
2146959360)))
1046+
10191047
(defnhash
10201048
"Returns the hash code of its argument. Note this is the hash code
10211049
consistent with =."
10221050
[o]
10231051
(cond
1024-
(implements? IHash o)
1025-
(bit-xor (-hash o)0)
1026-
1027-
(cljs.core/bigint? o)
1028-
(if (safe-value? o)
1029-
(hash (js/Number. o))
1030-
(hash-string (.toString o32)))
1031-
1032-
(number? o)
1033-
(if ^boolean (js/isFinite o)
1034-
(js-mod (Math/floor o)2147483647)
1035-
(case o
1036-
##Inf
1037-
2146435072
1038-
##-Inf
1039-
-1048576
1040-
2146959360))
1041-
1052+
(implements? IHash o) (bit-xor (-hash o)0)
1053+
(bigint? o) (hash-bigint o)
1054+
(number? o) (hash-number o)
10421055
;; note: mirrors Clojure's behavior on the JVM, where the hashCode is
10431056
;; 1231 for true and 1237 for false
10441057
;; http://docs.oracle.com/javase/7/docs/api/java/lang/Boolean.html#hashCode%28%29
10451058
(true? o)1231
1046-
10471059
(false? o)1237
1048-
1049-
(string? o)
1050-
(m3-hash-int (hash-string o))
1051-
1052-
(instance? js/Date o)
1053-
(bit-xor (.valueOf o)0)
1054-
1060+
(string? o) (m3-hash-int (hash-string o))
1061+
(instance? js/Date o) (bit-xor (.valueOf o)0)
10551062
(nil? o)0
1056-
1057-
:else
1058-
(bit-xor (-hash o)0)))
1063+
:else (bit-xor (-hash o)0)))
10591064

10601065
(defnhash-combine [seed hash]
10611066
; a la boost
@@ -1094,6 +1099,45 @@
10941099

10951100
(declareget)
10961101

1102+
;; wrapper type to simplify bigint integration
1103+
;; Integer has two fields, if number is null then beyond the range of
1104+
;; JS safe integral values. bigint is set for comparisons.
1105+
(deftypeInteger [number bigint ^:mutable __hash]
1106+
Object
1107+
(toString [_]
1108+
(.toString bigint))
1109+
(equiv [this other] (-equiv this other))
1110+
1111+
IEquiv
1112+
(-equiv [_ other]
1113+
(cond
1114+
(instance? Integer other) (if (nil? number)
1115+
(== bigint (.-bigint other))
1116+
(== number (.-number other)))
1117+
(js-number? other) (== number other)
1118+
(bigint? other) (== bigint other)
1119+
:elsefalse))
1120+
1121+
IHash
1122+
(-hash [_]
1123+
(if (nil? __hash)
1124+
(if (nil? bigint)
1125+
(set! __hash (hash-number number))
1126+
(set! __hash (hash-bigint bigint))))
1127+
__hash)
1128+
1129+
IPrintWithWriter
1130+
(-pr-writer [_ writer _]
1131+
(-write writer (or number bigint))
1132+
(-write writer"N")))
1133+
1134+
(unchecked-set (.-prototype Integer) TO_PRIM_SYMBOL
1135+
(fn [hint]
1136+
(this-as this
1137+
(if (nil? (.-number this))
1138+
(.-bigint this)
1139+
(.-number this)))))
1140+
10971141
(deftypeSymbol [ns name str ^:mutable _hash _meta]
10981142
Object
10991143
(toString [_] str)
@@ -1444,16 +1488,18 @@
14441488
(extend-type number
14451489
IEquiv
14461490
(-equiv [x o]
1447-
(if (cljs.core/bigint? o)
1448-
(cljs.core/coercive-= x o)
1449-
(identical? x o))))
1491+
(cond
1492+
(bigint? o) (coercive-= x o)
1493+
(instance? Integer o) (-equiv o x)
1494+
:else (identical? x o))))
14501495

14511496
(extend-type bigint
14521497
IEquiv
14531498
(-equiv [x o]
1454-
(if (cljs.core/js-number? o)
1455-
(cljs.core/coercive-= x o)
1456-
(identical? x o))))
1499+
(cond
1500+
(js-number? o) (coercive-= x o)
1501+
(instance? Integer o) (-equiv o x)
1502+
:else (identical? x o))))
14571503

14581504
(declarewith-meta)
14591505

@@ -6735,7 +6781,7 @@ reduces them without incurring seq initialization"
67356781
:else (recur (+ i2))))))
67366782

67376783
(defn-equal-number? [x y]
6738-
(and (number? x) (number? y) (cljs.core/coercive-= x y)))
6784+
(and (number? x) (number? y) (-equiv x y)))
67396785

67406786
(defn-array-index-of-number [arr k]
67416787
(let [len (alength arr)]

‎src/main/clojure/cljs/compiler.cljc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@
316316
(defmethodemit-constant*Long [x]
317317
(if (or (> x9007199254740991)
318318
(< x-9007199254740991))
319-
(emits"(" x"n)")
319+
(emits"new cljs.core.Integer(null," x"n," (hash x)")")
320320
(emits"(" x")"))))
321321

322322
#?(:clj
@@ -350,7 +350,13 @@
350350

351351
#?(:clj
352352
(defmethodemit-constant*clojure.lang.BigInt [x]
353-
(emits"(" (.toString ^clojure.lang.BigInt x)"n)")))
353+
(if (or (> x9007199254740991)
354+
(< x-9007199254740991))
355+
;; not we don't set hash code at compile time because this is difficult to replicate
356+
(emits"new cljs.core.Integer(null," (.toString ^clojure.lang.BigInt x)"n, null)")
357+
(emits"new cljs.core.Integer("
358+
(.toString ^clojure.lang.BigInt x)"," (.toString ^clojure.lang.BigInt x)
359+
"n, null)"))))
354360

355361
(defmethodemit-constant* #?(:clj String:cljs js/String) [x]
356362
(emits (wrap-in-double-quotes (escape-string x))))

‎src/main/clojure/cljs/core.cljc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1162,7 +1162,7 @@
11621162

11631163
(core/defmacro ^::ana/numeric==
11641164
([x]true)
1165-
([x y] (bool-expr (core/list 'js*"(~{} === ~{})" x y)))
1165+
([x y] (bool-expr (core/list 'js*"(~{} == ~{})" x y)))
11661166
([x y & more] `(and (== ~x ~y) (== ~y ~@more))))
11671167

11681168
(core/defmacro ^::ana/numericdec [x]

‎src/test/cljs/cljs/bigint_test.cljs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,28 @@
1515
(is (bigint?9007199254740992))
1616
(is (bigint?-9007199254740992)))
1717
(testing"BigInt & Number equality"
18-
;; the below is a bit backwards from Clojure
19-
;; i.e. (= 0.5 1/2) ; false
20-
;; but (== 0.5 1/2) ; true
2118
(is (=11N))
2219
(is (=1N1))
2320
(is (=11N1))
24-
(is (not (==11N)))
25-
(is (not (==1N1)))
26-
(is (not (==11N1))))
21+
(is (==11N))
22+
(is (==1N1))
23+
(is (==11N1)))
2724
(testing"BigInt Hashing"
2825
(is (= (hash1N) (hash1)))
2926
(is (= (hash9007199254740992) (hash9007199254740992)))
3027
(is (= (hash-9007199254740992) (hash-9007199254740992))))
3128
(testing"BigInt as HashMap keys"
3229
(let [m {1N2}]
3330
(is (=2 (get m1N)))
34-
(is (=2 (get m1))))))
31+
(is (=2 (get m1)))))
32+
(testing"Interop"
33+
(is (= (js/BigInt1)1N))
34+
(is (=1N (js/BigInt1)))
35+
(is (= (js/BigInt1)1N))
36+
(is (= (js/BigInt1)1))
37+
(is (=1 (js/BigInt1))))
38+
(testing"Interaction with core"
39+
(is (= (range15) (range15N)))))
3540

3641
(comment
3742

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp