summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/nimrod.ini2
-rw-r--r--lib/core/macros.nim6
-rw-r--r--lib/impure/fenv.nim113
-rw-r--r--lib/posix/posix.nim42
-rw-r--r--lib/pure/future.nim57
-rw-r--r--lib/pure/json.nim631
-rw-r--r--lib/pure/math.nim13
-rw-r--r--tools/niminst/nsis.tmpl13
8 files changed, 721 insertions, 156 deletions
diff --git a/compiler/nimrod.ini b/compiler/nimrod.ini
index ae1c6053f..7135b3490 100644
--- a/compiler/nimrod.ini
+++ b/compiler/nimrod.ini
@@ -126,7 +126,7 @@ Files: "start.bat"
 BinPath: r"bin;dist\mingw\bin;dist"
 
 ;           Section | dir | zipFile | size hint (in KB) | url | exe start menu entry
-Download: r"Documentation|doc|docs.zip|13824|http://nim-lang.org/download/docs-${version}.zip"
+Download: r"Documentation|doc|docs.zip|13824|http://nim-lang.org/download/docs-${version}.zip|doc\overview.html"
 Download: r"C Compiler (MingW)|dist|mingw.zip|82944|http://nim-lang.org/download/${mingw}.zip"
 Download: r"Aporia IDE|dist|aporia.zip|97997|http://nim-lang.org/download/aporia-0.1.3.zip|aporia\bin\aporia.exe"
 ; for now only NSIS supports optional downloads
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index e290cce32..455f99c9e 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -620,6 +620,8 @@ proc `body=`*(someProc: PNimrodNode, val: PNimrodNode) {.compileTime.} =
     someProc[high(someProc)] = val
   else:
     badNodeKind someProc.kind, "body=" 
+
+proc basename*(a: PNimrodNode): PNimrodNode {.compiletime.}
   
 
 proc `$`*(node: PNimrodNode): string {.compileTime.} =
@@ -627,6 +629,8 @@ proc `$`*(node: PNimrodNode): string {.compileTime.} =
   case node.kind
   of nnkIdent:
     result = $node.ident
+  of nnkPostfix:
+    result = $node.basename.ident & "*"
   of nnkStrLit..nnkTripleStrLit:
     result = node.strVal
   else: 
@@ -669,7 +673,7 @@ proc insert*(a: PNimrodNode; pos: int; b: PNimrodNode) {.compileTime.} =
       a[i + 1] = a[i]
     a[pos] = b
 
-proc basename*(a: PNimrodNode): PNimrodNode {.compiletime.} =
+proc basename*(a: PNimrodNode): PNimrodNode =
   ## Pull an identifier from prefix/postfix expressions
   case a.kind
   of nnkIdent: return a
diff --git a/lib/impure/fenv.nim b/lib/impure/fenv.nim
new file mode 100644
index 000000000..9d7c8809b
--- /dev/null
+++ b/lib/impure/fenv.nim
@@ -0,0 +1,113 @@
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2014 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## Floating-point environment. Handling of floating-point rounding and
+## exceptions (overflow, zero-devide, etc.).
+
+{.deadCodeElim:on.}
+
+when defined(Posix) and not defined(haiku):
+  {.passl: "-lm".}
+
+var
+  FE_DIVBYZERO* {.importc, header: "<fenv.h>".}: cint
+    ## division by zero
+  FE_INEXACT* {.importc, header: "<fenv.h>".}: cint
+    ## inexact result
+  FE_INVALID* {.importc, header: "<fenv.h>".}: cint
+    ## invalid operation
+  FE_OVERFLOW* {.importc, header: "<fenv.h>".}: cint
+    ## result not representable due to overflow
+  FE_UNDERFLOW* {.importc, header: "<fenv.h>".}: cint
+    ## result not representable due to underflow
+  FE_ALL_EXCEPT* {.importc, header: "<fenv.h>".}: cint
+    ## bitwise OR of all supported exceptions
+  FE_DOWNWARD* {.importc, header: "<fenv.h>".}: cint
+    ## round toward -Inf
+  FE_TONEAREST* {.importc, header: "<fenv.h>".}: cint
+    ## round to nearest
+  FE_TOWARDZERO* {.importc, header: "<fenv.h>".}: cint
+    ## round toward 0
+  FE_UPWARD* {.importc, header: "<fenv.h>".}: cint
+    ## round toward +Inf
+  FE_DFL_ENV* {.importc, header: "<fenv.h>".}: cint
+    ## macro of type pointer to fenv_t to be used as the argument
+    ## to functions taking an argument of type fenv_t; in this
+    ## case the default environment will be used
+
+type
+  TFloatClass* = enum ## describes the class a floating point value belongs to.
+                      ## This is the type that is returned by `classify`.
+    fcNormal,    ## value is an ordinary nonzero floating point value
+    fcSubnormal, ## value is a subnormal (a very small) floating point value
+    fcZero,      ## value is zero
+    fcNegZero,   ## value is the negative zero
+    fcNan,       ## value is Not-A-Number (NAN)
+    fcInf,       ## value is positive infinity
+    fcNegInf     ## value is negative infinity
+
+  Tfenv* {.importc: "fenv_t", header: "<fenv.h>", final, pure.} =
+    object ## Represents the entire floating-point environment. The
+           ## floating-point environment refers collectively to any
+           ## floating-point status flags and control modes supported
+           ## by the implementation.
+  Tfexcept* {.importc: "fexcept_t", header: "<fenv.h>", final, pure.} =
+    object ## Represents the floating-point status flags collectively,
+           ## including any status the implementation associates with the
+           ## flags. A floating-point status flag is a system variable
+           ## whose value is set (but never cleared) when a floating-point
+           ## exception is raised, which occurs as a side effect of
+           ## exceptional floating-point arithmetic to provide auxiliary
+           ## information. A floating-point control mode is a system variable
+           ## whose value may be set by the user to affect the subsequent
+           ## behavior of floating-point arithmetic.
+
+proc feclearexcept*(excepts: cint): cint {.importc, header: "<fenv.h>".}
+  ## Clear the supported exceptions represented by `excepts`.
+
+proc fegetexceptflag*(flagp: ptr Tfexcept, excepts: cint): cint {.
+  importc, header: "<fenv.h>".}
+  ## Store implementation-defined representation of the exception flags
+  ## indicated by `excepts` in the object pointed to by `flagp`.
+
+proc feraiseexcept*(excepts: cint): cint {.importc, header: "<fenv.h>".}
+  ## Raise the supported exceptions represented by `excepts`.
+
+proc fesetexceptflag*(flagp: ptr Tfexcept, excepts: cint): cint {.
+  importc, header: "<fenv.h>".}
+  ## Set complete status for exceptions indicated by `excepts` according to
+  ## the representation in the object pointed to by `flagp`.
+
+proc fetestexcept*(excepts: cint): cint {.importc, header: "<fenv.h>".}
+  ## Determine which of subset of the exceptions specified by `excepts` are
+  ## currently set.
+
+proc fegetround*(): cint {.importc, header: "<fenv.h>".}
+  ## Get current rounding direction.
+
+proc fesetround*(roundingDirection: cint): cint {.importc, header: "<fenv.h>".}
+  ## Establish the rounding direction represented by `roundingDirection`.
+
+proc fegetenv*(envp: ptr Tfenv): cint {.importc, header: "<fenv.h>".}
+  ## Store the current floating-point environment in the object pointed
+  ## to by `envp`.
+
+proc feholdexcept*(envp: ptr Tfenv): cint {.importc, header: "<fenv.h>".}
+  ## Save the current environment in the object pointed to by `envp`, clear
+  ## exception flags and install a non-stop mode (if available) for all
+  ## exceptions.
+
+proc fesetenv*(a1: ptr Tfenv): cint {.importc, header: "<fenv.h>".}
+  ## Establish the floating-point environment represented by the object
+  ## pointed to by `envp`.
+
+proc feupdateenv*(envp: ptr Tfenv): cint {.importc, header: "<fenv.h>".}
+  ## Save current exceptions in temporary storage, install environment
+  ## represented by object pointed to by `envp` and raise exceptions
+  ## according to saved exceptions.
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index e1bcd9dfc..9334ceeae 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -99,22 +99,6 @@ type
     l_pid*: TPid      ## Process ID of the process holding the lock;
                       ## returned with F_GETLK.
 
