diff options
author | Timothee Cour <timothee.cour2@gmail.com> | 2021-08-19 02:33:52 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-19 11:33:52 +0200 |
commit | 394f4ac7bb92fe5aaf902495c6b43b3451667602 (patch) | |
tree | 8957f2337957a2c28d152490d07be106b1dd2994 /lib/std/private | |
parent | 7b58dc2de0f606b757a558dfdda9d930ae63f41a (diff) | |
download | Nim-394f4ac7bb92fe5aaf902495c6b43b3451667602.tar.gz |
improvements to `addInt` and `$` for integer types (#18592)
* improvements to $(SomeInteger) and addInt * remove mIntToStr, mInt64ToStr * improvements * fix tests/pragmas/tinjectstmt.nim; the diff is harmless, cgen code is identical with -d:danger or debug mode * rm tests/system/tstrmantle.nim * revert compiler/jsgen.nim for -d:nimVersion140
Diffstat (limited to 'lib/std/private')
-rw-r--r-- | lib/std/private/digitsutils.nim | 68 | ||||
-rw-r--r-- | lib/std/private/miscdollars.nim | 9 |
2 files changed, 57 insertions, 20 deletions
diff --git a/lib/std/private/digitsutils.nim b/lib/std/private/digitsutils.nim index 7aefc36bc..268a3ba7d 100644 --- a/lib/std/private/digitsutils.nim +++ b/lib/std/private/digitsutils.nim @@ -29,18 +29,34 @@ const # doAssert res == digits100 proc utoa2Digits*(buf: var openArray[char]; pos: int; digits: uint32) {.inline.} = - assert(digits <= 99) buf[pos] = digits100[2 * digits] buf[pos+1] = digits100[2 * digits + 1] #copyMem(buf, unsafeAddr(digits100[2 * digits]), 2 * sizeof((char))) proc trailingZeros2Digits*(digits: uint32): int32 {.inline.} = - assert(digits <= 99) return trailingZeros100[digits] -func addIntImpl*(result: var string, origin: uint64) = +when defined(js): + proc numToString(a: SomeInteger): cstring {.importjs: "((#) + \"\")".} + +func addChars[T](result: var string, x: T, start: int, n: int) {.inline.} = + let old = result.len + result.setLen old + n + template impl = + for i in 0..<n: result[old + i] = x[start + i] + when nimvm: impl + else: + when defined(js) or defined(nimscript): impl + else: + {.noSideEffect.}: + copyMem result[old].addr, x[start].unsafeAddr, n + +func addChars[T](result: var string, x: T) {.inline.} = + addChars(result, x, 0, x.len) + +func addIntImpl(result: var string, x: uint64) {.inline.} = var tmp {.noinit.}: array[24, char] - var num = origin + var num = x var next = tmp.len - 1 const nbatch = 100 @@ -60,17 +76,39 @@ func addIntImpl*(result: var string, origin: uint64) = tmp[next] = digits100[index + 1] tmp[next - 1] = digits100[index] dec next - let n = result.len - let length = tmp.len - next - result.setLen n + length - when nimvm: - for i in 0..<length: - result[n+i] = tmp[next+i] + addChars(result, tmp, next, tmp.len - next) + +func addInt*(result: var string, x: uint64) = + when nimvm: addIntImpl(result, x) else: - when defined(js) or defined(nimscript): - for i in 0..<length: - result[n+i] = tmp[next+i] + when not defined(js): addIntImpl(result, x) else: - {.noSideEffect.}: - copyMem result[n].addr, tmp[next].addr, length + addChars(result, numToString(x)) + +proc addInt*(result: var string; x: int64) = + ## Converts integer to its string representation and appends it to `result`. + runnableExamples: + var s = "foo" + s.addInt(45) + assert s == "foo45" + template impl = + var num: uint64 + if x < 0: + if x == low(int64): + num = uint64(x) + else: + num = uint64(-x) + let base = result.len + setLen(result, base + 1) + result[base] = '-' + else: + num = uint64(x) + addInt(result, num) + when nimvm: impl() + else: + when defined(js): + addChars(result, numToString(x)) + else: impl() +proc addInt*(result: var string; x: int) {.inline.} = + addInt(result, int64(x)) diff --git a/lib/std/private/miscdollars.nim b/lib/std/private/miscdollars.nim index a41cf1bc1..840fedf54 100644 --- a/lib/std/private/miscdollars.nim +++ b/lib/std/private/miscdollars.nim @@ -1,3 +1,5 @@ +from std/private/digitsutils import addInt + template toLocation*(result: var string, file: string | cstring, line: int, col: int) = ## avoids spurious allocations # Hopefully this can be re-used everywhere so that if a user needs to customize, @@ -5,11 +7,8 @@ template toLocation*(result: var string, file: string | cstring, line: int, col: result.add file if line > 0: result.add "(" - # simplify this after moving moving `include strmantle` above import assertions` - when declared(addInt): result.addInt line - else: result.add $line + addInt(result, line) if col > 0: result.add ", " - when declared(addInt): result.addInt col - else: result.add $col + addInt(result, col) result.add ")" |