diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2016-02-26 14:49:07 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2016-02-26 14:49:07 +0100 |
commit | 4b3f164368bbf93b56187633a75bce999e6514c3 (patch) | |
tree | 176b3cd01d0e545f3c66162dde1697151828ccde | |
parent | 696ddbd93b4c16f27d78f608bfd5eaf157d2fcf4 (diff) | |
parent | cce64c335722bbf6bda39a9d8ca74154e0a3ad4c (diff) | |
download | Nim-4b3f164368bbf93b56187633a75bce999e6514c3.tar.gz |
Merge branch 'devel' of github.com:nim-lang/Nim into devel
-rw-r--r-- | compiler/installer.ini | 1 | ||||
-rw-r--r-- | compiler/semmagic.nim | 4 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 2 | ||||
-rw-r--r-- | lib/pure/collections/queues.nim | 2 | ||||
-rw-r--r-- | lib/pure/coro.nim | 2 | ||||
-rw-r--r-- | lib/pure/httpclient.nim | 15 | ||||
-rw-r--r-- | lib/pure/json.nim | 79 | ||||
-rw-r--r-- | lib/windows/winlean.nim | 3 | ||||
-rw-r--r-- | tests/closure/tclosure4.nim | 8 | ||||
-rw-r--r-- | tests/parallel/tarray_of_channels.nim | 2 | ||||
-rw-r--r-- | tests/parallel/tgc_unsafe.nim | 2 | ||||
-rw-r--r-- | tests/parallel/tgc_unsafe2.nim | 2 | ||||
-rw-r--r-- | tests/stdlib/tmitems.nim | 4 | ||||
-rw-r--r-- | tests/threads/threadex.nim | 2 | ||||
-rw-r--r-- | tests/threads/ttryrecv.nim | 4 | ||||
-rw-r--r-- | web/news.txt | 6 |
16 files changed, 70 insertions, 68 deletions
diff --git a/compiler/installer.ini b/compiler/installer.ini index 95c07e003..12d9baf82 100644 --- a/compiler/installer.ini +++ b/compiler/installer.ini @@ -104,6 +104,7 @@ Files: "lib/pure/concurrency/*.cfg" Files: "lib/impure/*.nim" Files: "lib/impure/nre/private/*.nim" Files: "lib/wrappers/*.nim" +Files: "lib/arch/*.nim" Files: "lib/wrappers/readline/*.nim" Files: "lib/wrappers/linenoise/*.nim" diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index f98ff0266..1a70e4a12 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -178,10 +178,6 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, result.typ = n[1].typ of mDotDot: result = n - # disallow negative indexing for now: - if not c.p.bracketExpr.isNil: - if isNegative(n.sons[1]) or (n.len > 2 and isNegative(n.sons[2])): - localError(n.info, "use '^' instead of '-'; negative indexing is obsolete") of mRoof: let bracketExpr = if n.len == 3: n.sons[2] else: c.p.bracketExpr if bracketExpr.isNil: diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 20b60a88d..a7f28feec 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -60,7 +60,7 @@ proc searchInstTypes*(key: PType): PType = if inst.id == key.id: return inst if inst.sons.len < key.sons.len: # XXX: This happens for prematurely cached - # types such as TChannel[empty]. Why? + # types such as Channel[empty]. Why? # See the notes for PActor in handleGenericInvocation return block matchType: diff --git a/lib/pure/collections/queues.nim b/lib/pure/collections/queues.nim index c35a2dc29..b9bf33bff 100644 --- a/lib/pure/collections/queues.nim +++ b/lib/pure/collections/queues.nim @@ -9,7 +9,7 @@ ## Implementation of a `queue`:idx:. The underlying implementation uses a ``seq``. ## Note: For inter thread communication use -## a `TChannel <channels.html>`_ instead. +## a `Channel <channels.html>`_ instead. import math diff --git a/lib/pure/coro.nim b/lib/pure/coro.nim index c5724f26f..2a81b7317 100644 --- a/lib/pure/coro.nim +++ b/lib/pure/coro.nim @@ -7,7 +7,7 @@ # distribution, for details about the copyright. # -when not defined(nimCoroutines): +when not defined(nimCoroutines) and not defined(nimdoc): {.error: "Coroutines require -d:nimCoroutines".} import os, times diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 1b91132db..603763386 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -455,14 +455,15 @@ proc redirection(status: string): bool = if status.startsWith(i): return true -proc getNewLocation(lastUrl: string, headers: StringTableRef): string = +proc getNewLocation(lastURL: string, headers: StringTableRef): string = result = headers.getOrDefault"Location" if result == "": httpError("location header expected") # Relative URLs. (Not part of the spec, but soon will be.) let r = parseUri(result) if r.hostname == "" and r.path != "": - let origParsed = parseUri(lastUrl) - result = origParsed.hostname & "/" & r.path + var parsed = parseUri(lastURL) + parsed.path = r.path + result = $parsed proc get*(url: string, extraHeaders = "", maxRedirects = 5, sslContext: SSLContext = defaultSSLContext, @@ -481,7 +482,7 @@ proc get*(url: string, extraHeaders = "", maxRedirects = 5, let redirectTo = getNewLocation(lastURL, result.headers) result = request(redirectTo, httpGET, extraHeaders, "", sslContext, timeout, userAgent, proxy) - lastUrl = redirectTo + lastURL = redirectTo proc getContent*(url: string, extraHeaders = "", maxRedirects = 5, sslContext: SSLContext = defaultSSLContext, @@ -528,14 +529,14 @@ proc post*(url: string, extraHeaders = "", body = "", result = request(url, httpPOST, xh, xb, sslContext, timeout, userAgent, proxy) - var lastUrl = "" + var lastURL = url for i in 1..maxRedirects: if result.status.redirection(): let redirectTo = getNewLocation(lastURL, result.headers) var meth = if result.status != "307": httpGet else: httpPost result = request(redirectTo, meth, xh, xb, sslContext, timeout, userAgent, proxy) - lastUrl = redirectTo + lastURL = redirectTo proc postContent*(url: string, extraHeaders = "", body = "", maxRedirects = 5, @@ -827,7 +828,7 @@ proc get*(client: AsyncHttpClient, url: string): Future[Response] {.async.} = if result.status.redirection(): let redirectTo = getNewLocation(lastURL, result.headers) result = await client.request(redirectTo, httpGET) - lastUrl = redirectTo + lastURL = redirectTo proc post*(client: AsyncHttpClient, url: string, body = "", multipart: MultipartData = nil): Future[Response] {.async.} = ## Connects to the hostname specified by the URL and performs a POST request. diff --git a/lib/pure/json.nim b/lib/pure/json.nim index f672a0c1b..3565e2feb 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -51,7 +51,7 @@ ## ] import - hashes, strutils, lexbase, streams, unicode, macros + hashes, tables, strutils, lexbase, streams, unicode, macros type JsonEventKind* = enum ## enumeration of all events that may occur when parsing @@ -567,7 +567,7 @@ type of JNull: nil of JObject: - fields*: seq[tuple[key: string, val: JsonNode]] + fields*: Table[string, JsonNode] of JArray: elems*: seq[JsonNode] @@ -617,7 +617,7 @@ proc newJObject*(): JsonNode = ## Creates a new `JObject JsonNode` new(result) result.kind = JObject - result.fields = @[] + result.fields = initTable[string, JsonNode](4) proc newJArray*(): JsonNode = ## Creates a new `JArray JsonNode` @@ -657,8 +657,8 @@ proc getBVal*(n: JsonNode, default: bool = false): bool = else: return n.bval proc getFields*(n: JsonNode, - default: seq[tuple[key: string, val: JsonNode]] = @[]): - seq[tuple[key: string, val: JsonNode]] = + default = initTable[string, JsonNode](4)): + Table[string, JsonNode] = ## Retrieves the key, value pairs of a `JObject JsonNode`. ## ## Returns ``default`` if ``n`` is not a ``JObject``, or if ``n`` is nil. @@ -700,8 +700,8 @@ proc `%`*(keyVals: openArray[tuple[key: string, val: JsonNode]]): JsonNode = ## Generic constructor for JSON data. Creates a new `JObject JsonNode` new(result) result.kind = JObject - newSeq(result.fields, keyVals.len) - for i, p in pairs(keyVals): result.fields[i] = p + result.fields = initTable[string, JsonNode](4) + for key, val in items(keyVals): result.fields[key] = val proc `%`*(elements: openArray[JsonNode]): JsonNode = ## Generic constructor for JSON data. Creates a new `JArray JsonNode` @@ -761,7 +761,9 @@ proc `==`* (a,b: JsonNode): bool = of JObject: a.fields == b.fields -proc hash* (n:JsonNode): Hash = +proc hash*(n: Table[string, JsonNode]): Hash {.noSideEffect.} + +proc hash*(n: JsonNode): Hash = ## Compute the hash for a JSON node case n.kind of JArray: @@ -779,6 +781,11 @@ proc hash* (n:JsonNode): Hash = of JNull: result = hash(0) +proc hash*(n: Table[string, JsonNode]): Hash = + for key, val in n: + result = result !& hash(key) !& hash(val) + result = !$result + proc len*(n: JsonNode): int = ## If `n` is a `JArray`, it returns the number of elements. ## If `n` is a `JObject`, it returns the number of pairs. @@ -793,10 +800,7 @@ proc `[]`*(node: JsonNode, name: string): JsonNode {.inline.} = ## If the value at `name` does not exist, returns nil assert(not isNil(node)) assert(node.kind == JObject) - for key, item in items(node.fields): - if key == name: - return item - return nil + result = node.fields.getOrDefault(name) proc `[]`*(node: JsonNode, index: int): JsonNode {.inline.} = ## Gets the node at `index` in an Array. Result is undefined if `index` @@ -808,8 +812,7 @@ proc `[]`*(node: JsonNode, index: int): JsonNode {.inline.} = proc hasKey*(node: JsonNode, key: string): bool = ## Checks if `key` exists in `node`. assert(node.kind == JObject) - for k, item in items(node.fields): - if k == key: return true + result = node.fields.hasKey(key) proc existsKey*(node: JsonNode, key: string): bool {.deprecated.} = node.hasKey(key) ## Deprecated for `hasKey` @@ -820,20 +823,14 @@ proc add*(father, child: JsonNode) = father.elems.add(child) proc add*(obj: JsonNode, key: string, val: JsonNode) = - ## Adds ``(key, val)`` pair to the JObject node `obj`. For speed - ## reasons no check for duplicate keys is performed! - ## But ``[]=`` performs the check. + ## Sets a field from a `JObject`. assert obj.kind == JObject - obj.fields.add((key, val)) + obj.fields[key] = val proc `[]=`*(obj: JsonNode, key: string, val: JsonNode) {.inline.} = - ## Sets a field from a `JObject`. Performs a check for duplicate keys. + ## Sets a field from a `JObject`. assert(obj.kind == JObject) - for i in 0..obj.fields.len-1: - if obj.fields[i].key == key: - obj.fields[i].val = val - return - obj.fields.add((key, val)) + obj.fields[key] = val proc `{}`*(node: JsonNode, keys: varargs[string]): JsonNode = ## Traverses the node and gets the given value. If any of the @@ -856,13 +853,11 @@ proc `{}=`*(node: JsonNode, keys: varargs[string], value: JsonNode) = node[keys[keys.len-1]] = value proc delete*(obj: JsonNode, key: string) = - ## Deletes ``obj[key]`` preserving the order of the other (key, value)-pairs. + ## Deletes ``obj[key]``. assert(obj.kind == JObject) - for i in 0..obj.fields.len-1: - if obj.fields[i].key == key: - obj.fields.delete(i) - return - raise newException(IndexError, "key not in object") + if not obj.fields.hasKey(key): + raise newException(IndexError, "key not in object") + obj.fields.del(key) proc copy*(p: JsonNode): JsonNode = ## Performs a deep copy of `a`. @@ -879,8 +874,8 @@ proc copy*(p: JsonNode): JsonNode = result = newJNull() of JObject: result = newJObject() - for key, field in items(p.fields): - result.fields.add((key, copy(field))) + for key, val in pairs(p.fields): + result.fields[key] = copy(val) of JArray: result = newJArray() for i in items(p.elems): @@ -924,15 +919,17 @@ proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true, if node.fields.len > 0: result.add("{") result.nl(ml) # New line - for i in 0..len(node.fields)-1: + var i = 0 + for key, val in pairs(node.fields): if i > 0: result.add(", ") result.nl(ml) # New Line + inc i # Need to indent more than { result.indent(newIndent(currIndent, indent, ml)) - result.add(escapeJson(node.fields[i].key)) + result.add(escapeJson(key)) result.add(": ") - toPretty(result, node.fields[i].val, indent, ml, false, + toPretty(result, val, indent, ml, false, newIndent(currIndent, indent, ml)) result.nl(ml) result.indent(currIndent) # indent the same as { @@ -994,7 +991,7 @@ proc toUgly*(result: var string, node: JsonNode) = result.add "]" of JObject: result.add "{" - for key, value in items(node.fields): + for key, value in pairs(node.fields): if comma: result.add "," else: comma = true result.add key.escapeJson() @@ -1033,15 +1030,15 @@ iterator mitems*(node: var JsonNode): var JsonNode = iterator pairs*(node: JsonNode): tuple[key: string, val: JsonNode] = ## Iterator for the child elements of `node`. `node` has to be a JObject. assert node.kind == JObject - for key, val in items(node.fields): + for key, val in pairs(node.fields): yield (key, val) -iterator mpairs*(node: var JsonNode): var tuple[key: string, val: JsonNode] = +iterator mpairs*(node: var JsonNode): tuple[key: string, val: var JsonNode] = ## Iterator for the child elements of `node`. `node` has to be a JObject. - ## Items can be modified + ## Values can be modified assert node.kind == JObject - for keyVal in mitems(node.fields): - yield keyVal + for key, val in mpairs(node.fields): + yield (key, val) proc eat(p: var JsonParser, tok: TokKind) = if p.tok == tok: discard getTok(p) diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index d00964a6d..9224c1ebd 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -14,6 +14,9 @@ import dynlib +when defined(vcc): + {.passC: "-DWIN32_LEAN_AND_MEAN".} + const useWinUnicode* = not defined(useWinAnsi) diff --git a/tests/closure/tclosure4.nim b/tests/closure/tclosure4.nim index 10c7cac54..69c076cd5 100644 --- a/tests/closure/tclosure4.nim +++ b/tests/closure/tclosure4.nim @@ -1,13 +1,13 @@ import json, tables, sequtils -proc run(json_params: TTable) = +proc run(json_params: Table) = let json_elems = json_params["files"].elems # These fail compilation. - var files = map(json_elems, proc (x: PJsonNode): string = x.str) - #var files = json_elems.map do (x: PJsonNode) -> string: x.str + var files = map(json_elems, proc (x: JsonNode): string = x.str) + #var files = json_elems.map do (x: JsonNode) -> string: x.str echo "Hey!" when isMainModule: let text = """{"files": ["a", "b", "c"]}""" - run(toTable((text.parseJson).fields)) + run((text.parseJson).fields) diff --git a/tests/parallel/tarray_of_channels.nim b/tests/parallel/tarray_of_channels.nim index 11b523401..90ae8369c 100644 --- a/tests/parallel/tarray_of_channels.nim +++ b/tests/parallel/tarray_of_channels.nim @@ -1,7 +1,7 @@ # bug #2257 import threadpool -type StringChannel = TChannel[string] +type StringChannel = Channel[string] var channels: array[1..3, StringChannel] type diff --git a/tests/parallel/tgc_unsafe.nim b/tests/parallel/tgc_unsafe.nim index 6548bbec8..a4d96cd73 100644 --- a/tests/parallel/tgc_unsafe.nim +++ b/tests/parallel/tgc_unsafe.nim @@ -6,7 +6,7 @@ discard """ # bug #2257 import threadpool -type StringChannel = TChannel[string] +type StringChannel = Channel[string] var channels: array[1..3, StringChannel] type diff --git a/tests/parallel/tgc_unsafe2.nim b/tests/parallel/tgc_unsafe2.nim index ec4605fe9..4a5f36f6d 100644 --- a/tests/parallel/tgc_unsafe2.nim +++ b/tests/parallel/tgc_unsafe2.nim @@ -9,7 +9,7 @@ tgc_unsafe2.nim(28, 5) Error: 'consumer' is not GC-safe as it calls 'track' import threadpool -type StringChannel = TChannel[string] +type StringChannel = Channel[string] var channels: array[1..3, StringChannel] type diff --git a/tests/stdlib/tmitems.nim b/tests/stdlib/tmitems.nim index 27ff344e5..c713d91a4 100644 --- a/tests/stdlib/tmitems.nim +++ b/tests/stdlib/tmitems.nim @@ -11,7 +11,7 @@ fpqeew [11, 12, 13] [11, 12, 13] [11, 12, 13] -{"key1":11,"key2":12,"key3":13} +11 12 13 [11,12,13] <Students> <Student Name="Aprilfoo" /> @@ -115,7 +115,7 @@ block: var j = parseJson """{"key1": 1, "key2": 2, "key3": 3}""" for key,val in j.pairs: val.num += 10 - echo j + echo j["key1"], " ", j["key2"], " ", j["key3"] block: var j = parseJson """[1, 2, 3]""" diff --git a/tests/threads/threadex.nim b/tests/threads/threadex.nim index 00d0992a5..442e80189 100644 --- a/tests/threads/threadex.nim +++ b/tests/threads/threadex.nim @@ -12,7 +12,7 @@ type var producer, consumer: Thread[void] - chan: TChannel[TMsg] + chan: Channel[TMsg] printedLines = 0 proc consume() {.thread.} = diff --git a/tests/threads/ttryrecv.nim b/tests/threads/ttryrecv.nim index fc1f21321..be79fadae 100644 --- a/tests/threads/ttryrecv.nim +++ b/tests/threads/ttryrecv.nim @@ -7,7 +7,7 @@ discard """ from math import random from os import sleep -type PComm = ptr TChannel[int] +type PComm = ptr Channel[int] proc doAction(outC: PComm) {.thread.} = for i in 0.. <5: @@ -16,7 +16,7 @@ proc doAction(outC: PComm) {.thread.} = var thr: Thread[PComm] - chan: TChannel[int] + chan: Channel[int] open(chan) createThread[PComm](thr, doAction, addr(chan)) diff --git a/web/news.txt b/web/news.txt index d854347a5..027844794 100644 --- a/web/news.txt +++ b/web/news.txt @@ -10,6 +10,11 @@ Changes affecting backwards compatibility - ``--out`` and ``--nimcache`` command line arguments are now relative to current directory. Previously they were relative to project directory. +- The json module now stores the name/value pairs in objects internally as a + hash table of type ``fields*: Table[string, JsonNode]`` instead of a + sequence. This means that order is no longer preserved. When using the + ``table.mpairs`` iterator only the returned values can be modified, no + longer the keys. Library Additions ----------------- @@ -24,7 +29,6 @@ Compiler Additions handling (no ``throw`` or ``try``/``catch`` generated) when compiling to C++ code - 2016-01-27 Nim in Action is now available! ========================================== |