-  Tfenv* {.importc: "fenv_t", header: "<fenv.h>", final, pure.} =
-    object ## Represents the entire floating-point environment. The
-           ## floating-point environment refers collectively to any
-           ## floating-point status flags and control modes supported
-           ## by the implementation.
-  Tfexcept* {.importc: "fexcept_t", header: "<fenv.h>", final, pure.} =
-    object ## Represents the floating-point status flags collectively,
-           ## including any status the implementation associates with the
-           ## flags. A floating-point status flag is a system variable
-           ## whose value is set (but never cleared) when a floating-point
-           ## exception is raised, which occurs as a side effect of
-           ## exceptional floating-point arithmetic to provide auxiliary
-           ## information. A floating-point control mode is a system variable
-           ## whose value may be set by the user to affect the subsequent
-           ## behavior of floating-point arithmetic.
-
   TFTW* {.importc: "struct FTW", header: "<ftw.h>", final, pure.} = object
     base*: cint
     level*: cint
@@ -834,18 +818,6 @@ var
     ## The application expects to access the specified data once and
     ## then not reuse it thereafter.
 
-  FE_DIVBYZERO* {.importc, header: "<fenv.h>".}: cint
-  FE_INEXACT* {.importc, header: "<fenv.h>".}: cint
-  FE_INVALID* {.importc, header: "<fenv.h>".}: cint
-  FE_OVERFLOW* {.importc, header: "<fenv.h>".}: cint
-  FE_UNDERFLOW* {.importc, header: "<fenv.h>".}: cint
-  FE_ALL_EXCEPT* {.importc, header: "<fenv.h>".}: cint
-  FE_DOWNWARD* {.importc, header: "<fenv.h>".}: cint
-  FE_TONEAREST* {.importc, header: "<fenv.h>".}: cint
-  FE_TOWARDZERO* {.importc, header: "<fenv.h>".}: cint
-  FE_UPWARD* {.importc, header: "<fenv.h>".}: cint
-  FE_DFL_ENV* {.importc, header: "<fenv.h>".}: cint
-
 when not defined(haiku) and not defined(OpenBSD):
   var
     MM_HARD* {.importc, header: "<fmtmsg.h>".}: cint
