summary refs log tree commit diff stats
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/backends.md8
-rw-r--r--doc/grammar.txt2
-rw-r--r--doc/lib.md2
-rw-r--r--doc/manual.md257
-rw-r--r--doc/manual_experimental.md160
-rw-r--r--doc/nep1.md40
-rw-r--r--doc/nimc.md38
-rw-r--r--doc/nimdoc.css9
-rw-r--r--doc/nims.md33
-rw-r--r--doc/tut2.md2
-rw-r--r--doc/tut3.md30
11 files changed, 492 insertions, 89 deletions
diff --git a/doc/backends.md b/doc/backends.md
index 27b654890..9f0c54835 100644
--- a/doc/backends.md
+++ b/doc/backends.md
@@ -250,6 +250,8 @@ which will likely make your program crash at runtime.
 The name `NimMain` can be influenced via the `--nimMainPrefix:prefix` switch.
 Use `--nimMainPrefix:MyLib` and the function to call is named `MyLibNimMain`.
 
+When compiling to static or dynamic libraries, they don't call destructors of global variables as normal Nim programs would do. A C API `NimDestroyGlobals` is provided to call these global destructors.
+
 
 ### Nim invocation example from C
 
@@ -371,11 +373,7 @@ The manual mentions that [Nim strings are implicitly convertible to
 cstrings](manual.html#types-cstring-type) which makes interaction usually
 painless. Most C functions accepting a Nim string converted to a
 `cstring` will likely not need to keep this string around and by the time
-they return the string won't be needed anymore. However, for the rare cases
-where a Nim string has to be preserved and made available to the C backend
-as a `cstring`, you will need to manually prevent the string data
-from being freed with [GC_ref](system.html#GC_ref,string) and [GC_unref](
-system.html#GC_unref,string).
+they return the string won't be needed anymore.
 
 A similar thing happens with C code invoking Nim code which returns a
 `cstring`. Consider the following proc:
diff --git a/doc/grammar.txt b/doc/grammar.txt
index f1484bb0b..51b3e0053 100644
--- a/doc/grammar.txt
+++ b/doc/grammar.txt
@@ -187,7 +187,7 @@ objectCase = 'case' declColonEquals ':'? COMMENT?
 objectPart = IND{>} objectPart^+IND{=} DED
            / objectWhen / objectCase / 'nil' / 'discard' / declColonEquals
 objectDecl = 'object' ('of' typeDesc)? COMMENT? objectPart
-conceptParam = ('var' | 'out')? symbol
+conceptParam = ('var' | 'out' | 'ptr' | 'ref' | 'static' | 'type')? symbol
 conceptDecl = 'concept' conceptParam ^* ',' (pragma)? ('of' typeDesc ^* ',')?
               &IND{>} stmt
 typeDef = identVisDot genericParamList? pragma '=' optInd typeDefValue
diff --git a/doc/lib.md b/doc/lib.md
index a76b29151..1507bbaac 100644
--- a/doc/lib.md
+++ b/doc/lib.md
@@ -578,7 +578,7 @@ Modules for the JavaScript backend
   The wrapper of core JavaScript functions. For most purposes, you should be using
   the `math`, `json`, and `times` stdlib modules instead of this module.
 
-* [jsfetch](jshttp.html)
+* [jsfetch](jsfetch.html)
   Wrapper for `fetch`.
 
 * [jsffi](jsffi.html)
diff --git a/doc/manual.md b/doc/manual.md
index 0e167be04..5c36a0a7b 100644
--- a/doc/manual.md
+++ b/doc/manual.md
@@ -267,7 +267,7 @@ You can also use the [discard statement](#statements-and-expressions-discard-sta
   ```
 
 This was how multiline comments were done before version 0.13.0,
-and it is used to provide specifications to [testament](testament.html#writing-unitests) test framework.
+and it is used to provide specifications to [testament](testament.html#writing-unit-tests) test framework.
 
 
 Identifiers & Keywords
@@ -2619,13 +2619,20 @@ An expression `b` can be assigned to an expression `a` iff `a` is an
 Overload resolution
 ===================
 
-In a call `p(args)` the routine `p` that matches best is selected. If
-multiple routines match equally well, the ambiguity is reported during
-semantic analysis.
+In a call `p(args)` where `p` may refer to more than one
+candidate, it is said to be a symbol choice. Overload resolution will attempt to
+find the best candidate, thus transforming the symbol choice into a resolved symbol.
+The routine `p` that matches best is selected following a series of trials explained below. 
+In order: Catagory matching, Hierarchical Order Comparison, and finally, Complexity Analysis.
 
-Every arg in args needs to match. There are multiple different categories how an
-argument can match. Let `f` be the formal parameter's type and `a` the type
-of the argument.
+If multiple candidates match equally well after all trials have been tested, the ambiguity 
+is reported during semantic analysis.
+
+First Trial: Catagory matching
+--------------------------------
+
+Every arg in `args` needs to match and there are multiple different categories of matches.
+Let `f` be the formal parameter's type and `a` the type of the argument.
 
 1. Exact match: `a` and `f` are of the same type.
 2. Literal match: `a` is an integer literal of value `v`
@@ -2643,16 +2650,16 @@ of the argument.
 6. Conversion match: `a` is convertible to `f`, possibly via a user
    defined `converter`.
 
+Each operand may fall into one of the categories above; the operand's
+highest priority category. The list above is in order or priority.
+If a candidate has more priority matches than all other candidates, it is selected as the
+resolved symbol.
 
-There are two major methods of selecting the best matching candidate, namely
-counting and disambiguation. Counting takes precedence to disambiguation. In counting,
-each parameter is given a category and the number of parameters in each category is counted.
-The categories are listed above and are in order of precedence. For example, if
-a candidate with one exact match is compared to a candidate with multiple generic matches
-and zero exact matches, the candidate with an exact match will win.
+For example, if a candidate with one exact match is compared to a candidate with multiple
+generic matches and zero exact matches, the candidate with an exact match will win.
 
-In the following, `count(p, m)` counts the number of matches of the matching category `m`
-for the routine `p`.
+Below is a pseudocode interpretation of category matching, `count(p, m)` counts the number 
+of matches of the matching category `m` for the routine `p`.
 
 A routine `p` matches better than a routine `q` if the following
 algorithm returns true:
@@ -2669,13 +2676,51 @@ algorithm returns true:
   return "ambiguous"
   ```
 
-When counting is ambiguous, disambiguation begins. Parameters are iterated
-by position and these parameter pairs are compared for their type relation. The general goal
-of this comparison is to determine which parameter is more specific. The types considered are
-not of the inputs from the callsite, but of the competing candidates' parameters.
+Second Trial: Hierarchical Order Comparison
+----------------------------------------------
+
+The hierarchical order of a type is analogous to its relative specificity. Consider the type defined:
+
+```nim
+type A[T] = object
+```
+
+Matching formals for this type include `T`, `object`, `A`, `A[...]` and `A[C]` where `C` is a concrete type, `A[...]`
+is a generic typeclass composition and `T` is an unconstrained generic type variable. This list is in order of 
+specificity with respect to `A` as each subsequent category narrows the set of types that are members of their match set.
+
+In this trail, the formal parameters of candidates are compared in order (1st parameter, 2nd parameter, etc.) to search for
+a candidate that has an unrivaled specificity. If such a formal parameter is found, the candidate it belongs to is chosen 
+as the resolved symbol.
+
+Third Trial: Complexity Analysis
+----------------------------------
+
+A slight clarification: While category matching digests all the formal parameters of a candidate at once (order doesn't matter),
+specificity comparison and complexity analysis operate on each formal parameter at a time. The following
+is the final trial to disambiguate a symbol choice when a pair of formal parameters have the same hierarchical order.
+
+The complexity of a type is essentially its number of modifiers and depth of shape. The definition with the *highest*
+complexity wins. Consider the following types:
+
+```nim
+type
+  A[T] = object
+  B[T, H] = object
+```
+
+Note: The below examples are not exhaustive.
+
+We shall say that:
 
+1. `A[T]` has a higher complexity than `A`
+2. `var A[T]` has a higher complexity than `A[T]`
+3. `A[A[T]]` has a higher complexity than `A[T]`
+4. `B[T, H]` has a higher complexity than `A[T]` (`A` and `B` are not compatible here, but convoluted versions of this exist)
+5. `B[ptr T, H]` has a higher complexity than `B[T, H]`
 
-Some examples:
+Some Examples
+---------------
 
   ```nim
   proc takesInt(x: int) = echo "int"
@@ -2692,7 +2737,6 @@ Some examples:
   ```
 
 
-If this algorithm returns "ambiguous" further disambiguation is performed:
 If the argument `a` matches both the parameter type `f` of `p`
 and `g` of `q` via a subtyping relation, the inheritance depth is taken
 into account:
@@ -2734,6 +2778,23 @@ matches) is preferred:
   gen(ri) # "ref T"
   ```
 
+Type variables match
+----------------------
+
+When overload resolution is considering candidates, the type variable's definition
+is not overlooked as it is used to define the formal parameter's type via variable substitution.
+
+For example:
+```nim
+type A
+proc p[T: A](param: T)
+proc p[T: object](param: T)
+```
+
+These signatures are not ambiguous for a concrete type of `A` even though the formal parameters match ("T" == "T").
+Instead `T` is treated as a variable in that (`T` ?= `T`) depending on the bound type of `T` at the time of
+overload resolution.
+
 
 Overloading based on 'var T'
 --------------------------------------
@@ -3159,6 +3220,15 @@ A const section declares constants whose values are constant expressions:
 
 Once declared, a constant's symbol can be used as a constant expression.
 
+The value part of a constant declaration opens a new scope for each constant,
+so no symbols declared in the constant value are accessible outside of it.
+
+  ```nim
+  const foo = (var a = 1; a)
+  const bar = a # error
+  let baz = a # error
+  ```
+
 See [Constants and Constant Expressions] for details.
 
 Static statement/expression
@@ -3727,9 +3797,6 @@ type conversions to unsigned integers and between unsigned integers. The
 rationale for this is mostly better interoperability with the C Programming
 language when algorithms are ported from C to Nim.
 
-Exception: Values that are converted to an unsigned type at compile time
-are checked so that code like `byte(-1)` does not compile.
-
 **Note**: Historically the operations
 were unchecked and the conversions were sometimes checked but starting with
 the revision 1.0.4 of this document and the language implementation the
@@ -4396,7 +4463,42 @@ as an example:
 Overloading of the subscript operator
 -------------------------------------
 
-The `[]` subscript operator for arrays/openarrays/sequences can be overloaded.
+The `[]` subscript operator for arrays/openarrays/sequences can be overloaded
+for any type (with some exceptions) by defining a routine with the name `[]`.
+
+  ```nim
+  type Foo = object
+    data: seq[int]
+  
+  proc `[]`(foo: Foo, i: int): int =
+    result = foo.data[i]
+  
+  let foo = Foo(data: @[1, 2, 3])
+  echo foo[1] # 2
+  ```
+
+Assignment to subscripts can also be overloaded by naming a routine `[]=`,
+which has precedence over assigning to the result of `[]`.
+
+  ```nim
+  type Foo = object
+    data: seq[int]
+  
+  proc `[]`(foo: Foo, i: int): int =
+    result = foo.data[i]
+  proc `[]=`(foo: var Foo, i: int, val: int) =
+    foo.data[i] = val
+  
+  var foo = Foo(data: @[1, 2, 3])
+  echo foo[1] # 2
+  foo[1] = 5
+  echo foo.data # @[1, 5, 3]
+  echo foo[1] # 5
+  ```
+
+Overloads of the subscript operator cannot be applied to routine or type
+symbols themselves, as this conflicts with the syntax for instantiating
+generic parameters, i.e. `foo[int](1, 2, 3)` or `Foo[int]`.
 
 
 Methods
@@ -4612,7 +4714,6 @@ Closure iterators and inline iterators have some restrictions:
    (but rarely useful) and ends the iteration.
 3. Inline iterators cannot be recursive.
 4. Neither inline nor closure iterators have the special `result` variable.
-5. Closure iterators are not supported by the JS backend.
 
 Iterators that are neither marked `{.closure.}` nor `{.inline.}` explicitly
 default to being inline, but this may change in future versions of the
@@ -5359,6 +5460,8 @@ To override the compiler's side effect analysis a `{.noSideEffect.}`
 **Side effects are usually inferred. The inference for side effects is
 analogous to the inference for exception tracking.**
 
+When the compiler cannot infer side effects, as is the case for imported
+functions, one can annotate them with the `sideEffect` pragma.
 
 GC safety effect
 ----------------
@@ -5424,6 +5527,7 @@ Generics are Nim's means to parametrize procs, iterators or types with
 `type parameters`:idx:. Depending on the context, the brackets are used either to
 introduce type parameters or to instantiate a generic proc, iterator, or type.
 
+
 The following example shows how a generic binary tree can be modeled:
 
   ```nim  test = "nim c $1"
@@ -5801,7 +5905,7 @@ at definition and the context at instantiation are considered:
   echo a == b # works!
   ```
 
-In the example, the generic `==` for tuples (as defined in the system module)
+In the example, the [generic `==` for tuples](system.html#%3D%3D%2CT%2CT_2) (as defined in the system module)
 uses the `==` operators of the tuple's components. However, the `==` for
 the `Index` type is defined *after* the `==` for tuples; yet the example
 compiles as the instantiation takes the currently defined symbols into account
@@ -6153,9 +6257,12 @@ scope is controlled by the `inject`:idx: and `gensym`:idx: pragmas:
 `gensym`'ed symbols are not exposed but `inject`'ed symbols are.
 
 The default for symbols of entity `type`, `var`, `let` and `const`
-is `gensym` and for `proc`, `iterator`, `converter`, `template`,
-`macro` is `inject`. However, if the name of the entity is passed as a
-template parameter, it is an `inject`'ed symbol:
+is `gensym`. For `proc`, `iterator`, `converter`, `template`,
+`macro`, the default is `inject`, but if a `gensym` symbol with the same name
+is defined in the same syntax-level scope, it will be `gensym` by default.
+This can be overriden by marking the routine as `inject`. 
+
+If the name of the entity is passed as a template parameter, it is an `inject`'ed symbol:
 
   ```nim
   template withFile(f, fn, mode: untyped, actions: untyped): untyped =
@@ -6956,25 +7063,47 @@ All identifiers of a module are valid from the point of declaration until
 the end of the module. Identifiers from indirectly dependent modules are *not*
 available. The `system`:idx: module is automatically imported in every module.
 
-If a module imports an identifier by two different modules, each occurrence of
-the identifier has to be qualified unless it is an overloaded procedure or
-iterator in which case the overloading resolution takes place:
+If a module imports the same identifier from two different modules, the
+identifier is considered ambiguous, which can be resolved in the following ways:
+
+* Qualifying the identifier as `module.identifier` resolves ambiguity
+  between modules. (See below for the case that the module name itself
+  is ambiguous.)
+* Calling the identifier as a routine makes overload resolution take place,
+  which resolves ambiguity in the case that one overload matches stronger
+  than the others.
+* Using the identifier in a context where the compiler can infer the type
+  of the identifier resolves ambiguity in the case that one definition
+  matches the type stronger than the others.
 
   ```nim
   # Module A
   var x*: string
+  proc foo*(a: string) =
+    echo "A: ", a
   ```
 
   ```nim
   # Module B
   var x*: int
+  proc foo*(b: int) =
+    echo "B: ", b
   ```
 
   ```nim
   # Module C
   import A, B
+
+  foo("abc") # A: abc
+  foo(123) # B: 123
+  let inferred: proc (x: string) = foo
+  foo("def") # A: def
+
   write(stdout, x) # error: x is ambiguous
   write(stdout, A.x) # no error: qualifier used
+  
+  proc bar(a: int): int = a + 1
+  assert bar(x) == x + 1 # no error: only A.x of type int matches
 
   var x = 4
   write(stdout, x) # not ambiguous: uses the module C's x
@@ -6998,7 +7127,7 @@ proc fb* = echo "buzz"
 import A/C
 import B/C
 
-C.fb() # Error: ambiguous identifier: 'fb'
+C.fb() # Error: ambiguous identifier: 'C'
 ```
 
 
@@ -8553,8 +8682,62 @@ Byref pragma
 The `byref` pragma can be applied to an object or tuple type or a proc param.
 When applied to a type it instructs the compiler to pass the type by reference
 (hidden pointer) to procs. When applied to a param it will take precedence, even
-if the the type was marked as `bycopy`. When using the Cpp backend, params marked
-as byref will translate to cpp references `&`.
+if the the type was marked as `bycopy`. When an `importc` type has a `byref` pragma or
+parameters are marked as `byref` in an `importc` proc, these params translate to pointers.
+When an `importcpp` type has a `byref` pragma, these params translate to
+C++ references `&`.
+
+  ```Nim
+  {.emit: """/*TYPESECTION*/
+  typedef struct {
+    int x;
+  } CStruct;
+  """.}
+
+  {.emit: """
+  #ifdef __cplusplus
+  extern "C"
+  #endif
+  int takesCStruct(CStruct* x) {
+    return x->x;
+  }
+  """.}
+
+  type
+    CStruct {.importc, byref.} = object
+      x: cint
+
+  proc takesCStruct(x: CStruct): cint {.importc.}
+  ```
+
+  or
+
+
+  ```Nim
+  type
+    CStruct {.importc.} = object
+      x: cint
+
+  proc takesCStruct(x {.byref.}: CStruct): cint {.importc.}
+  ```
+
+  ```Nim
+  {.emit: """/*TYPESECTION*/
+  struct CppStruct {
+    int x;
+
+    int takesCppStruct(CppStruct& y) {
+      return x + y.x;
+    }
+  };
+  """.}
+
+  type
+    CppStruct {.importcpp, byref.} = object
+      x: cint
+
+  proc takesCppStruct(x, y: CppStruct): cint {.importcpp.}
+  ```
 
 Varargs pragma
 --------------
@@ -8564,7 +8747,7 @@ after the last specified parameter. Nim string values will be converted to C
 strings automatically:
 
   ```Nim
-  proc printf(formatstr: cstring) {.nodecl, varargs.}
+  proc printf(formatstr: cstring) {.header: "<stdio.h>", varargs.}
 
   printf("hallo %s", "world") # "world" will be passed as C string
   ```
diff --git a/doc/manual_experimental.md b/doc/manual_experimental.md
index d20695933..da51d59ad 100644
--- a/doc/manual_experimental.md
+++ b/doc/manual_experimental.md
@@ -560,12 +560,14 @@ Not nil annotation
 `{.experimental: "notnil".}`.
 
 All types for which `nil` is a valid value can be annotated with the
-`not nil` annotation to exclude `nil` as a valid value:
+`not nil` annotation to exclude `nil` as a valid value. Note that only local
+symbols are checked.
 
   ```nim
   {.experimental: "notnil".}
 
   type
+    TObj = object
     PObject = ref TObj not nil
     TProc = (proc (x, y: int)) not nil
 
@@ -576,8 +578,11 @@ All types for which `nil` is a valid value can be annotated with the
   p(nil)
 
   # and also this:
-  var x: PObject
-  p(x)
+  proc foo =
+    var x: PObject
+    p(x)
+
+  foo()
   ```
 
 The compiler ensures that every code path initializes variables which contain
@@ -2445,7 +2450,7 @@ main()
 
 Will produce: 
 
-```c++
+```cpp
 
 struct Test {
 	Foo foo; 
@@ -2515,3 +2520,150 @@ NimFunctor()(1)
 ```
 Notice we use the overload of `()` to have the same semantics in Nim, but on the `importcpp` we import the functor as a function. 
 This allows to easy interop with functions that accepts for example a `const` operator in its signature. 
+
+
+Injected symbols in generic procs and templates
+===============================================
+
+With the experimental option `openSym`, captured symbols in generic routine and
+template bodies may be replaced by symbols injected locally by templates/macros
+at instantiation time. `bind` may be used to keep the captured symbols over the
+injected ones regardless of enabling the options, but other methods like
+renaming the captured symbols should be used instead so that the code is not
+affected by context changes.
+
+Since this change may affect runtime behavior, the experimental switch
+`openSym` needs to be enabled; and a warning is given in the case where an
+injected symbol would replace a captured symbol not bound by `bind` and
+the experimental switch isn't enabled.
+
+```nim
+const value = "captured"
+template foo(x: int, body: untyped): untyped =
+  let value {.inject.} = "injected"
+  body
+
+proc old[T](): string =
+  foo(123):
+    return value # warning: a new `value` has been injected, use `bind` or turn on `experimental:openSym`
+echo old[int]() # "captured"
+
+template oldTempl(): string =
+  block:
+    foo(123):
+      value # warning: a new `value` has been injected, use `bind` or turn on `experimental:openSym`
+echo oldTempl() # "captured"
+
+{.experimental: "openSym".}
+
+proc bar[T](): string =
+  foo(123):
+    return value
+assert bar[int]() == "injected" # previously it would be "captured"
+
+proc baz[T](): string =
+  bind value
+  foo(123):
+    return value
+assert baz[int]() == "captured"
+
+template barTempl(): string =
+  block:
+    foo(123):
+      value
+assert barTempl() == "injected" # previously it would be "captured"
+
+template bazTempl(): string =
+  bind value
+  block:
+    foo(123):
+      value
+assert bazTempl() == "captured"
+```
+
+This option also generates a new node kind `nnkOpenSym` which contains
+exactly 1 `nnkSym` node. In the future this might be merged with a slightly
+modified `nnkOpenSymChoice` node but macros that want to support the
+experimental feature should still handle `nnkOpenSym`, as the node kind would
+simply not be generated as opposed to being removed.
+
+Another experimental switch `genericsOpenSym` exists that enables this behavior
+at instantiation time, meaning templates etc can enable it specifically when
+they are being called. However this does not generate `nnkOpenSym` nodes
+(unless the other switch is enabled) and so doesn't reflect the regular
+behavior of the switch.
+
+```nim
+const value = "captured"
+template foo(x: int, body: untyped): untyped =
+  let value {.inject.} = "injected"
+  {.push experimental: "genericsOpenSym".}
+  body
+  {.pop.}
+
+proc bar[T](): string =
+  foo(123):
+    return value
+echo bar[int]() # "injected"
+
+template barTempl(): string =
+  block:
+    var res: string
+    foo(123):
+      res = value
+    res
+assert barTempl() == "injected"
+```
+
+
+VTable for methods
+==================
+
+Methods now support implementations based on a VTable by using `--experimental:vtables`. Note that the option needs to enabled
+globally. The virtual method table is stored in the type info of
+an object, which is an array of function pointers.
+
+```nim
+method foo(x: Base, ...) {.base.}
+method foo(x: Derived, ...) {.base.}
+```
+
+It roughly generates a dispatcher like
+
+```nim
+proc foo_dispatch(x: Base, ...) =
+  x.typeinfo.vtable[method_index](x, ...) # method_index is the index of the sorted order of a method
+```
+
+Methods are required to be in the same module where their type has been defined.
+
+```nim
+# types.nim
+type
+  Base* = ref object
+```
+
+```nim
+import types
+
+method foo(x: Base) {.base.} = discard
+```
+
+It gives an error: method `foo` can be defined only in the same module with its type (Base).
+
+
+asmSyntax pragma
+================
+
+The `asmSyntax` pragma is used to specify target inline assembler syntax in an `asm` statement.
+
+It prevents compiling code with different of the target CC inline asm syntax, i.e. it will not allow gcc inline asm code to be compiled with vcc.
+
+```nim
+proc nothing() =
+  asm {.asmSyntax: "gcc".}"""
+    nop
+  """
+```
+
+The current C(C++) backend implementation cannot generate code for gcc and for vcc at the same time. For example, `{.asmSyntax: "vcc".}` with the ICC compiler will not generate code with intel asm syntax, even though ICC can use both gcc-like and vcc-like asm.
diff --git a/doc/nep1.md b/doc/nep1.md
index 0c62e3f9c..3d2a0cef3 100644
--- a/doc/nep1.md
+++ b/doc/nep1.md
@@ -256,36 +256,46 @@ Coding Conventions
 Conventions for multi-line statements and expressions
 -----------------------------------------------------
 
-- Tuples which are longer than one line should indent their parameters to
-  align with the parameters above it.
+- Tuples which are longer than one line should indent their parameters.
 
     ```nim
     type
-      LongTupleA = tuple[wordyTupleMemberOne: int, wordyTupleMemberTwo: string,
-                         wordyTupleMemberThree: float]
+      LongTupleA = tuple[
+        wordyTupleMemberOne: int, wordyTupleMemberTwo: string,
+        wordyTupleMemberThree: float]
     ```
 
 - Similarly, any procedure and procedure type declarations that are longer
-  than one line should do the same thing.
+  than one line should do the same thing. Double indent may be used to
+  distinguish them from the body that follows - this applies to all constructs
+  with a body (if, while, etc).
 
     ```nim
     type
-      EventCallback = proc (timeReceived: Time, errorCode: int, event: Event,
-                            output: var string)
-
-    proc lotsOfArguments(argOne: string, argTwo: int, argThree: float,
-                         argFour: proc(), argFive: bool): int
-                        {.heyLookALongPragma.} =
+      EventCallback = proc(
+        timeReceived: Time, errorCode: int, event: Event,
+        output: var string)
+
+    proc lotsOfArguments(
+        argOne: string, argTwo: int, argThree: float,
+        argFour: proc(), argFive: bool, argSix: int
+    ): GenericType[int, string] {.heyLookALongPragma.} =
+      discard
     ```
 
-- Multi-line procedure calls should continue on the same column as the opening
-  parenthesis (like multi-line procedure declarations).
+- Multi-line procedure calls should continue indented (like multi-line procedure
+  declarations).
 
     ```nim
-    startProcess(nimExecutable, currentDirectory, compilerArguments
-                 environment, processOptions)
+    startProcess(
+      nimExecutable, currentDirectory, compilerArguments
+      environment, processOptions)
     ```
 
+Previous versions of this guide advocated vertical alignment along the opening
+brace / parenthesis - both styles are permissible with a preference for the
+current style in new code.
+
 Miscellaneous
 -------------
 
diff --git a/doc/nimc.md b/doc/nimc.md
index 08bd016e1..38558454b 100644
--- a/doc/nimc.md
+++ b/doc/nimc.md
@@ -481,6 +481,28 @@ They are:
 5. nl_types. No headers for this.
 6. As mmap is not supported, the nimAllocPagesViaMalloc option has to be used.
 
+GPU Compilation
+===============
+
+Compiling for GPU computation can be achieved with `--cc:nvcc` for CUDA with nvcc, or with `--cc:hipcc` for AMD GPUs with HIP. Both compilers require building for C++ with `nim cpp`.
+
+Here's a very simple CUDA kernel example using emit, which can be compiled with `nim cpp --cc:nvcc --define:"useMalloc" hello_kernel.nim` assuming you have the CUDA toolkit installed.
+
+```nim
+{.emit: """
+__global__ void add(int a, int b) {
+  int c;
+  c = a + b;
+}
+""".}
+
+proc main() =
+  {.emit: """
+  add<<<1,1>>>(2,7);
+  """.}
+
+main()
+```
 
 DLL generation
 ==============
@@ -503,9 +525,6 @@ To link against ``nimrtl.dll`` use the command:
   nim c -d:useNimRtl myprog.nim
   ```
 
-**Note**: Currently the creation of ``nimrtl.dll`` with thread support has
-never been tested and is unlikely to work!
-
 
 Additional compilation switches
 ===============================
@@ -552,6 +571,13 @@ Define                   Effect
 `globalSymbols`          Load all `{.dynlib.}` libraries with the `RTLD_GLOBAL`:c:
                          flag on Posix systems to resolve symbols in subsequently
                          loaded libraries.
+`lto`                    Enable link-time optimization in the backend compiler and
+                         linker.
+`lto_incremental`        Enable link-time optimization and additionally enable
+                         incremental linking for compilers that support it.
+                         Currently only clang and vcc.
+`strip`                  Strip debug symbols added by the backend compiler from
+                         the executable.
 ======================   =========================================================
 
 
@@ -677,11 +703,11 @@ additional flags to both the Nim compiler and the C compiler and/or linker
 to optimize the build for size. For example, the following flags can be used
 when targeting a gcc compiler:
 
-`--opt:size --passC:-flto --passL:-flto`:option:
+`--opt:size -d:lto -d:strip`:option:
 
 The `--opt:size`:option: flag instructs Nim to optimize code generation for small
-size (with the help of the C compiler), the `-flto`:option: flags enable link-time
-optimization in the compiler and linker.
+size (with the help of the C compiler), the `-d:lto`:option: flags enable link-time
+optimization in the compiler and linker, the `-d:strip`:option: strips debug symbols.
 
 Check the [Cross-compilation] section for instructions on how to compile the
 program for your target.
diff --git a/doc/nimdoc.css b/doc/nimdoc.css
index a9e4ac9c6..0c399e4c1 100644
--- a/doc/nimdoc.css
+++ b/doc/nimdoc.css
@@ -623,8 +623,8 @@ pre {
 

 table.line-nums-table {

   border-radius: 4px;

-  border: 1px solid #cccccc;

-  background-color: ghostwhite;

+  border: 1px solid var(--border);

+  background-color: var(--secondary-background);

   border-collapse: separate;

   margin-top: 15px;

   margin-bottom: 25px; }

@@ -660,6 +660,9 @@ table {
   border-collapse: collapse;

   border-color: var(--third-background);

   border-spacing: 0;

+}

+

+table:not(.line-nums-table) {

   font-size: 0.9em;

 }

 

@@ -678,7 +681,7 @@ table th.docinfo-name {
   text-align: right;

 }

 

-table tr:hover {

+table:not(.line-nums-table) tr:hover {

   background-color: var(--third-background); }

 

 

diff --git a/doc/nims.md b/doc/nims.md
index 42cc6e124..987cc2096 100644
--- a/doc/nims.md
+++ b/doc/nims.md
@@ -61,43 +61,44 @@ Standard library modules
 
 At least the following standard library modules are available:
 
-* [macros](macros.html)
-* [os](os.html)
-* [strutils](strutils.html)
-* [math](math.html)
-* [distros](distros.html)
-* [sugar](sugar.html)
 * [algorithm](algorithm.html)
 * [base64](base64.html)
 * [bitops](bitops.html)
 * [chains](chains.html)
 * [colors](colors.html)
 * [complex](complex.html)
+* [distros](distros.html)
+* [std/editdistance](editdistance.html)
 * [htmlgen](htmlgen.html)
+* [htmlparser](htmlparser.html)
 * [httpcore](httpcore.html)
+* [json](json.html)
 * [lenientops](lenientops.html)
+* [macros](macros.html)
+* [math](math.html)
 * [options](options.html)
+* [os](os.html)
+* [parsecfg](parsecfg.html)
+* [parsecsv](parsecsv.html)
+* [parsejson](parsejson.html)
+* [parsesql](parsesql.html)
 * [parseutils](parseutils.html)
 * [punycode](punycode.html)
 * [random](random.html)
+* [ropes](ropes.html)
+* [std/setutils](setutils.html)
 * [stats](stats.html)
 * [strformat](strformat.html)
 * [strmisc](strmisc.html)
 * [strscans](strscans.html)
+* [strtabs](strtabs.html)
+* [strutils](strutils.html)
+* [sugar](sugar.html)
 * [unicode](unicode.html)
+* [unidecode](unidecode.html)
 * [uri](uri.html)
-* [std/editdistance](editdistance.html)
 * [std/wordwrap](wordwrap.html)
-* [parsecsv](parsecsv.html)
-* [parsecfg](parsecfg.html)
-* [parsesql](parsesql.html)
 * [xmlparser](xmlparser.html)
-* [htmlparser](htmlparser.html)
-* [ropes](ropes.html)
-* [json](json.html)
-* [parsejson](parsejson.html)
-* [strtabs](strtabs.html)
-* [unidecode](unidecode.html)
 
 In addition to the standard Nim syntax ([system](system.html) module),
 NimScripts support the procs and templates defined in the
diff --git a/doc/tut2.md b/doc/tut2.md
index 4b9049082..1b59288d5 100644
--- a/doc/tut2.md
+++ b/doc/tut2.md
@@ -166,7 +166,7 @@ An example:
   n.strVal = ""
   ```
 
-As can been seen from the example, an advantage to an object hierarchy is that
+As can be seen from the example, an advantage to an object hierarchy is that
 no conversion between different object types is needed. Yet, access to invalid
 object fields raises an exception.
 
diff --git a/doc/tut3.md b/doc/tut3.md
index 67f49c879..3a55d4790 100644
--- a/doc/tut3.md
+++ b/doc/tut3.md
@@ -322,6 +322,36 @@ used to get this output.
     raise newException(AssertionDefect, $a & " != " & $b)
   ```
 
+
+Going further
+-------------
+
+It is possible to create more complex macros by combining different
+`NimNode` symbols with `quote do:` expressions. For example, you may
+use `newStmtList` to build your macro iteratively, and `ident` in cases
+in which you wish to create an identifier from a string, as shown below.
+
+  ```nim
+  import std/macros
+
+  macro createProcedures() =
+    result = newStmtList()
+
+    for i in 0..<10:
+      let name = ident("myProc" & $i)
+      let content = newLit("I am procedure number #" & $i)
+
+      result.add quote do:
+        proc `name`() =
+          echo `content`
+
+  createProcedures()
+  myProc7()
+  ```
+
+The call to `myProc7` will echo `I am procedure number #7`.
+
+
 With Power Comes Responsibility
 -------------------------------