summary refs log tree commit diff stats
path: root/lib/std/private
diff options
context:
space:
mode:
authorTimothee Cour <timothee.cour2@gmail.com>2021-08-19 02:33:52 -0700
committerGitHub <noreply@github.com>2021-08-19 11:33:52 +0200
commit394f4ac7bb92fe5aaf902495c6b43b3451667602 (patch)
tree8957f2337957a2c28d152490d07be106b1dd2994 /lib/std/private
parent7b58dc2de0f606b757a558dfdda9d930ae63f41a (diff)
downloadNim-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.nim68
-rw-r--r--lib/std/private/miscdollars.nim9
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 ")"