@@ -1821,20 +1793,6 @@ proc posix_fadvise*(a1: cint, a2, a3: TOff, a4: cint): cint {.
 proc posix_fallocate*(a1: cint, a2, a3: TOff): cint {.
   importc, header: "<fcntl.h>".}
 
-proc feclearexcept*(a1: cint): cint {.importc, header: "<fenv.h>".}
-proc fegetexceptflag*(a1: ptr Tfexcept, a2: cint): cint {.
-  importc, header: "<fenv.h>".}
-proc feraiseexcept*(a1: cint): cint {.importc, header: "<fenv.h>".}
-proc fesetexceptflag*(a1: ptr Tfexcept, a2: cint): cint {.
-  importc, header: "<fenv.h>".}
-proc fetestexcept*(a1: cint): cint {.importc, header: "<fenv.h>".}
-proc fegetround*(): cint {.importc, header: "<fenv.h>".}
-proc fesetround*(a1: cint): cint {.importc, header: "<fenv.h>".}
-proc fegetenv*(a1: ptr Tfenv): cint {.importc, header: "<fenv.h>".}
-proc feholdexcept*(a1: ptr Tfenv): cint {.importc, header: "<fenv.h>".}
-proc fesetenv*(a1: ptr Tfenv): cint {.importc, header: "<fenv.h>".}
-proc feupdateenv*(a1: ptr Tfenv): cint {.importc, header: "<fenv.h>".}
-
 when not defined(haiku) and not defined(OpenBSD):
   proc fmtmsg*(a1: int, a2: cstring, a3: cint,
               a4, a5, a6: cstring): cint {.importc, header: "<fmtmsg.h>".}
diff --git a/lib/pure/future.nim b/lib/pure/future.nim
index b7df05207..480ee2b0d 100644
--- a/lib/pure/future.nim
+++ b/lib/pure/future.nim
@@ -115,3 +115,60 @@ macro `->`*(p, b: expr): expr {.immediate.} =
   ##     f(2, 2)
 
   result = createProcType(p, b)
+
+type ListComprehension = object
+var lc*: ListComprehension
+
+macro `[]`*(lc: ListComprehension, comp, typ: expr): expr =
+  ## List comprehension, returns a sequence. `comp` is the actual list
+  ## comprehension, for example ``x | (x <- 1..10, x mod 2 == 0)``. `typ` is
+  ## the type that will be stored inside the result seq.
+  ##
+  ## .. code-block:: nimrod
+  ##
+  ##   echo lc[x | (x <- 1..10, x mod 2 == 0), int]
+  ##
+  ##   const n = 20
+  ##   echo lc[(x,y,z) | (x <- 1..n, y <- x..n, z <- y..n, x*x + y*y == z*z),
+  ##           tuple[a,b,c: int]]
+
+  expectLen(comp, 3)
+  expectKind(comp, nnkInfix)
+  expectKind(comp[0], nnkIdent)
+  assert($comp[0].ident == "|")
+
+  result = newCall(
+    newDotExpr(
+      newIdentNode("result"),
+      newIdentNode("add")),
+    comp[1])
+
+  for i in countdown(comp[2].len-1, 0):
+    let x = comp[2][i]
+    expectKind(x, nnkInfix)
+    expectMinLen(x, 1)
+    if x[0].kind == nnkIdent and $x[0].ident == "<-":
+      expectLen(x, 3)
+      result = newNimNode(nnkForStmt).add(x[1], x[2], result)
+    else:
+      result = newIfStmt((x, result))
+
+  result = newNimNode(nnkCall).add(
+    newNimNode(nnkPar).add(
+      newNimNode(nnkLambda).add(
+        newEmptyNode(),
+        newEmptyNode(),
+        newEmptyNode(),
+        newNimNode(nnkFormalParams).add(
+          newNimNode(nnkBracketExpr).add(
+            newIdentNode("seq"),
+            typ)),
+        newEmptyNode(),
+        newEmptyNode(),
+        newStmtList(
+          newAssignment(
+            newIdentNode("result"),
+            newNimNode(nnkPrefix).add(
+              newIdentNode("@"),
+              newNimNode(nnkBracket))),
+          result))))
diff --git a/lib/pure/json.nim b/lib/pure/json.nim
index a45900f29..5d51c2d87 100644
--- a/lib/pure/json.nim
+++ b/lib/pure/json.nim
@@ -7,47 +7,71 @@
 #    distribution, for details about the copyright.
 #
 
-## This module implements a simple high performance `JSON`:idx:
-## parser. JSON (JavaScript Object Notation) is a lightweight 
-## data-interchange format that is easy for humans to read and write 
-## (unlike XML). It is easy for machines to parse and generate.
-## JSON is based on a subset of the JavaScript Programming Language,
-## Standard ECMA-262 3rd Edition - December 1999.
+## This module implements a simple high performance `JSON`:idx: parser. `JSON
+## (JavaScript Object Notation) <http://www.json.org>`_ is a lightweight
+## data-interchange format that is easy for humans to read and write (unlike
+## XML). It is easy for machines to parse and generate.  JSON is based on a
+## subset of the JavaScript Programming Language, `Standard ECMA-262 3rd
+## Edition - December 1999
+## <http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf>`_.
 ##
-## Usage example:
+## Parsing small values quickly can be done with the convenience `parseJson()
+## <#parseJson,string>`_ proc which returns the whole JSON tree.  If you are
+## parsing very big JSON inputs or want to skip most of the items in them you
+## can initialize your own `TJsonParser <#TJsonParser>`_ with the `open()
+## <#open>`_ proc and call `next() <#next>`_ in a loop to process the
+## individual parsing events.
+##
+## If you need to create JSON objects from your Nimrod types you can call procs
+## like `newJObject() <#newJObject>`_ (or their equivalent `%()
+## <#%,openArray[tuple[string,PJsonNode]]>`_ generic constructor). For
+## consistency you can provide your own ``%`` operators for custom object
+## types:
 ##
 ## .. code-block:: nimrod
-##  let
-##    small_json = """{"test": 1.3, "key2": true}"""
-##    jobj = parseJson(small_json)
-##  assert (jobj.kind == JObject)
-##  echo($jobj["test"].fnum)
-##  echo($jobj["key2"].bval)
+##   type
+##     Person = object ## Generic person record.
+##       age: int      ## The age of the person.
+##       name: string  ## The name of the person.
 ##
-## Results in:
+##   proc `%`(p: Person): PJsonNode =
+##     ## Converts a Person into a PJsonNode.
+##     result = %[("age", %p.age), ("name", %p.name)]
 ##
-## .. code-block:: nimrod
+##   proc test() =
+##     # Tests making some jsons.
+##     var p: Person
+##     p.age = 24
+##     p.name = "Minah"
+##     echo(%p) # { "age": 24,  "name": "Minah"}
+##
+##     p.age = 33
+##     p.name = "Sojin"
+##     echo(%p) # { "age": 33,  "name": "Sojin"}
 ##
-##   1.3000000000000000e+00
-##   true
+## If you don't need special logic in your Nimrod objects' serialization code
+## you can also use the `marshal module <marshal.html>`_ which converts objects
+## directly to JSON.
 
 import 
   hashes, strutils, lexbase, streams, unicode
 
 type 
-  TJsonEventKind* = enum ## enumeration of all events that may occur when parsing
-    jsonError,           ## an error ocurred during parsing
-    jsonEof,             ## end of file reached
-    jsonString,          ## a string literal
-    jsonInt,             ## an integer literal
-    jsonFloat,           ## a float literal
-    jsonTrue,            ## the value ``true``
-    jsonFalse,           ## the value ``false``
-    jsonNull,            ## the value ``null``
-    jsonObjectStart,     ## start of an object: the ``{`` token
-    jsonObjectEnd,       ## end of an object: the ``}`` token
-    jsonArrayStart,      ## start of an array: the ``[`` token
-    jsonArrayEnd         ## start of an array: the ``]`` token
+  TJsonEventKind* = enum ## Events that may occur when parsing. \
+    ##
+    ## You compare these values agains the result of the `kind() proc <#kind>`_.
+    jsonError,           ## An error ocurred during parsing.
+    jsonEof,             ## End of file reached.
+    jsonString,          ## A string literal.
+    jsonInt,             ## An integer literal.
+    jsonFloat,           ## A float literal.
+    jsonTrue,            ## The value ``true``.
+    jsonFalse,           ## The value ``false``.
+    jsonNull,            ## The value ``null``.
+    jsonObjectStart,     ## Start of an object: the ``{`` token.
+    jsonObjectEnd,       ## End of an object: the ``}`` token.
+    jsonArrayStart,      ## Start of an array: the ``[`` token.
+    jsonArrayEnd         ## Start of an array: the ``]`` token.
     
   TTokKind = enum        # must be synchronized with TJsonEventKind!
     tkError,
@@ -65,7 +89,7 @@ type
     tkColon,
     tkComma
     
-  TJsonError* = enum       ## enumeration that lists all errors that can occur
+  TJsonError = enum        ## enumeration that lists all errors that can occur
     errNone,               ## no error
     errInvalidToken,       ## invalid token
     errStringExpected,     ## string expected
@@ -82,7 +106,9 @@ type
     stateEof, stateStart, stateObject, stateArray, stateExpectArrayComma,
     stateExpectObjectComma, stateExpectColon, stateExpectValue
 
-  TJsonParser* = object of TBaseLexer ## the parser object.
+  TJsonParser* = object of TBaseLexer ## The JSON parser object. \
+    ##
+    ## Create a variable of this type and use `open() <#open>`_ on it.
     a: string
     tok: TTokKind
     kind: TJsonEventKind
@@ -117,59 +143,129 @@ const
   ]
 
 proc open*(my: var TJsonParser, input: PStream, filename: string) =
