JSON module now distinguishes between Integers and Floats.

This commit is contained in:
dom96 2011-02-13 00:45:15 +00:00
commit 8915df00e2

View file

@ -22,7 +22,8 @@ type
jsonError, ## an error ocurred during parsing jsonError, ## an error ocurred during parsing
jsonEof, ## end of file reached jsonEof, ## end of file reached
jsonString, ## a string literal jsonString, ## a string literal
jsonNumber, ## a number literal jsonInt, ## a integer literal
jsonFloat, ## a float literal
jsonTrue, ## the value ``true`` jsonTrue, ## the value ``true``
jsonFalse, ## the value ``false`` jsonFalse, ## the value ``false``
jsonNull, ## the value ``null`` jsonNull, ## the value ``null``
@ -35,7 +36,8 @@ type
tkError, tkError,
tkEof, tkEof,
tkString, tkString,
tkNumber, tkInt,
tkFloat,
tkTrue, tkTrue,
tkFalse, tkFalse,
tkNull, tkNull,
@ -89,7 +91,8 @@ const
"invalid token", "invalid token",
"EOF", "EOF",
"string literal", "string literal",
"number literal", "int literal",
"float literal",
"true", "true",
"false", "false",
"null", "null",
@ -110,14 +113,19 @@ proc close*(my: var TJsonParser) {.inline.} =
lexbase.close(my) lexbase.close(my)
proc str*(my: TJsonParser): string {.inline.} = proc str*(my: TJsonParser): string {.inline.} =
## returns the character data for the events: ``jsonNumber``, ## returns the character data for the events: ``jsonInt``, ``jsonFloat``,
## ``jsonString`` ## ``jsonString``
assert(my.kind in {jsonNumber, jsonString}) assert(my.kind in {jsonInt, jsonFloat, jsonString})
return my.a return my.a
proc number*(my: TJsonParser): float {.inline.} = proc getInt*(my: TJsonParser): biggestInt {.inline.} =
## returns the number for the event: ``jsonNumber`` ## returns the number for the event: ``jsonInt``
assert(my.kind == jsonNumber) assert(my.kind == jsonInt)
return parseInt(my.a)
proc getFloat*(my: TJsonParser): float {.inline.} =
## returns the number for the event: ``jsonFloat``
assert(my.kind == jsonFloat)
return parseFloat(my.a) return parseFloat(my.a)
proc kind*(my: TJsonParser): TJsonEventKind {.inline.} = proc kind*(my: TJsonParser): TJsonEventKind {.inline.} =
@ -318,7 +326,10 @@ proc getTok(my: var TJsonParser): TTokKind =
case my.buf[my.bufpos] case my.buf[my.bufpos]
of '-', '.', '0'..'9': of '-', '.', '0'..'9':
parseNumber(my) parseNumber(my)
result = tkNumber if {'.', 'e'} in my.a:
result = tkFloat
else:
result = tkInt
of '"': of '"':
result = parseString(my) result = parseString(my)
of '[': of '[':
@ -369,7 +380,7 @@ proc next*(my: var TJsonParser) =
of stateStart: of stateStart:
# tokens allowed? # tokens allowed?
case tk case tk
of tkString, tkNumber, tkTrue, tkFalse, tkNull: of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
my.state[i] = stateEof # expect EOF next! my.state[i] = stateEof # expect EOF next!
my.kind = TJsonEventKind(ord(tk)) my.kind = TJsonEventKind(ord(tk))
of tkBracketLe: of tkBracketLe:
@ -385,7 +396,7 @@ proc next*(my: var TJsonParser) =
my.err = errEofExpected my.err = errEofExpected
of stateObject: of stateObject:
case tk case tk
of tkString, tkNumber, tkTrue, tkFalse, tkNull: of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
my.state.add(stateExpectColon) my.state.add(stateExpectColon)
my.kind = TJsonEventKind(ord(tk)) my.kind = TJsonEventKind(ord(tk))
of tkBracketLe: of tkBracketLe:
@ -404,7 +415,7 @@ proc next*(my: var TJsonParser) =
my.err = errCurlyRiExpected my.err = errCurlyRiExpected
of stateArray: of stateArray:
case tk case tk
of tkString, tkNumber, tkTrue, tkFalse, tkNull: of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
my.state.add(stateExpectArrayComma) # expect value next! my.state.add(stateExpectArrayComma) # expect value next!
my.kind = TJsonEventKind(ord(tk)) my.kind = TJsonEventKind(ord(tk))
of tkBracketLe: of tkBracketLe:
@ -455,7 +466,7 @@ proc next*(my: var TJsonParser) =
my.err = errColonExpected my.err = errColonExpected
of stateExpectValue: of stateExpectValue:
case tk case tk
of tkString, tkNumber, tkTrue, tkFalse, tkNull: of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
my.state[i] = stateExpectObjectComma my.state[i] = stateExpectObjectComma
my.kind = TJsonEventKind(ord(tk)) my.kind = TJsonEventKind(ord(tk))
of tkBracketLe: of tkBracketLe:
@ -477,7 +488,8 @@ type
TJsonNodeKind* = enum ## possible JSON node types TJsonNodeKind* = enum ## possible JSON node types
JNull, JNull,
JBool, JBool,
JNumber, JInt,
JFloat,
JString, JString,
JObject, JObject,
JArray JArray
@ -487,8 +499,10 @@ type
case kind*: TJsonNodeKind case kind*: TJsonNodeKind
of JString: of JString:
str*: String str*: String
of JNumber: of JInt:
num*: Float num*: biggestInt
of JFloat:
fnum: Float
of JBool: of JBool:
bval*: Bool bval*: Bool
of JNull: of JNull:
@ -509,12 +523,18 @@ proc newJString*(s: String): PJsonNode =
result.kind = JString result.kind = JString
result.str = s result.str = s
proc newJNumber*(n: Float): PJsonNode = proc newJInt*(n: biggestInt): PJsonNode =
## Creates a new `JNumber PJsonNode`. ## Creates a new `JInt PJsonNode`.
new(result) new(result)
result.kind = JNumber result.kind = JInt
result.num = n result.num = n
proc newJFloat*(n: Float): PJsonNode =
## Creates a new `JFloat PJsonNode`.
new(result)
result.kind = JFloat
result.fnum = n
proc newJBool*(b: Bool): PJsonNode = proc newJBool*(b: Bool): PJsonNode =
## Creates a new `JBool PJsonNode`. ## Creates a new `JBool PJsonNode`.
new(result) new(result)
@ -641,9 +661,12 @@ proc toPretty(result: var string, node: PJsonNode, indent = 2, ml = True,
of JString: of JString:
if lstArr: result.indent(currIndent) if lstArr: result.indent(currIndent)
result.add(escapeJson(node.str)) result.add(escapeJson(node.str))
of JNumber: of JInt:
if lstArr: result.indent(currIndent) if lstArr: result.indent(currIndent)
result.add($node.num) result.add($node.num)
of JFloat:
if lstArr: result.indent(currIndent)
result.add($node.fnum)
of JBool: of JBool:
if lstArr: result.indent(currIndent) if lstArr: result.indent(currIndent)
result.add($node.bval) result.add($node.bval)
@ -687,8 +710,11 @@ proc parseJson(p: var TJsonParser): PJsonNode =
of tkString: of tkString:
result = newJString(p.a) result = newJString(p.a)
discard getTok(p) discard getTok(p)
of tkNumber: of tkInt:
result = newJNumber(parseFloat(p.a)) result = newJInt(parseInt(p.a))
discard getTok(p)
of tkFloat:
result = newJFloat(parseFloat(p.a))
discard getTok(p) discard getTok(p)
of tkTrue: of tkTrue:
result = newJBool(true) result = newJBool(true)
@ -757,7 +783,7 @@ when false:
Echo(x.errorMsg()) Echo(x.errorMsg())
break break
of jsonEof: break of jsonEof: break
of jsonString, jsonNumber: echo(x.str) of jsonString, jsonInt, jsonFloat: echo(x.str)
of jsonTrue: Echo("!TRUE") of jsonTrue: Echo("!TRUE")
of jsonFalse: Echo("!FALSE") of jsonFalse: Echo("!FALSE")
of jsonNull: Echo("!NULL") of jsonNull: Echo("!NULL")