summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2023-04-11 22:20:20 +0300
committerGitHub <noreply@github.com>2023-04-11 21:20:20 +0200
commitf05387045df55bf7123ee68002238e943716815e (patch)
tree9ba7959434162830612e31351eadbae79cf3bc37 /lib/pure
parentbe06446ffecd7665651a25d6b07fade5cc019296 (diff)
downloadNim-f05387045df55bf7123ee68002238e943716815e.tar.gz
int64/uint64 as bigint in JS (#21613)
* int64/uint64 as bigint in JS

* fix CI

* convert to compile option

* fix lie

* smaller diff, changelog entry
Diffstat (limited to 'lib/pure')
-rw-r--r--lib/pure/json.nim2
-rw-r--r--lib/pure/random.nim19
-rw-r--r--lib/pure/strutils.nim10
-rw-r--r--lib/pure/times.nim2
4 files changed, 18 insertions, 15 deletions
diff --git a/lib/pure/json.nim b/lib/pure/json.nim
index d91da3545..45b22cea5 100644
--- a/lib/pure/json.nim
+++ b/lib/pure/json.nim
@@ -1110,7 +1110,7 @@ proc initFromJson(dst: var JsonNode; jsonNode: JsonNode; jsonPath: var string) =
   dst = jsonNode.copy
 
 proc initFromJson[T: SomeInteger](dst: var T; jsonNode: JsonNode, jsonPath: var string) =
-  when T is uint|uint64 or (not defined(js) and int.sizeof == 4):
+  when T is uint|uint64 or int.sizeof == 4:
     verifyJsonKind(jsonNode, {JInt, JString}, jsonPath)
     case jsonNode.kind
     of JString:
diff --git a/lib/pure/random.nim b/lib/pure/random.nim
index c36ab445b..422f42a8b 100644
--- a/lib/pure/random.nim
+++ b/lib/pure/random.nim
@@ -72,7 +72,7 @@ runnableExamples:
 ##   in the standard library
 
 import algorithm, math
-import std/private/since
+import std/private/[since, jsutils]
 
 when defined(nimPreviewSlimSystem):
   import std/[assertions]
@@ -231,11 +231,14 @@ proc rand[T: uint | uint64](r: var Rand; max: T): T =
     let max = uint64(max)
     when T.high.uint64 == uint64.high:
       if max == uint64.high: return T(next(r))
+    var iters = 0
     while true:
       let x = next(r)
       # avoid `mod` bias
-      if x <= randMax - (randMax mod max):
+      if x <= randMax - (randMax mod max) or iters > 20:
         return T(x mod (max + 1))
+      else:
+        inc iters
 
 proc rand*(r: var Rand; max: Natural): int {.benign.} =
   ## Returns a random integer in the range `0..max` using the given state.
@@ -337,9 +340,9 @@ proc rand*[T: Ordinal or SomeFloat](r: var Rand; x: HSlice[T, T]): T =
   when T is SomeFloat:
     result = rand(r, x.b - x.a) + x.a
   else: # Integers and Enum types
-    when defined(js):
+    whenJsNoBigInt64:
       result = cast[T](rand(r, cast[uint](x.b) - cast[uint](x.a)) + cast[uint](x.a))
-    else:
+    do:
       result = cast[T](rand(r, cast[uint64](x.b) - cast[uint64](x.a)) + cast[uint64](x.a))
 
 proc rand*[T: Ordinal or SomeFloat](x: HSlice[T, T]): T =
@@ -378,14 +381,14 @@ proc rand*[T: Ordinal](r: var Rand; t: typedesc[T]): T {.since: (1, 7, 1).} =
   when T is range or T is enum:
     result = rand(r, low(T)..high(T))
   elif T is bool:
-    when defined(js):
+    whenJsNoBigInt64:
       result = (r.next or 0) < 0
-    else:
+    do:
       result = cast[int64](r.next) < 0
   else:
-    when defined(js):
+    whenJsNoBigInt64:
       result = cast[T](r.next shr (sizeof(uint)*8 - sizeof(T)*8))
-    else:
+    do:
       result = cast[T](r.next shr (sizeof(uint64)*8 - sizeof(T)*8))
 
 proc rand*[T: Ordinal](t: typedesc[T]): T =
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index c458d605e..0a77e8bf6 100644
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -79,7 +79,7 @@ from unicode import toLower, toUpper
 export toLower, toUpper
 
 include "system/inclrtl"
-import std/private/since
+import std/private/[since, jsutils]
 from std/private/strimpl import cmpIgnoreStyleImpl, cmpIgnoreCaseImpl,
     startsWithImpl, endsWithImpl
 
@@ -944,9 +944,9 @@ func toHex*[T: SomeInteger](x: T, len: Positive): string =
     doAssert b.toHex(4) == "1001"
     doAssert toHex(62, 3) == "03E"
     doAssert toHex(-8, 6) == "FFFFF8"
-  when defined(js):
+  whenJsNoBigInt64:
     toHexImpl(cast[BiggestUInt](x), len, x < 0)
-  else:
+  do:
     when T is SomeSignedInt:
       toHexImpl(cast[BiggestUInt](BiggestInt(x)), len, x < 0)
     else:
@@ -957,9 +957,9 @@ func toHex*[T: SomeInteger](x: T): string =
   runnableExamples:
     doAssert toHex(1984'i64) == "00000000000007C0"
     doAssert toHex(1984'i16) == "07C0"
-  when defined(js):
+  whenJsNoBigInt64:
     toHexImpl(cast[BiggestUInt](x), 2*sizeof(T), x < 0)
-  else:
+  do:
     when T is SomeSignedInt:
       toHexImpl(cast[BiggestUInt](BiggestInt(x)), 2*sizeof(T), x < 0)
     else:
diff --git a/lib/pure/times.nim b/lib/pure/times.nim
index 138f2d9ec..3d644d361 100644
--- a/lib/pure/times.nim
+++ b/lib/pure/times.nim
@@ -537,7 +537,7 @@ proc getDayOfWeek*(monthday: MonthdayRange, month: Month, year: int): WeekDay
   assertValidDate monthday, month, year
   # 1970-01-01 is a Thursday, we adjust to the previous Monday
   let days = toEpochDay(monthday, month, year) - 3
-  let weeks = floorDiv(days, 7)
+  let weeks = floorDiv(days, 7'i64)
   let wd = days - weeks * 7
   # The value of d is 0 for a Sunday, 1 for a Monday, 2 for a Tuesday, etc.
   # so we must correct for the WeekDay type.