-  ## initializes the parser with an input stream. `Filename` is only used
-  ## for nice error messages.
-  lexbase.open(my, input)
+  ## Initializes the JSON parser with an `input stream <streams.html>`_.
+  ##
+  ## The `filename` parameter is not strictly required and is used only for
+  ## nice error messages. You can pass ``nil`` as long as you never use procs
+  ## like `errorMsg() <#errorMsg>`_ or `errorMsgExpected()
+  ## <#errorMsgExpected>`_ but passing a dummy filename like ``<input string>``
+  ## is safer and more user friendly. Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   import json, streams
+  ##
+  ##   var
+  ##     s = newStringStream("some valid json")
+  ##     p: TJsonParser
+  ##   p.open(s, "<input string>")
+  ##
+  ## Once opened, you can process JSON parsing events with the `next()
+  ## <#next>`_ proc.
   my.filename = filename
   my.state = @[stateStart]
   my.kind = jsonError
   my.a = ""
   
-proc close*(my: var TJsonParser) {.inline.} = 
-  ## closes the parser `my` and its associated input stream.
+proc close*(my: var TJsonParser) {.inline.} =
+  ## Closes the parser `my` and its associated input stream.
+  ##
+  ## Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var
+  ##     s = newStringStream("some valid json")
+  ##     p: TJsonParser
+  ##   p.open(s, "<input string>")
+  ##   finally: p.close
+  ##   # write here parsing of input
   lexbase.close(my)
 
 proc str*(my: TJsonParser): string {.inline.} = 
-  ## returns the character data for the events: ``jsonInt``, ``jsonFloat``, 
-  ## ``jsonString``
+  ## Returns the character data for the `events <#TJsonEventKind>`_
+  ## ``jsonInt``, ``jsonFloat`` and ``jsonString``.
+  ##
+  ## This proc will `assert <system.html#assert>`_ in debug builds when used
+  ## with other event types. See `next() <#next>`_ for an usage example.
   assert(my.kind in {jsonInt, jsonFloat, jsonString})
   return my.a
 
 proc getInt*(my: TJsonParser): BiggestInt {.inline.} = 
-  ## returns the number for the event: ``jsonInt``
+  ## Returns the number for the `jsonInt <#TJsonEventKind>`_ event.
+  ##
+  ## This proc will `assert <system.html#assert>`_ in debug builds when used
+  ## with other event types. See `next() <#next>`_ for an usage example.
   assert(my.kind == jsonInt)
   return parseBiggestInt(my.a)
 
 proc getFloat*(my: TJsonParser): float {.inline.} = 
-  ## returns the number for the event: ``jsonFloat``
+  ## Returns the number for the `jsonFloat <#TJsonEventKind>`_ event.
+  ##
+  ## This proc will `assert <system.html#assert>`_ in debug builds when used
+  ## with other event types. See `next() <#next>`_ for an usage example.
   assert(my.kind == jsonFloat)
   return parseFloat(my.a)
 
 proc kind*(my: TJsonParser): TJsonEventKind {.inline.} = 
-  ## returns the current event type for the JSON parser
+  ## Returns the current event type for the `JSON parser <#TJsonParser>`_.
+  ##
+  ## Call this proc just after `next() <#next>`_ to act on the new event.
   return my.kind
   
 proc getColumn*(my: TJsonParser): int {.inline.} = 
-  ## get the current column the parser has arrived at.
+  ## Get the current column the parser has arrived at.
+  ##
+  ## While this is mostly used by procs like `errorMsg() <#errorMsg>`_ you can
+  ## use it as well to show user warnings if you are validating JSON values
+  ## during parsing. See `next() <#next>`_ for the full example:
+  ##
+  ## .. code-block:: nimrod
+  ##   case parser.kind
+  ##   ...
+  ##   of jsonString:
+  ##     let inputValue = parser.str
+  ##     if previousValues.contains(inputValue):
+  ##       echo "$1($2, $3) Warning: repeated value '$4'" % [
+  ##         parser.getFilename, $parser.getLine, $parser.getColumn,
+  ##          inputValue]
+  ##   ...
   result = getColNumber(my, my.bufpos)
 
 proc getLine*(my: TJsonParser): int {.inline.} = 
-  ## get the current line the parser has arrived at.
+  ## Get the current line the parser has arrived at.
+  ##
+  ## While this is mostly used by procs like `errorMsg() <#errorMsg>`_ you can
+  ## use it as well to indicate user warnings if you are validating JSON values
+  ## during parsing. See `next() <#next>`_ and `getColumn() <#getColumn>`_ for
+  ## examples.
   result = my.lineNumber
 
 proc getFilename*(my: TJsonParser): string {.inline.} = 
-  ## get the filename of the file that the parser processes.
+  ## Get the filename of the file that the parser is processing.
+  ##
+  ## This is the value you pass to the `open() <#open>`_ proc.  While this is
+  ## mostly used by procs like `errorMsg() <#errorMsg>`_ you can use it as well
+  ## to indicate user warnings if you are validating JSON values during
+  ## parsing. See `next() <#next>`_ and `getColumn() <#getColumn>`_ for
+  ## examples.
   result = my.filename
   
 proc errorMsg*(my: TJsonParser): string = 
-  ## returns a helpful error message for the event ``jsonError``
+  ## Returns a helpful error message for the `jsonError <#TJsonEventKind>`_
+  ## event.
+  ##
+  ## This proc will `assert <system.html#assert>`_ in debug builds when used
+  ## with other event types. See `next() <#next>`_ for an usage example.
   assert(my.kind == jsonError)
   result = "$1($2, $3) Error: $4" % [
     my.filename, $getLine(my), $getColumn(my), errorMessages[my.err]]
 
 proc errorMsgExpected*(my: TJsonParser, e: string): string = 
-  ## returns an error message "`e` expected" in the same format as the
-  ## other error messages 
+  ## Returns an error message "`e` expected".
+  ##
+  ## The message is in the same format as the other error messages which
+  ## include the parser filename, line and column values. This is used by
+  ## `raiseParseErr() <#raiseParseErr>`_ to raise  an `EJsonParsingError
+  ## <#EJsonParsingError>`_.
   result = "$1($2, $3) Error: $4" % [
     my.filename, $getLine(my), $getColumn(my), e & " expected"]
 
@@ -382,7 +478,32 @@ proc getTok(my: var TJsonParser): TTokKind =
   my.tok = result
 
 proc next*(my: var TJsonParser) = 
