Merge branch 'devel' of github.com:nim-lang/Nim into devel
This commit is contained in:
commit
4b76d9846b
7 changed files with 88 additions and 20 deletions
|
|
@ -115,7 +115,7 @@ proc createObj*(owner: PSym, info: TLineInfo): PType =
|
||||||
incl result.flags, tfFinal
|
incl result.flags, tfFinal
|
||||||
result.n = newNodeI(nkRecList, info)
|
result.n = newNodeI(nkRecList, info)
|
||||||
when true:
|
when true:
|
||||||
let s = newSym(skType, getIdent("Env_" & info.toFilename & "_" & $info.line),
|
let s = newSym(skType, getIdent("Env_" & info.toFilename),
|
||||||
owner, info)
|
owner, info)
|
||||||
incl s.flags, sfAnon
|
incl s.flags, sfAnon
|
||||||
s.typ = result
|
s.typ = result
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@ compilation fails. This exit code tells ``git bisect`` to skip the
|
||||||
current commit.::
|
current commit.::
|
||||||
|
|
||||||
git bisect start bad-commit good-commit
|
git bisect start bad-commit good-commit
|
||||||
git bisect ./koch -r c test-source.nim
|
git bisect run ./koch temp -r c test-source.nim
|
||||||
|
|
||||||
The compiler's architecture
|
The compiler's architecture
|
||||||
===========================
|
===========================
|
||||||
|
|
|
||||||
|
|
@ -785,7 +785,7 @@ proc sort*[A, B](t: OrderedTableRef[A, B],
|
||||||
t[].sort(cmp)
|
t[].sort(cmp)
|
||||||
|
|
||||||
proc del*[A, B](t: var OrderedTable[A, B], key: A) =
|
proc del*[A, B](t: var OrderedTable[A, B], key: A) =
|
||||||
## deletes `key` from ordered hash table `t`. O(n) comlexity.
|
## deletes `key` from ordered hash table `t`. O(n) complexity.
|
||||||
var n: OrderedKeyValuePairSeq[A, B]
|
var n: OrderedKeyValuePairSeq[A, B]
|
||||||
newSeq(n, len(t.data))
|
newSeq(n, len(t.data))
|
||||||
var h = t.first
|
var h = t.first
|
||||||
|
|
@ -804,7 +804,7 @@ proc del*[A, B](t: var OrderedTable[A, B], key: A) =
|
||||||
h = nxt
|
h = nxt
|
||||||
|
|
||||||
proc del*[A, B](t: var OrderedTableRef[A, B], key: A) =
|
proc del*[A, B](t: var OrderedTableRef[A, B], key: A) =
|
||||||
## deletes `key` from ordered hash table `t`. O(n) comlexity.
|
## deletes `key` from ordered hash table `t`. O(n) complexity.
|
||||||
t[].del(key)
|
t[].del(key)
|
||||||
|
|
||||||
# ------------------------------ count tables -------------------------------
|
# ------------------------------ count tables -------------------------------
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ proc setCookie*(key, value: string, domain = "", path = "",
|
||||||
if domain != "": result.add("; Domain=" & domain)
|
if domain != "": result.add("; Domain=" & domain)
|
||||||
if path != "": result.add("; Path=" & path)
|
if path != "": result.add("; Path=" & path)
|
||||||
if expires != "": result.add("; Expires=" & expires)
|
if expires != "": result.add("; Expires=" & expires)
|
||||||
if secure: result.add("; secure")
|
if secure: result.add("; Secure")
|
||||||
if httpOnly: result.add("; HttpOnly")
|
if httpOnly: result.add("; HttpOnly")
|
||||||
|
|
||||||
proc setCookie*(key, value: string, expires: TimeInfo,
|
proc setCookie*(key, value: string, expires: TimeInfo,
|
||||||
|
|
@ -50,7 +50,7 @@ proc setCookie*(key, value: string, expires: TimeInfo,
|
||||||
##
|
##
|
||||||
## **Note:** UTC is assumed as the timezone for ``expires``.
|
## **Note:** UTC is assumed as the timezone for ``expires``.
|
||||||
return setCookie(key, value, domain, path,
|
return setCookie(key, value, domain, path,
|
||||||
format(expires, "ddd',' dd MMM yyyy HH:mm:ss 'UTC'"),
|
format(expires, "ddd',' dd MMM yyyy HH:mm:ss 'GMT'"),
|
||||||
noname, secure, httpOnly)
|
noname, secure, httpOnly)
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
|
|
|
||||||
|
|
@ -1502,7 +1502,7 @@ proc processObjField(field, jsonNode: NimNode): seq[NimNode] =
|
||||||
doAssert result.len > 0
|
doAssert result.len > 0
|
||||||
|
|
||||||
proc processType(typeName: NimNode, obj: NimNode,
|
proc processType(typeName: NimNode, obj: NimNode,
|
||||||
jsonNode: NimNode): NimNode {.compileTime.} =
|
jsonNode: NimNode, isRef: bool): NimNode {.compileTime.} =
|
||||||
## Process a type such as ``Sym "float"`` or ``ObjectTy ...``.
|
## Process a type such as ``Sym "float"`` or ``ObjectTy ...``.
|
||||||
##
|
##
|
||||||
## Sample ``ObjectTy``:
|
## Sample ``ObjectTy``:
|
||||||
|
|
@ -1524,6 +1524,20 @@ proc processType(typeName: NimNode, obj: NimNode,
|
||||||
for field in obj[2]:
|
for field in obj[2]:
|
||||||
let nodes = processObjField(field, jsonNode)
|
let nodes = processObjField(field, jsonNode)
|
||||||
result.add(nodes)
|
result.add(nodes)
|
||||||
|
|
||||||
|
# Object might be null. So we need to check for that.
|
||||||
|
if isRef:
|
||||||
|
result = quote do:
|
||||||
|
verifyJsonKind(`jsonNode`, {JObject, JNull}, astToStr(`jsonNode`))
|
||||||
|
if `jsonNode`.kind == JNull:
|
||||||
|
nil
|
||||||
|
else:
|
||||||
|
`result`
|
||||||
|
else:
|
||||||
|
result = quote do:
|
||||||
|
verifyJsonKind(`jsonNode`, {JObject}, astToStr(`jsonNode`));
|
||||||
|
`result`
|
||||||
|
|
||||||
of nnkEnumTy:
|
of nnkEnumTy:
|
||||||
let instType = toIdentNode(getTypeInst(typeName))
|
let instType = toIdentNode(getTypeInst(typeName))
|
||||||
let getEnumCall = createGetEnumCall(jsonNode, instType)
|
let getEnumCall = createGetEnumCall(jsonNode, instType)
|
||||||
|
|
@ -1536,8 +1550,8 @@ proc processType(typeName: NimNode, obj: NimNode,
|
||||||
of "float":
|
of "float":
|
||||||
result = quote do:
|
result = quote do:
|
||||||
(
|
(
|
||||||
verifyJsonKind(`jsonNode`, {JFloat}, astToStr(`jsonNode`));
|
verifyJsonKind(`jsonNode`, {JFloat, JInt}, astToStr(`jsonNode`));
|
||||||
`jsonNode`.fnum
|
if `jsonNode`.kind == JFloat: `jsonNode`.fnum else: `jsonNode`.num.float
|
||||||
)
|
)
|
||||||
of "string":
|
of "string":
|
||||||
result = quote do:
|
result = quote do:
|
||||||
|
|
@ -1551,6 +1565,12 @@ proc processType(typeName: NimNode, obj: NimNode,
|
||||||
verifyJsonKind(`jsonNode`, {JInt}, astToStr(`jsonNode`));
|
verifyJsonKind(`jsonNode`, {JInt}, astToStr(`jsonNode`));
|
||||||
`jsonNode`.num.int
|
`jsonNode`.num.int
|
||||||
)
|
)
|
||||||
|
of "biggestint":
|
||||||
|
result = quote do:
|
||||||
|
(
|
||||||
|
verifyJsonKind(`jsonNode`, {JInt}, astToStr(`jsonNode`));
|
||||||
|
`jsonNode`.num
|
||||||
|
)
|
||||||
of "bool":
|
of "bool":
|
||||||
result = quote do:
|
result = quote do:
|
||||||
(
|
(
|
||||||
|
|
@ -1585,7 +1605,7 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode =
|
||||||
typeName = typeName[0 .. ^12]
|
typeName = typeName[0 .. ^12]
|
||||||
|
|
||||||
let obj = getType(typeSym[1])
|
let obj = getType(typeSym[1])
|
||||||
result = processType(newIdentNode(typeName), obj, jsonNode)
|
result = processType(newIdentNode(typeName), obj, jsonNode, true)
|
||||||
of "seq":
|
of "seq":
|
||||||
let seqT = typeSym[1]
|
let seqT = typeSym[1]
|
||||||
let forLoopI = newIdentNode("i")
|
let forLoopI = newIdentNode("i")
|
||||||
|
|
@ -1605,17 +1625,21 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode =
|
||||||
else:
|
else:
|
||||||
# Generic type.
|
# Generic type.
|
||||||
let obj = getType(typeSym)
|
let obj = getType(typeSym)
|
||||||
result = processType(typeSym, obj, jsonNode)
|
result = processType(typeSym, obj, jsonNode, false)
|
||||||
of nnkSym:
|
of nnkSym:
|
||||||
let obj = getType(typeSym)
|
let obj = getType(typeSym)
|
||||||
result = processType(typeSym, obj, jsonNode)
|
if obj.kind == nnkBracketExpr:
|
||||||
|
# When `Sym "Foo"` turns out to be a `ref object`.
|
||||||
|
result = createConstructor(obj, jsonNode)
|
||||||
|
else:
|
||||||
|
result = processType(typeSym, obj, jsonNode, false)
|
||||||
else:
|
else:
|
||||||
doAssert false, "Unable to create constructor for: " & $typeSym.kind
|
doAssert false, "Unable to create constructor for: " & $typeSym.kind
|
||||||
|
|
||||||
doAssert(not result.isNil(), "Constructor not initialised.")
|
doAssert(not result.isNil(), "Constructor not initialised.")
|
||||||
|
|
||||||
proc postProcess(node: NimNode): NimNode
|
proc postProcess(node: NimNode): NimNode
|
||||||
proc postProcessValue(value: NimNode, depth=0): NimNode =
|
proc postProcessValue(value: NimNode): NimNode =
|
||||||
## Looks for object constructors and calls the ``postProcess`` procedure
|
## Looks for object constructors and calls the ``postProcess`` procedure
|
||||||
## on them. Otherwise it just returns the node as-is.
|
## on them. Otherwise it just returns the node as-is.
|
||||||
case value.kind
|
case value.kind
|
||||||
|
|
@ -1736,9 +1760,10 @@ macro to*(node: JsonNode, T: typedesc): untyped =
|
||||||
doAssert(($typeNode[0]).normalize == "typedesc")
|
doAssert(($typeNode[0]).normalize == "typedesc")
|
||||||
|
|
||||||
result = createConstructor(typeNode[1], node)
|
result = createConstructor(typeNode[1], node)
|
||||||
result = postProcess(result)
|
# TODO: Rename postProcessValue and move it (?)
|
||||||
|
result = postProcessValue(result)
|
||||||
|
|
||||||
#echo(toStrLit(result))
|
# echo(toStrLit(result))
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
import os
|
import os
|
||||||
|
|
|
||||||
|
|
@ -69,10 +69,9 @@ var
|
||||||
proc genOid*(): Oid =
|
proc genOid*(): Oid =
|
||||||
## generates a new OID.
|
## generates a new OID.
|
||||||
proc rand(): cint {.importc: "rand", header: "<stdlib.h>", nodecl.}
|
proc rand(): cint {.importc: "rand", header: "<stdlib.h>", nodecl.}
|
||||||
proc gettime(dummy: ptr cint): cint {.importc: "time", header: "<time.h>".}
|
|
||||||
proc srand(seed: cint) {.importc: "srand", header: "<stdlib.h>", nodecl.}
|
proc srand(seed: cint) {.importc: "srand", header: "<stdlib.h>", nodecl.}
|
||||||
|
|
||||||
var t = gettime(nil)
|
var t = getTime().int32
|
||||||
|
|
||||||
var i = int32(atomicInc(incr))
|
var i = int32(atomicInc(incr))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -159,11 +159,11 @@ when isMainModule:
|
||||||
name: string
|
name: string
|
||||||
age: int
|
age: int
|
||||||
|
|
||||||
Data = object
|
Data1 = object # TODO: Codegen bug when changed to ``Data``.
|
||||||
person: Person
|
person: Person
|
||||||
list: seq[int]
|
list: seq[int]
|
||||||
|
|
||||||
var data = to(jsonNode, Data)
|
var data = to(jsonNode, Data1)
|
||||||
doAssert data.person.name == "Nimmer"
|
doAssert data.person.name == "Nimmer"
|
||||||
doAssert data.person.age == 21
|
doAssert data.person.age == 21
|
||||||
doAssert data.list == @[1, 2, 3, 4]
|
doAssert data.list == @[1, 2, 3, 4]
|
||||||
|
|
@ -182,4 +182,48 @@ when isMainModule:
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = to(node, TestEnum)
|
var result = to(node, TestEnum)
|
||||||
doAssert result.field == Bar
|
doAssert result.field == Bar
|
||||||
|
|
||||||
|
# Test ref type in field.
|
||||||
|
block:
|
||||||
|
var jsonNode = parseJson("""
|
||||||
|
{
|
||||||
|
"person": {
|
||||||
|
"name": "Nimmer",
|
||||||
|
"age": 21
|
||||||
|
},
|
||||||
|
"list": [1, 2, 3, 4]
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
type
|
||||||
|
Person = ref object
|
||||||
|
name: string
|
||||||
|
age: int
|
||||||
|
|
||||||
|
Data = object
|
||||||
|
person: Person
|
||||||
|
list: seq[int]
|
||||||
|
|
||||||
|
var data = to(jsonNode, Data)
|
||||||
|
doAssert data.person.name == "Nimmer"
|
||||||
|
doAssert data.person.age == 21
|
||||||
|
doAssert data.list == @[1, 2, 3, 4]
|
||||||
|
|
||||||
|
jsonNode = parseJson("""
|
||||||
|
{
|
||||||
|
"person": null,
|
||||||
|
"list": [1, 2, 3, 4]
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
data = to(jsonNode, Data)
|
||||||
|
doAssert data.person.isNil
|
||||||
|
|
||||||
|
block:
|
||||||
|
type
|
||||||
|
FooBar = object
|
||||||
|
field: float
|
||||||
|
|
||||||
|
let x = parseJson("""{ "field": 5}""")
|
||||||
|
let data = to(x, FooBar)
|
||||||
|
doAssert data.field == 5.0
|
||||||
Loading…
Add table
Add a link
Reference in a new issue