fix stringify unsigned integer in JS and JS VM (#17086)

* fix js unsigned integer

* better
This commit is contained in:
flywind
2021-02-18 13:13:52 -06:00
committed by GitHub
parent 8fd1ed6dfe
commit cd274a5ac9
2 changed files with 57 additions and 18 deletions

View File

@@ -3,6 +3,26 @@ proc `$`*(x: int): string {.magic: "IntToStr", noSideEffect.}
## converted to a decimal string. ``$`` is Nim's general way of
## spelling `toString`:idx:.
template dollarImpl(x: uint | uint64, result: var string) =
type destTyp = typeof(x)
if x == 0:
result = "0"
else:
result = newString(60)
var i = 0
var n = x
while n != 0:
let nn = n div destTyp(10)
result[i] = char(n - destTyp(10) * nn + ord('0'))
inc i
n = nn
result.setLen i
let half = i div 2
# Reverse
for t in 0 .. half-1: swap(result[t], result[i-t-1])
when defined(js):
import std/private/since
since (1, 3):
@@ -10,34 +30,25 @@ when defined(js):
## Caveat: currently implemented as $(cast[int](x)), tied to current
## semantics of js' Number type.
# for c, see strmantle.`$`
$(cast[int](x))
when nimvm:
dollarImpl(x, result)
else:
result = $(int(x))
proc `$`*(x: uint64): string =
## Compatibility note:
## the results may change in future releases if/when js target implements
## 64bit ints.
# pending https://github.com/nim-lang/RFCs/issues/187
$(cast[int](x))
when nimvm:
dollarImpl(x, result)
else:
result = $(cast[int](x))
else:
proc `$`*(x: uint64): string {.noSideEffect, raises: [].} =
## The stringify operator for an unsigned integer argument. Returns `x`
## converted to a decimal string.
if x == 0:
result = "0"
else:
result = newString(60)
var i = 0
var n = x
while n != 0:
let nn = n div 10'u64
result[i] = char(n - 10'u64 * nn + ord('0'))
inc i
n = nn
result.setLen i
let half = i div 2
# Reverse
for t in 0 .. half-1: swap(result[t], result[i-t-1])
dollarImpl(x, result)
proc `$`*(x: int64): string {.magic: "Int64ToStr", noSideEffect.}
## The stringify operator for an integer argument. Returns `x`

View File

@@ -101,6 +101,31 @@ block: # #14350, #16674, #16686 for JS
doAssert nil1 == cstring("")
doAssert nil2 == cstring("")
block:
block:
let x = -1'i8
let y = uint32(x)
doAssert $y == "4294967295"
block:
let x = -1'i16
let y = uint32(x)
doAssert $y == "4294967295"
block:
let x = -1'i32
let y = uint32(x)
doAssert $y == "4294967295"
block:
let x = 4294967295'u32
doAssert $x == "4294967295"
block:
doAssert $(4294967295'u32) == "4294967295"
proc main()=
block:
@@ -124,5 +149,8 @@ proc main()=
doAssert $(0) == "0"
doAssert $uint32.high == "4294967295"
static: main()
main()