-  ## retrieves the first/next event. This controls the parser.
+  ## Retrieves the first/next event for the `JSON parser <#TJsonParser>`_.
+  ##
+  ## You are meant to call this method inside an infinite loop. After each
+  ## call, check the result of the `kind() <#kind>`_ proc to know what has to
+  ## be done next (eg. break out due to end of file). Here is a basic example
+  ## which simply echoes all found elements by the parser:
+  ##
+  ## .. code-block:: nimrod
+  ##   parser.open(stream, "<input string>")
+  ##   while true:
+  ##     parser.next
+  ##     case parser.kind
+  ##     of jsonError:
+  ##       echo parser.errorMsg
+  ##       break
+  ##     of jsonEof: break
+  ##     of jsonString: echo parser.str
+  ##     of jsonInt: echo parser.getInt
+  ##     of jsonFloat: echo parser.getFloat
+  ##     of jsonTrue: echo "true"
+  ##     of jsonFalse: echo "false"
+  ##     of jsonNull: echo "null"
+  ##     of jsonObjectStart: echo "{"
+  ##     of jsonObjectEnd: echo "}"
+  ##     of jsonArrayStart: echo "["
+  ##     of jsonArrayEnd: echo "]"
   var tk = getTok(my)
   var i = my.state.len-1
   # the following code is a state machine. If we had proper coroutines,
@@ -502,7 +623,16 @@ proc next*(my: var TJsonParser) =
 # ------------- higher level interface ---------------------------------------
 
 type
-  TJsonNodeKind* = enum ## possible JSON node types
+  TJsonNodeKind* = enum ## Possible `JSON node <#TJsonNodeKind>`_ types. \
+    ##
+    ## To build nodes use the helper procs
+    ## `newJNull() <#newJNull>`_,
+    ## `newJBool() <#newJBool>`_,
+    ## `newJInt() <#newJInt>`_,
+    ## `newJFloat() <#newJFloat>`_,
+    ## `newJString() <#newJString>`_,
+    ## `newJObject() <#newJObject>`_ and
+    ## `newJArray() <#newJArray>`_.
     JNull,
     JBool,
     JInt,
@@ -511,8 +641,9 @@ type
     JObject,
     JArray
     
-  PJsonNode* = ref TJsonNode ## JSON node 
-  TJsonNode* {.final, pure, acyclic.} = object
+  PJsonNode* = ref TJsonNode ## Reference to a `JSON node <#TJsonNode>`_.
+  TJsonNode* {.final, pure, acyclic.} = object ## `Object variant \
+    ## <manual.html#object-variants>`_ wrapping all possible JSON types.
     case kind*: TJsonNodeKind
     of JString:
       str*: string
@@ -529,14 +660,36 @@ type
     of JArray:
       elems*: seq[PJsonNode]
 
-  EJsonParsingError* = object of EInvalidValue ## is raised for a JSON error
+  EJsonParsingError* = object of EInvalidValue ## Raised during JSON parsing. \
+    ##
+    ## Example:
+    ##
+    ## .. code-block:: nimrod
+    ##   let smallJson = """{"test: 1.3, "key2": true}"""
+    ##   try:
+    ##     discard parseJson(smallJson)
+    ##     # --> Bad JSON! input(1, 18) Error: : expected
+    ##   except EJsonParsingError:
+    ##     echo "Bad JSON! " & getCurrentExceptionMsg()
 
 proc raiseParseErr*(p: TJsonParser, msg: string) {.noinline, noreturn.} =
-  ## raises an `EJsonParsingError` exception.
+  ## Raises an `EJsonParsingError <#EJsonParsingError>`_ exception.
+  ##
+  ## The message for the exception will be built passing the `msg` parameter to
+  ## the `errorMsgExpected() <#errorMsgExpected>`_ proc.
   raise newException(EJsonParsingError, errorMsgExpected(p, msg))
 
 proc newJString*(s: string): PJsonNode =
-  ## Creates a new `JString PJsonNode`.
+  ## Creates a new `JString PJsonNode <#TJsonNodeKind>`_.
+  ##
+  ## Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var node = newJString("A string")
+  ##   echo node
+  ##   # --> "A string"
+  ##
+  ## Or you can use the shorter `%() proc <#%,string>`_.
   new(result)
   result.kind = JString
   result.str = s
@@ -547,80 +700,206 @@ proc newJStringMove(s: string): PJsonNode =
   shallowCopy(result.str, s)
 
 proc newJInt*(n: BiggestInt): PJsonNode =
-  ## Creates a new `JInt PJsonNode`.
+  ## Creates a new `JInt PJsonNode <#TJsonNodeKind>`_.
+  ##
+  ## Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var node = newJInt(900_100_200_300)
+  ##   echo node
+  ##   # --> 900100200300
+  ##
+  ## Or you can use the shorter `%() proc <#%,BiggestInt>`_.
   new(result)
   result.kind = JInt
   result.num  = n
 
 proc newJFloat*(n: float): PJsonNode =
-  ## Creates a new `JFloat PJsonNode`.
+  ## Creates a new `JFloat PJsonNode <#TJsonNodeKind>`_.
+  ##
+  ## Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var node = newJFloat(3.14)
+  ##   echo node
+  ##   # --> 3.14
+  ##
+  ## Or you can use the shorter `%() proc <#%,float>`_.
   new(result)
   result.kind = JFloat
   result.fnum  = n
 
 proc newJBool*(b: bool): PJsonNode =
-  ## Creates a new `JBool PJsonNode`.
+  ## Creates a new `JBool PJsonNode <#TJsonNodeKind>`_.
+  ##
+  ## Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var node = newJBool(true)
+  ##   echo node
+  ##   # --> true
+  ##
+  ## Or you can use the shorter `%() proc <#%,bool>`_.
   new(result)
   result.kind = JBool
   result.bval = b
 
 proc newJNull*(): PJsonNode =
-  ## Creates a new `JNull PJsonNode`.
+  ## Creates a new `JNull PJsonNode <#TJsonNodeKind>`_.
+  ##
+  ## Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var node = newJNull()
+  ##   echo node
+  ##   # --> null
   new(result)
 
 proc newJObject*(): PJsonNode =
-  ## Creates a new `JObject PJsonNode`
+  ## Creates a new `JObject PJsonNode <#TJsonNodeKind>`_.
+  ##
+  ## The `PJsonNode <#PJsonNode>`_ will be initialized with an empty ``fields``
+  ## sequence to which you can add new elements. Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var node = newJObject()
+  ##   node.add("age", newJInt(24))
+  ##   node.add("name", newJString("Minah"))
+  ##   echo node
+  ##   # --> { "age": 24,  "name": "Minah"}
+  ##
+  ## Or you can use the shorter `%() proc
+  ## <#%,openArray[tuple[string,PJsonNode]]>`_.
   new(result)
   result.kind = JObject
   result.fields = @[]
 
 proc newJArray*(): PJsonNode =
