Skip to content

Commit

Permalink
fix nim-lang#15413: Json now supports numbers in int64.high+1 .. uint…
Browse files Browse the repository at this point in the history
…64.high
  • Loading branch information
timotheecour committed Oct 19, 2020
1 parent f20e485 commit 081c607
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 2 deletions.
31 changes: 29 additions & 2 deletions lib/pure/json.nim
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,8 @@ type
JFloat,
JString,
JObject,
JArray
JArray,
JUInt

JsonNode* = ref JsonNodeObj ## JSON node
JsonNodeObj* {.acyclic.} = object
Expand All @@ -182,6 +183,8 @@ type
str*: string
of JInt:
num*: BiggestInt
of JUInt:
unum*: BiggestUInt
of JFloat:
fnum*: float
of JBool:
Expand All @@ -205,6 +208,10 @@ proc newJInt*(n: BiggestInt): JsonNode =
## Creates a new `JInt JsonNode`.
result = JsonNode(kind: JInt, num: n)

proc newJUInt*(n: BiggestUInt): JsonNode =
## Creates a new `JUInt JsonNode`.
result = JsonNode(kind: JUInt, unum: n)

proc newJFloat*(n: float): JsonNode =
## Creates a new `JFloat JsonNode`.
result = JsonNode(kind: JFloat, fnum: n)
Expand Down Expand Up @@ -419,6 +426,8 @@ proc `==`*(a, b: JsonNode): bool =
result = a.str == b.str
of JInt:
result = a.num == b.num
of JUInt:
result = a.unum == b.unum
of JFloat:
result = a.fnum == b.fnum
of JBool:
Expand Down Expand Up @@ -447,6 +456,8 @@ proc hash*(n: JsonNode): Hash =
result = hash(n.fields)
of JInt:
result = hash(n.num)
of JUInt:
result = hash(n.unum)
of JFloat:
result = hash(n.fnum)
of JBool:
Expand Down Expand Up @@ -564,6 +575,8 @@ proc copy*(p: JsonNode): JsonNode =
result = newJString(p.str)
of JInt:
result = newJInt(p.num)
of JUInt:
result = newJUInt(p.unum)
of JFloat:
result = newJFloat(p.fnum)
of JBool:
Expand Down Expand Up @@ -657,6 +670,11 @@ proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
if lstArr: result.indent(currIndent)
when defined(js): result.add($node.num)
else: result.addInt(node.num)
of JUInt:
if lstArr: result.indent(currIndent)
when defined(js): result.add($node.unum)
else:
result.addInt(node.unum)
of JFloat:
if lstArr: result.indent(currIndent)
# Fixme: implement new system.add ops for the JS target
Expand Down Expand Up @@ -738,6 +756,9 @@ proc toUgly*(result: var string, node: JsonNode) =
of JInt:
when defined(js): result.add($node.num)
else: result.addInt(node.num)
of JUInt:
when defined(js): result.add($node.unum)
else: result.addInt(node.unum)
of JFloat:
when defined(js): result.add($node.fnum)
else: result.addFloat(node.fnum)
Expand Down Expand Up @@ -792,7 +813,11 @@ proc parseJson(p: var JsonParser): JsonNode =
p.a = ""
discard getTok(p)
of tkInt:
result = newJInt(parseBiggestInt(p.a))
try:
result = newJInt(parseBiggestInt(p.a))
except ValueError:
# this can still raise for numbers outside of 64bit range
result = newJUInt(parseBiggestUInt(p.a))
discard getTok(p)
of tkFloat:
result = newJFloat(parseFloat(p.a))
Expand Down Expand Up @@ -921,6 +946,8 @@ when defined(js):
asm "}}"
of JInt:
result = newJInt(cast[int](x))
of JUInt:
result = newJUInt(cast[uint](x))
of JFloat:
result = newJFloat(cast[float](x))
of JString:
Expand Down
3 changes: 3 additions & 0 deletions lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2402,6 +2402,9 @@ when defined(js) or defined(nimscript):
proc addInt*(result: var string; x: int64) =
result.add $x

proc addInt*(result: var string; x: uint64) =
addInt(result, cast[int64](x)) # checkme

proc addFloat*(result: var string; x: float) =
result.add $x

Expand Down
17 changes: 17 additions & 0 deletions lib/system/strmantle.nim
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,23 @@ proc addInt*(result: var string; x: int64) =
for j in 0..i div 2 - 1:
swap(result[base+j], result[base+i-j-1])

proc addInt*(result: var string; x: uint64) =
# PRTEMP: TODO: add tests
let base = result.len
setLen(result, base + sizeof(x)*4)
var i = 0
var y = x
while true:
var d = y div 10
result[base+i] = chr(abs(int(y - d*10)) + ord('0'))
inc(i)
y = d
if y == 0: break
setLen(result, base+i)
# mirror the string:
for j in 0..i div 2 - 1:
swap(result[base+j], result[base+i-j-1])

proc nimIntToStr(x: int): string {.compilerRtl.} =
result = newStringOfCap(sizeof(x)*4)
result.addInt x
Expand Down

0 comments on commit 081c607

Please sign in to comment.