From 96c97d41035cc4e0f109ac559452174cfef25a72 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Fri, 11 Apr 2014 21:41:45 +0100 Subject: JS: Fixes math and streams module and implements json. --- lib/pure/json.nim | 111 +++++++++++++++++++++++++++++++++++++++++---------- lib/pure/math.nim | 4 +- lib/pure/streams.nim | 80 +++++++++++++++++++------------------ 3 files changed, 134 insertions(+), 61 deletions(-) diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 7424bbae9..4250847e5 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -861,26 +861,97 @@ proc parseJson(p: var TJsonParser): PJsonNode = of tkError, tkCurlyRi, tkBracketRi, tkColon, tkComma, tkEof: raiseParseErr(p, "{") -proc parseJson*(s: PStream, filename: string): PJsonNode = - ## Parses from a stream `s` into a `PJsonNode`. `filename` is only needed - ## for nice error messages. - var p: TJsonParser - p.open(s, filename) - discard getTok(p) # read first token - result = p.parseJson() - p.close() - -proc parseJson*(buffer: string): PJsonNode = - ## Parses JSON from `buffer`. - result = parseJson(newStringStream(buffer), "input") - -proc parseFile*(filename: string): PJsonNode = - ## Parses `file` into a `PJsonNode`. - var stream = newFileStream(filename, fmRead) - if stream == nil: - raise newException(EIO, "cannot read from file: " & filename) - result = parseJson(stream, filename) - +when not defined(js): + proc parseJson*(s: PStream, filename: string): PJsonNode = + ## Parses from a stream `s` into a `PJsonNode`. `filename` is only needed + ## for nice error messages. + var p: TJsonParser + p.open(s, filename) + discard getTok(p) # read first token + result = p.parseJson() + p.close() + + proc parseJson*(buffer: string): PJsonNode = + ## Parses JSON from `buffer`. + result = parseJson(newStringStream(buffer), "input") + + proc parseFile*(filename: string): PJsonNode = + ## Parses `file` into a `PJsonNode`. + var stream = newFileStream(filename, fmRead) + if stream == nil: + raise newException(EIO, "cannot read from file: " & filename) + result = parseJson(stream, filename) +else: + from math import `mod` + type + TJSObject = object + proc parseNativeJson(x: cstring): TJSObject {.importc: "JSON.parse".} + + proc getVarType(x): TJsonNodeKind = + result = JNull + proc getProtoName(y): cstring + {.importc: "Object.prototype.toString.call".} + case $getProtoName(x) # TODO: Implicit returns fail here. + of "[object Array]": return JArray + of "[object Object]": return JObject + of "[object Number]": + if cast[float](x) mod 1.0 == 0: + return JInt + else: + return JFloat + of "[object Boolean]": return JBool + of "[object Null]": return JNull + of "[object String]": return JString + else: assert false + + proc len(x: TJSObject): int = + assert x.getVarType == JArray + asm """ + return `x`.length; + """ + + proc `[]`(x: TJSObject, y: string): TJSObject = + assert x.getVarType == JObject + asm """ + return `x`[`y`]; + """ + + proc `[]`(x: TJSObject, y: int): TJSObject = + assert x.getVarType == JArray + asm """ + return `x`[`y`]; + """ + + proc convertObject(x: TJSObject): PJsonNode = + case getVarType(x) + of JArray: + result = newJArray() + for i in 0 .. `_ module for a list of available TFileMode enums. - var f: TFile - if open(f, filename, mode): result = newFileStream(f) +when not defined(js): + + type + PFileStream* = ref TFileStream ## a stream that encapsulates a `TFile` + TFileStream* = object of TStream + f: TFile + + proc fsClose(s: PStream) = + if PFileStream(s).f != nil: + close(PFileStream(s).f) + PFileStream(s).f = nil + proc fsFlush(s: PStream) = flushFile(PFileStream(s).f) + proc fsAtEnd(s: PStream): bool = return endOfFile(PFileStream(s).f) + proc fsSetPosition(s: PStream, pos: int) = setFilePos(PFileStream(s).f, pos) + proc fsGetPosition(s: PStream): int = return int(getFilePos(PFileStream(s).f)) + + proc fsReadData(s: PStream, buffer: pointer, bufLen: int): int = + result = readBuffer(PFileStream(s).f, buffer, bufLen) + + proc fsWriteData(s: PStream, buffer: pointer, bufLen: int) = + if writeBuffer(PFileStream(s).f, buffer, bufLen) != bufLen: + raise newEIO("cannot write to stream") + + proc newFileStream*(f: TFile): PFileStream = + ## creates a new stream from the file `f`. + new(result) + result.f = f + result.closeImpl = fsClose + result.atEndImpl = fsAtEnd + result.setPositionImpl = fsSetPosition + result.getPositionImpl = fsGetPosition + result.readDataImpl = fsReadData + result.writeDataImpl = fsWriteData + result.flushImpl = fsFlush + + proc newFileStream*(filename: string, mode: TFileMode): PFileStream = + ## creates a new stream from the file named `filename` with the mode `mode`. + ## If the file cannot be opened, nil is returned. See the `system + ## `_ module for a list of available TFileMode enums. + var f: TFile + if open(f, filename, mode): result = newFileStream(f) when true: -- cgit 1.4.1-2-gfad0