-  ## Creates a new `JArray PJsonNode`
+  ## Creates a new `JArray PJsonNode <#TJsonNodeKind>`_.
+  ##
+  ## The `PJsonNode <#PJsonNode>`_ will be initialized with an empty ``elems``
+  ## sequence to which you can add new elements. Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var node = newJArray()
+  ##   node.add(newJString("Mixing types"))
+  ##   node.add(newJInt(42))
+  ##   node.add(newJString("is madness"))
+  ##   node.add(newJFloat(3.14))
+  ##   echo node
+  ##   # --> [ "Mixing types",  42,  "is madness",  3.14]
+  ##
+  ## Or you can use the shorter `%() proc <#%,openArray[PJsonNode]>`_.
   new(result)
   result.kind = JArray
   result.elems = @[]
 
 
 proc `%`*(s: string): PJsonNode =
-  ## Generic constructor for JSON data. Creates a new `JString PJsonNode`.
+  ## Creates a new `JString PJsonNode <#TJsonNodeKind>`_.
+  ##
+  ## Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var node = %"A string"
+  ##   echo node
+  ##   # --> "A string"
+  ##
+  ## This generic constructor is equivalent to the `newJString()
+  ## <#newJString>`_ proc.
   new(result)
   result.kind = JString
   result.str = s
 
 proc `%`*(n: BiggestInt): PJsonNode =
-  ## Generic constructor for JSON data. Creates a new `JInt PJsonNode`.
+  ## Creates a new `JInt PJsonNode <#TJsonNodeKind>`_.
+  ##
+  ## Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var node = %900_100_200_300
+  ##   echo node
+  ##   # --> 900100200300
+  ##
+  ## This generic constructor is equivalent to the `newJInt() <#newJInt>`_
+  ## proc.
   new(result)
   result.kind = JInt
   result.num  = n
 
 proc `%`*(n: float): PJsonNode =
-  ## Generic constructor for JSON data. Creates a new `JFloat PJsonNode`.
+  ## Creates a new `JFloat PJsonNode <#TJsonNodeKind>`_.
+  ##
+  ## Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var node = %3.14
+  ##   echo node
+  ##   # --> 3.14
+  ##
+  ## This generic constructor is equivalent to the `newJFloat() <#newJFloat>`_
+  ## proc.
   new(result)
   result.kind = JFloat
   result.fnum  = n
 
 proc `%`*(b: bool): PJsonNode =
-  ## Generic constructor for JSON data. Creates a new `JBool PJsonNode`.
+  ## Creates a new `JBool PJsonNode <#TJsonNodeKind>`_.
+  ##
+  ## Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var node = %true
+  ##   echo node
+  ##   # --> true
+  ##
+  ## This generic constructor is equivalent to the `newJBool() <#newJBool>`_
+  ## proc.
   new(result)
   result.kind = JBool
   result.bval = b
 
 proc `%`*(keyVals: openArray[tuple[key: string, val: PJsonNode]]): PJsonNode =
-  ## Generic constructor for JSON data. Creates a new `JObject PJsonNode`
+  ## Creates a new `JObject PJsonNode <#TJsonNodeKind>`_.
+  ##
+  ## Unlike the `newJObject() <#newJObject>`_ proc, which returns an object
+  ## that has to be further manipulated, you can use this generic constructor
+  ## to create JSON objects with all their fields in one go. Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   let node = %[("age", %24), ("name", %"Minah")]
+  ##   echo node
+  ##   # --> { "age": 24,  "name": "Minah"}
   new(result)
   result.kind = JObject
   newSeq(result.fields, keyVals.len)
   for i, p in pairs(keyVals): result.fields[i] = p
 
 proc `%`*(elements: openArray[PJsonNode]): PJsonNode =
-  ## Generic constructor for JSON data. Creates a new `JArray PJsonNode`
+  ## Creates a new `JArray PJsonNode <#TJsonNodeKind>`_.
+  ##
+  ## Unlike the `newJArray() <#newJArray>`_ proc, which returns an object
+  ## that has to be further manipulated, you can use this generic constructor
+  ## to create JSON arrays with all their values in one go. Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   let node = %[%"Mixing types", %42,
+  ##     %"is madness", %3.14,]
+  ##   echo node
+  ##   # --> [ "Mixing types",  42,  "is madness",  3.14]
   new(result)
   result.kind = JArray
   newSeq(result.elems, elements.len)
   for i, p in pairs(elements): result.elems[i] = p
 
 proc `==`* (a,b: PJsonNode): bool =
-  ## Check two nodes for equality
+  ## Check two `PJsonNode <#PJsonNode>`_ nodes for equality.
+  ##
+  ## Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   assert(%1 == %1)
+  ##   assert(%1 != %2)
   if a.isNil:
     if b.isNil: return true
     return false
@@ -644,7 +923,21 @@ proc `==`* (a,b: PJsonNode): bool =
       a.fields == b.fields
 
 proc hash* (n:PJsonNode): THash =
-  ## Compute the hash for a JSON node
+  ## Computes the hash for a JSON node.
+  ##
+  ## The `THash <hashes.html#THash>`_ allows JSON nodes to be used as keys for
+  ## `sets <sets.html>`_ or `tables <tables.html>`_. Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   import json, sets
+  ##
+  ##   var
+  ##     uniqueValues = initSet[PJsonNode]()
+  ##     values = %[%1, %2, %1, %2, %3]
+  ##   for value in values.elems:
+  ##     discard uniqueValues.containsOrIncl(value)
+  ##   echo uniqueValues
+  ##   # --> {1, 2, 3}
   case n.kind
   of JArray:
     result = hash(n.elems)
@@ -662,17 +955,40 @@ proc hash* (n:PJsonNode): THash =
     result = hash(0)
 
 proc len*(n: PJsonNode): int = 
-  ## If `n` is a `JArray`, it returns the number of elements.
-  ## If `n` is a `JObject`, it returns the number of pairs.
-  ## Else it returns 0.
+  ## Returns the number of children items for this `PJsonNode <#PJsonNode>`_.
+  ##
+  ## If `n` is a `JArray <#TJsonNodeKind>`_, it will return the number of
+  ## elements.  If `n` is a `JObject <#TJsonNodeKind>`_, it will return the
+  ## number of key-value pairs. For all other types this proc returns zero.
+  ## Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   let
+  ##     n1 = %[("age", %33), ("name", %"Sojin")]
+  ##     n2 = %[%1, %2, %3, %4, %5, %6, %7]
+  ##     n3 = %"Some odd string we have here"
+  ##   echo n1.len # --> 2
+  ##   echo n2.len # --> 7
+  ##   echo n3.len # --> 0
+  ##
   case n.kind
   of JArray: result = n.elems.len
   of JObject: result = n.fields.len
   else: discard
 
 proc `[]`*(node: PJsonNode, name: string): PJsonNode =
