diff options
author | flywind <43030857+xflywind@users.noreply.github.com> | 2021-02-18 13:13:52 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-18 20:13:52 +0100 |
commit | cd274a5ac90edec6edccb5b8772bd34b4d1cd993 (patch) | |
tree | 0ab3bf0d4b757c438f31532c4ac221946fb95790 | |
parent | 8fd1ed6dfe68c98bee7f69d26946df8003f930c5 (diff) | |
download | Nim-cd274a5ac90edec6edccb5b8772bd34b4d1cd993.tar.gz |
fix stringify unsigned integer in JS and JS VM (#17086)
* fix js unsigned integer * better
-rw-r--r-- | lib/system/dollars.nim | 47 | ||||
-rw-r--r-- | tests/system/tdollars.nim | 28 |
2 files changed, 57 insertions, 18 deletions
diff --git a/lib/system/dollars.nim b/lib/system/dollars.nim index 4c72c2901..238c59837 100644 --- a/lib/system/dollars.nim +++ b/lib/system/dollars.nim @@ -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` diff --git a/tests/system/tdollars.nim b/tests/system/tdollars.nim index 62f77c857..04595c93c 100644 --- a/tests/system/tdollars.nim +++ b/tests/system/tdollars.nim @@ -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() |