summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2016-02-26 14:49:07 +0100
committerAndreas Rumpf <rumpf_a@web.de>2016-02-26 14:49:07 +0100
commit4b3f164368bbf93b56187633a75bce999e6514c3 (patch)
tree176b3cd01d0e545f3c66162dde1697151828ccde
parent696ddbd93b4c16f27d78f608bfd5eaf157d2fcf4 (diff)
parentcce64c335722bbf6bda39a9d8ca74154e0a3ad4c (diff)
downloadNim-4b3f164368bbf93b56187633a75bce999e6514c3.tar.gz
Merge branch 'devel' of github.com:nim-lang/Nim into devel
-rw-r--r--compiler/installer.ini1
-rw-r--r--compiler/semmagic.nim4
-rw-r--r--compiler/semtypinst.nim2
-rw-r--r--lib/pure/collections/queues.nim2
-rw-r--r--lib/pure/coro.nim2
-rw-r--r--lib/pure/httpclient.nim15
-rw-r--r--lib/pure/json.nim79
-rw-r--r--lib/windows/winlean.nim3
-rw-r--r--tests/closure/tclosure4.nim8
-rw-r--r--tests/parallel/tarray_of_channels.nim2
-rw-r--r--tests/parallel/tgc_unsafe.nim2
-rw-r--r--tests/parallel/tgc_unsafe2.nim2
-rw-r--r--tests/stdlib/tmitems.nim4
-rw-r--r--tests/threads/threadex.nim2
-rw-r--r--tests/threads/ttryrecv.nim4
-rw-r--r--web/news.txt6
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!
 ==========================================