-  ## Gets a field from a `JObject`, which must not be nil.
-  ## If the value at `name` does not exist, returns nil
+  ## Gets a named field from a `JObject <#TJsonNodeKind>`_ `PJsonNode
+  ## <#PJsonNode>`_.
+  ##
+  ## Returns the value for `name` or nil if `node` doesn't contain such a
+  ## field.  This proc will `assert <system.html#assert>`_ in debug builds if
+  ## `name` is ``nil`` or `node` is not a ``JObject``. On release builds it
+  ## will likely crash. Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   let node = %[("age", %40), ("name", %"Britney")]
+  ##   echo node["name"]
+  ##   # --> "Britney"
   assert(not isNil(node))
   assert(node.kind == JObject)
   for key, item in items(node.fields):
@@ -681,35 +997,92 @@ proc `[]`*(node: PJsonNode, name: string): PJsonNode =
   return nil
   
 proc `[]`*(node: PJsonNode, index: int): PJsonNode =
-  ## Gets the node at `index` in an Array. Result is undefined if `index`
-  ## is out of bounds
+  ## Gets the `index` item from a `JArray <#TJsonNodeKind>`_ `PJsonNode
+  ## <#PJsonNode>`_.
+  ##
+  ## Returns the specified item. Result is undefined if `index` is out of
+  ## bounds.  This proc will `assert <system.html#assert>`_ in debug builds if
+  ## `node` is ``nil`` or not a ``JArray``. Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   let node = %[%"Mixing types", %42,
+  ##     %"is madness", %3.14,]
+  ##   echo node[2]
+  ##   # --> "is madness"
   assert(not isNil(node))
   assert(node.kind == JArray)
   return node.elems[index]
 
 proc hasKey*(node: PJsonNode, key: string): bool =
-  ## Checks if `key` exists in `node`.
+  ## Returns `true` if `key` exists in a `JObject <#TJsonNodeKind>`_ `PJsonNode
+  ## <#PJsonNode>`_.
+  ##
+  ## This proc will `assert <system.html#assert>`_ in debug builds if `node` is
+  ## not a ``JObject``. On release builds it will likely crash. Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   let node = %[("age", %40), ("name", %"Britney")]
+  ##   echo node.hasKey("email")
+  ##   # --> false
   assert(node.kind == JObject)
   for k, item in items(node.fields):
     if k == key: return true
 
 proc existsKey*(node: PJsonNode, key: string): bool {.deprecated.} = node.hasKey(key)
-  ## Deprecated for `hasKey`
+  ## Deprecated for `hasKey() <#hasKey>`_.
 
 proc add*(father, child: PJsonNode) = 
-  ## Adds `child` to a JArray node `father`. 
+  ## Adds `child` to a `JArray <#TJsonNodeKind>`_ `PJsonNode <#PJsonNode>`_
+  ## `father` node.
+  ##
+  ## This proc will `assert <system.html#assert>`_ in debug builds if `node` is
+  ## not a ``JArray``. On release builds it will likely crash. Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var node = %[%"Mixing types", %42]
+  ##   node.add(%"is madness")
+  ##   echo node
+  ##   # --> false
   assert father.kind == JArray
   father.elems.add(child)
 
 proc add*(obj: PJsonNode, key: string, val: PJsonNode) = 
-  ## Adds ``(key, val)`` pair to the JObject node `obj`. For speed
-  ## reasons no check for duplicate keys is performed!
-  ## But ``[]=`` performs the check.
+  ## Adds ``(key, val)`` pair to a `JObject <#TJsonNodeKind>`_ `PJsonNode
+  ## <#PJsonNode>`_ `obj` node.
+  ##
+  ## For speed reasons no check for duplicate keys is performed!  But ``[]=``
+  ## performs the check.
+  ##
+  ## This proc will `assert <system.html#assert>`_ in debug builds if `node` is
+  ## not a ``JObject``. On release builds it will likely crash. Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var node = newJObject()
+  ##   node.add("age", newJInt(12))
+  ##   # This is wrong! But we need speed…
+  ##   node.add("age", newJInt(24))
+  ##   echo node
+  ##   # --> { "age": 12,  "age": 24}
   assert obj.kind == JObject
   obj.fields.add((key, val))
 
 proc `[]=`*(obj: PJsonNode, key: string, val: PJsonNode) =
-  ## Sets a field from a `JObject`. Performs a check for duplicate keys.
+  ## Sets a field from a `JObject <#TJsonNodeKind>`_ `PJsonNode
+  ## <#PJsonNode>`_ `obj` node.
+  ##
+  ## Unlike the `add() <#add,PJsonNode,string,PJsonNode>`_ proc this will
+  ## perform a check for duplicate keys and replace existing values.
+  ##
+  ## This proc will `assert <system.html#assert>`_ in debug builds if `node` is
+  ## not a ``JObject``. On release builds it will likely crash. Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var node = newJObject()
+  ##   node["age"] = %12
+  ##   # The new value replaces the previous one.
+  ##   node["age"] = %24
+  ##   echo node
+  ##   # --> { "age": 24}
   assert(obj.kind == JObject)
   for i in 0..obj.fields.len-1:
     if obj.fields[i].key == key: 
@@ -736,6 +1109,18 @@ proc `{}=`*(node: PJsonNode, names: varargs[string], value: PJsonNode) =
 
 proc delete*(obj: PJsonNode, key: string) =
   ## Deletes ``obj[key]`` preserving the order of the other (key, value)-pairs.
+  ##
+  ## If `key` doesn't exist in `obj` ``EInvalidIndex`` will be raised.  This
+  ## proc will `assert <system.html#assert>`_ in debug builds if `node` is not
+  ## a ``JObject``. On release builds it will likely crash. Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var node = %[("age", %37), ("name", %"Chris"), ("male", %false)]
+  ##   echo node
+  ##   # --> { "age": 37,  "name": "Chris",  "male": false}
+  ##   node.delete("age")
+  ##   echo node
+  ##   # --> { "name": "Chris",  "male": false}
   assert(obj.kind == JObject)
   for i in 0..obj.fields.len-1:
     if obj.fields[i].key == key:
@@ -744,7 +1129,9 @@ proc delete*(obj: PJsonNode, key: string) =
   raise newException(EInvalidIndex, "key not in object")
 
 proc copy*(p: PJsonNode): PJsonNode =
-  ## Performs a deep copy of `a`.
+  ## Performs a deep copy of `p`.
+  ##
+  ## Modifications to the copy won't affect the original.
   case p.kind
   of JString:
     result = newJString(p.str)
@@ -779,6 +1166,12 @@ proc nl(s: var string, ml: bool) =
 
 proc escapeJson*(s: string): string = 
   ## Converts a string `s` to its JSON representation.
+  ##
+  ## Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   echo """name: "Torbjørn"""".escapeJson
+  ##   # --> "name: \"Torbj\u00F8rn\""
   result = newStringOfCap(s.len + s.len shr 3)
   result.add("\"")
   for x in runes(s):
@@ -850,24 +1243,58 @@ proc toPretty(result: var string, node: PJsonNode, indent = 2, ml = true,
     result.add("null")
 
 proc pretty*(node: PJsonNode, indent = 2): string =
-  ## Converts `node` to its JSON Representation, with indentation and
-  ## on multiple lines.
+  ## Converts `node` to a pretty JSON representation.
+  ##
+  ## The representation will have indentation use multiple lines. Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   let node = %[("age", %33), ("name", %"Sojin")]
+  ##   echo node
+  ##   # --> { "age": 33,  "name": "Sojin"}
+  ##   echo node.pretty
+  ##   # --> {
+  ##   #       "age": 33,
+  ##   #       "name": "Sojin"
+  ##   #     }
   result = ""
   toPretty(result, node, indent)
 
 proc `$`*(node: PJsonNode): string =
-  ## Converts `node` to its JSON Representation on one line.
+  ## Converts `node` to its JSON representation on one line.
   result = ""
   toPretty(result, node, 1, false)
 
 iterator items*(node: PJsonNode): PJsonNode =
-  ## Iterator for the items of `node`. `node` has to be a JArray.
+  ## Iterator for the items of `node`.
+  ##
+  ## This proc will `assert <system.html#assert>`_ in debug builds if `node` is
+  ## not a `JArray <#TJsonNodeKind>`_. On release builds it will likely crash.
+  ## Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   let numbers = %[%1, %2, %3]
+  ##   for n in numbers.items:
+  ##     echo "Number ", n
+  ##   ## --> Number 1
+  ##   ##     Number 2
+  ##   ##     Number 3
   assert node.kind == JArray
   for i in items(node.elems):
     yield i
 
 iterator pairs*(node: PJsonNode): tuple[key: string, val: PJsonNode] =
-  ## Iterator for the child elements of `node`. `node` has to be a JObject.
+  ## Iterator for the child elements of `node`.
+  ##
+  ## This proc will `assert <system.html#assert>`_ in debug builds if `node` is
+  ## not a `JObject <#TJsonNodeKind>`_. On release builds it will likely crash.
+  ## Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var node = %[("age", %37), ("name", %"Chris")]
+  ##   for key, value in node.pairs:
+  ##     echo "Key: ", key, ", value: ", value
+  ##   # --> Key: age, value: 37
+  ##   #     Key: name, value: "Chris"
   assert node.kind == JObject
   for key, val in items(node.fields):
     yield (key, val)
@@ -926,8 +1353,12 @@ proc parseJson(p: var TJsonParser): PJsonNode =
 
 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.
+    ## Generic convenience proc to parse stream `s` into a `PJsonNode`.
+    ##
+    ## This wraps around `open() <#open>`_ and `next() <#next>`_ to return the
+    ## full JSON DOM. Errors will be raised as exceptions, this requires the
+    ## `filename` parameter to not be ``nil`` to avoid crashes.
+    assert(not isNil(filename))
     var p: TJsonParser
     p.open(s, filename)
     discard getTok(p) # read first token
@@ -936,10 +1367,28 @@ when not defined(js):
 
   proc parseJson*(buffer: string): PJsonNode =
     ## Parses JSON from `buffer`.
+    ##
+    ## Specialized version around `parseJson(PStream, string)
+    ## <#parseJson,PStream,string>`_. Example:
+    ##
+    ## .. code-block:: nimrod
+    ##  let
+    ##    smallJson = """{"test": 1.3, "key2": true}"""
+    ##    jobj = parseJson(smallJson)
+    ##  assert jobj.kind == JObject
+    ##
+    ##  assert jobj["test"].kind == JFloat
+    ##  echo jobj["test"].fnum # --> 1.3
+    ##
+    ##  assert jobj["key2"].kind == JBool
+    ##  echo jobj["key2"].bval # --> true
     result = parseJson(newStringStream(buffer), "input")
 
   proc parseFile*(filename: string): PJsonNode =
     ## Parses `file` into a `PJsonNode`.
+    ##
+    ## Specialized version around `parseJson(PStream, string)
+    ## <#parseJson,PStream,string>`_.
     var stream = newFileStream(filename, fmRead)
     if stream == nil:
       raise newException(EIO, "cannot read from file: " & filename)
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index 8af09114b..0f6a07f13 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -14,7 +14,7 @@
 ## <backends.html#the-javascript-target>`_.
 
 include "system/inclrtl"
-
+import "impure/fenv"
 {.push debugger:off .} # the user does not want to trace a part
                        # of the standard library!
 
@@ -40,17 +40,6 @@ const
                                            ## after the decimal point 
                                            ## for Nimrod's ``float`` type.
 
-type
-  TFloatClass* = enum ## describes the class a floating point value belongs to.
-                      ## This is the type that is returned by `classify`.
-    fcNormal,    ## value is an ordinary nonzero floating point value
-    fcSubnormal, ## value is a subnormal (a very small) floating point value
-    fcZero,      ## value is zero
-    fcNegZero,   ## value is the negative zero
-    fcNan,       ## value is Not-A-Number (NAN)
-    fcInf,       ## value is positive infinity
-    fcNegInf     ## value is negative infinity
-
 proc classify*(x: float): TFloatClass = 
   ## classifies a floating point value. Returns `x`'s class as specified by
   ## `TFloatClass`.
diff --git a/tools/niminst/nsis.tmpl b/tools/niminst/nsis.tmpl
index 14b1e7d77..40e171d41 100644
--- a/tools/niminst/nsis.tmpl
+++ b/tools/niminst/nsis.tmpl
@@ -149,11 +149,6 @@
         CreateShortCut "$DESKTOP\?{c.displayName}.lnk" "$INSTDIR\?{c.name}.exe"
       #end if
 
-      ; Add shortcuts for the documentation
-      #for f in items(c.cat[fcDocStart]):
-        CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\?{splitFile(f).name}.lnk" "$INSTDIR\?{f.toWin}"
-      #end for
-
       ; Write the shortcut to the uninstaller
       CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk" "$INSTDIR\uninstaller.exe"
     !insertmacro MUI_STARTMENU_WRITE_END
@@ -204,15 +199,15 @@
       abort
     ${EndIf}
 
+    ; Shortcuts
     #  if d.len >= 6:
     #    let startMenuEntry = d[5]
     #    let e = splitFile(startMenuEntry).name.capitalize
-      CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\?{e}.lnk" "$INSTDIR\?dir\?{startMenuEntry.toWin}"
-    #  end if
-
-    ; Shortcuts
       !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
+        CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\?{e}.lnk" "$INSTDIR\?dir\?{startMenuEntry.toWin}"
       !insertmacro MUI_STARTMENU_WRITE_END
+    #  end if
+    
     ignore:
   SectionEnd
   #end