RST backtick refactor (all *.rst except manual.rst and rst_examples.rst) (#17258)

Co-authored-by: quantimnot <quantimnot@users.noreply.github.com>
This commit is contained in:
quantimnot
2021-03-18 23:37:55 -04:00
committed by GitHub
parent 15586c7a7a
commit 83ae70cb54
30 changed files with 1402 additions and 1350 deletions

View File

@@ -1,3 +1,5 @@
.. default-role:: code
=================
API naming design
=================
@@ -18,22 +20,22 @@ been renamed to fit this scheme. The ultimate goal is that the programmer can
------------------- ------------ --------------------------------------
English word To use Notes
------------------- ------------ --------------------------------------
initialize initT ``init`` is used to create a
value type ``T``
new newP ``new`` is used to create a
reference type ``P``
initialize initT `init` is used to create a
value type `T`
new newP `new` is used to create a
reference type `P`
find find should return the position where
something was found; for a bool result
use ``contains``
contains contains often short for ``find() >= 0``
append add use ``add`` instead of ``append``
use `contains`
contains contains often short for `find() >= 0`
append add use `add` instead of `append`
compare cmp should return an int with the
``< 0`` ``== 0`` or ``> 0`` semantics;
for a bool result use ``sameXYZ``
put put, ``[]=`` consider overloading ``[]=`` for put
get get, ``[]`` consider overloading ``[]`` for get;
consider to not use ``get`` as a
prefix: ``len`` instead of ``getLen``
`< 0` `== 0` or `> 0` semantics;
for a bool result use `sameXYZ`
put put, `[]=` consider overloading `[]=` for put
get get, `[]` consider overloading `[]` for get;
consider to not use `get` as a
prefix: `len` instead of `getLen`
length len also used for *number of elements*
size size, len size should refer to a byte size
capacity cap
@@ -44,7 +46,7 @@ delete delete, del del is supposed to be faster than
delete, because it does not keep
the order; delete keeps the order
remove delete, del inconsistent right now
remove-and-return pop ``Table``/``TableRef`` alias to ``take``
remove-and-return pop `Table`/`TableRef` alias to `take`
include incl
exclude excl
command cmd

View File

@@ -1,3 +1,5 @@
.. default-role:: code
================================
Nim Backend Integration
================================
@@ -13,8 +15,8 @@ Introduction
============
The `Nim Compiler User Guide <nimc.html>`_ documents the typical
compiler invocation, using the ``compile`` or ``c`` command to transform a
``.nim`` file into one or more ``.c`` files which are then compiled with the
compiler invocation, using the `compile` or `c` command to transform a
`.nim` file into one or more `.c` files which are then compiled with the
platform's C compiler into a static binary. However, there are other commands
to compile to C++, Objective-C, or JavaScript. This document tries to
concentrate in a single place all the backend and interfacing options.
@@ -23,7 +25,7 @@ The Nim compiler supports mainly two backend families: the C, C++ and
Objective-C targets and the JavaScript target. `The C like targets
<#backends-the-c-like-targets>`_ creates source files that can be compiled
into a library or a final executable. `The JavaScript target
<#backends-the-javascript-target>`_ can generate a ``.js`` file which you
<#backends-the-javascript-target>`_ can generate a `.js` file which you
reference from an HTML file or create a `standalone Node.js program
<http://nodejs.org>`_.
@@ -45,7 +47,7 @@ The commands to compile to either C, C++ or Objective-C are:
//compileToOC, objc compile project to Objective C code
The most significant difference between these commands is that if you look
into the ``nimcache`` directory you will find ``.c``, ``.cpp`` or ``.m``
into the `nimcache` directory you will find `.c`, `.cpp` or `.m`
files, other than that all of them will produce a native binary for your
project. This allows you to take the generated code and place it directly
into a project using any of these languages. Here are some typical command-
@@ -64,17 +66,17 @@ or compiler/linker commands.
The JavaScript target
---------------------
Nim can also generate `JavaScript`:idx: code through the ``js`` command.
Nim can also generate `JavaScript`:idx: code through the `js` command.
Nim targets JavaScript 1.5 which is supported by any widely used browser.
Since JavaScript does not have a portable means to include another module,
Nim just generates a long ``.js`` file.
Nim just generates a long `.js` file.
Features or modules that the JavaScript platform does not support are not
available. This includes:
* manual memory management (``alloc``, etc.)
* casting and other unsafe operations (``cast`` operator, ``zeroMem``, etc.)
* manual memory management (`alloc`, etc.)
* casting and other unsafe operations (`cast` operator, `zeroMem`, etc.)
* file management
* OS-specific operations
* threading, coroutines
@@ -86,14 +88,14 @@ To compensate, the standard library has modules `catered to the JS backend
and more support will come in the future (for instance, Node.js bindings
to get OS info).
To compile a Nim module into a ``.js`` file use the ``js`` command; the
default is a ``.js`` file that is supposed to be referenced in an ``.html``
To compile a Nim module into a `.js` file use the `js` command; the
default is a `.js` file that is supposed to be referenced in an `.html`
file. However, you can also run the code with `nodejs`:idx:
(`<http://nodejs.org>`_)::
nim js -d:nodejs -r examples/hallo.nim
If you experience errors saying that ``globalThis`` is not defined, be
If you experience errors saying that `globalThis` is not defined, be
sure to run a recent version of Node.js (at least 12.0).
@@ -113,7 +115,7 @@ Nim code calling the backend
Nim code can interface with the backend through the `Foreign function
interface <manual.html#foreign-function-interface>`_ mainly through the
`importc pragma <manual.html#foreign-function-interface-importc-pragma>`_.
The ``importc`` pragma is the *generic* way of making backend symbols available
The `importc` pragma is the *generic* way of making backend symbols available
in Nim and is available in all the target backends (JavaScript too). The C++
or Objective-C backends have their respective `ImportCpp
<manual.html#implementation-specific-pragmas-importcpp-pragma>`_ and
@@ -123,7 +125,7 @@ pragmas to call methods from classes.
Whenever you use any of these pragmas you need to integrate native code into
your final binary. In the case of JavaScript this is no problem at all, the
same HTML file which hosts the generated JavaScript will likely provide other
JavaScript functions which you are importing with ``importc``.
JavaScript functions which you are importing with `importc`.
However, for the C like targets you need to link external code either
statically or dynamically. The preferred way of integrating native code is to
@@ -148,7 +150,7 @@ interface.
C invocation example
~~~~~~~~~~~~~~~~~~~~
Create a ``logic.c`` file with the following content:
Create a `logic.c` file with the following content:
.. code-block:: c
int addTwoIntegers(int a, int b)
@@ -156,7 +158,7 @@ Create a ``logic.c`` file with the following content:
return a + b;
}
Create a ``calculator.nim`` file with the following content:
Create a `calculator.nim` file with the following content:
.. code-block:: nim
@@ -166,26 +168,26 @@ Create a ``calculator.nim`` file with the following content:
when isMainModule:
echo addTwoIntegers(3, 7)
With these two files in place, you can run ``nim c -r calculator.nim`` and
the Nim compiler will compile the ``logic.c`` file in addition to
``calculator.nim`` and link both into an executable, which outputs ``10`` when
With these two files in place, you can run `nim c -r calculator.nim` and
the Nim compiler will compile the `logic.c` file in addition to
`calculator.nim` and link both into an executable, which outputs `10` when
run. Another way to link the C file statically and get the same effect would
be to remove the line with the ``compile`` pragma and run the following typical
be to remove the line with the `compile` pragma and run the following typical
Unix commands::
$ gcc -c logic.c
$ ar rvs mylib.a logic.o
$ nim c --passL:mylib.a -r calculator.nim
Just like in this example we pass the path to the ``mylib.a`` library (and we
could as well pass ``logic.o``) we could be passing switches to link any other
Just like in this example we pass the path to the `mylib.a` library (and we
could as well pass `logic.o`) we could be passing switches to link any other
static C library.
JavaScript invocation example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Create a ``host.html`` file with the following content:
Create a `host.html` file with the following content:
.. code-block::
@@ -199,7 +201,7 @@ Create a ``host.html`` file with the following content:
<script type="text/javascript" src="calculator.js"></script>
</body></html>
Create a ``calculator.nim`` file with the following content (or reuse the one
Create a `calculator.nim` file with the following content (or reuse the one
from the previous section):
.. code-block:: nim
@@ -209,9 +211,9 @@ from the previous section):
when isMainModule:
echo addTwoIntegers(3, 7)
Compile the Nim code to JavaScript with ``nim js -o:calculator.js
calculator.nim`` and open ``host.html`` in a browser. If the browser supports
javascript, you should see the value ``10`` in the browser's console. Use the
Compile the Nim code to JavaScript with `nim js -o:calculator.js
calculator.nim` and open `host.html` in a browser. If the browser supports
javascript, you should see the value `10` in the browser's console. Use the
`dom module <dom.html>`_ for specific DOM querying and modification procs
or take a look at `karax <https://github.com/pragmagic/karax>`_ for how to
develop browser-based applications.
@@ -222,29 +224,29 @@ Backend code calling Nim
Backend code can interface with Nim code exposed through the `exportc
pragma <manual.html#foreign-function-interface-exportc-pragma>`_. The
``exportc`` pragma is the *generic* way of making Nim symbols available to
`exportc` pragma is the *generic* way of making Nim symbols available to
the backends. By default, the Nim compiler will mangle all the Nim symbols to
avoid any name collision, so the most significant thing the ``exportc`` pragma
avoid any name collision, so the most significant thing the `exportc` pragma
does is maintain the Nim symbol name, or if specified, use an alternative
symbol for the backend in case the symbol rules don't match.
The JavaScript target doesn't have any further interfacing considerations
since it also has garbage collection, but the C targets require you to
initialize Nim's internals, which is done calling a ``NimMain`` function.
initialize Nim's internals, which is done calling a `NimMain` function.
Also, C code requires you to specify a forward declaration for functions or
the compiler will assume certain types for the return value and parameters
which will likely make your program crash at runtime.
The Nim compiler can generate a C interface header through the ``--header``
The Nim compiler can generate a C interface header through the `--header`
command-line switch. The generated header will contain all the exported
symbols and the ``NimMain`` proc which you need to call before any other
symbols and the `NimMain` proc which you need to call before any other
Nim code.
Nim invocation example from C
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Create a ``fib.nim`` file with the following content:
Create a `fib.nim` file with the following content:
.. code-block:: nim
@@ -254,7 +256,7 @@ Create a ``fib.nim`` file with the following content:
else:
result = fib(a - 1) + fib(a - 2)
Create a ``maths.c`` file with the following content:
Create a `maths.c` file with the following content:
.. code-block:: c
@@ -277,30 +279,30 @@ program::
$ gcc -o m -I$HOME/.cache/nim/fib_d -Ipath/to/nim/lib $HOME/.cache/nim/fib_d/*.c maths.c
The first command runs the Nim compiler with three special options to avoid
generating a ``main()`` function in the generated files, avoid linking the
generating a `main()` function in the generated files, avoid linking the
object files into a final binary, and explicitly generate a header file for C
integration. All the generated files are placed into the ``nimcache``
directory. That's why the next command compiles the ``maths.c`` source plus
all the ``.c`` files from ``nimcache``. In addition to this path, you also
have to tell the C compiler where to find Nim's ``nimbase.h`` header file.
integration. All the generated files are placed into the `nimcache`
directory. That's why the next command compiles the `maths.c` source plus
all the `.c` files from `nimcache`. In addition to this path, you also
have to tell the C compiler where to find Nim's `nimbase.h` header file.
Instead of depending on the generation of the individual ``.c`` files you can
Instead of depending on the generation of the individual `.c` files you can
also ask the Nim compiler to generate a statically linked library::
$ nim c --app:staticLib --noMain --header fib.nim
$ gcc -o m -Inimcache -Ipath/to/nim/lib libfib.nim.a maths.c
The Nim compiler will handle linking the source files generated in the
``nimcache`` directory into the ``libfib.nim.a`` static library, which you can
`nimcache` directory into the `libfib.nim.a` static library, which you can
then link into your C program. Note that these commands are generic and will
vary for each system. For instance, on Linux systems you will likely need to
use ``-ldl`` too to link in required dlopen functionality.
use `-ldl` too to link in required dlopen functionality.
Nim invocation example from JavaScript
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Create a ``mhost.html`` file with the following content:
Create a `mhost.html` file with the following content:
.. code-block::
@@ -311,7 +313,7 @@ Create a ``mhost.html`` file with the following content:
</script>
</body></html>
Create a ``fib.nim`` file with the following content (or reuse the one
Create a `fib.nim` file with the following content (or reuse the one
from the previous section):
.. code-block:: nim
@@ -322,10 +324,10 @@ from the previous section):
else:
result = fib(a - 1) + fib(a - 2)
Compile the Nim code to JavaScript with ``nim js -o:fib.js fib.nim`` and
open ``mhost.html`` in a browser. If the browser supports javascript, you
should see an alert box displaying the text ``Fib for 9 is 34``. As mentioned
earlier, JavaScript doesn't require an initialization call to ``NimMain`` or
Compile the Nim code to JavaScript with `nim js -o:fib.js fib.nim` and
open `mhost.html` in a browser. If the browser supports javascript, you
should see an alert box displaying the text `Fib for 9 is 34`. As mentioned
earlier, JavaScript doesn't require an initialization call to `NimMain` or
a similar function and you can call the exported Nim proc directly.
@@ -335,14 +337,14 @@ Nimcache naming logic
The `nimcache`:idx: directory is generated during compilation and will hold
either temporary or final files depending on your backend target. The default
name for the directory depends on the used backend and on your OS but you can
use the ``--nimcache`` `compiler switch
use the `--nimcache` `compiler switch
<nimc.html#compiler-usage-commandminusline-switches>`_ to change it.
Memory management
=================
In the previous sections, the ``NimMain()`` function reared its head. Since
In the previous sections, the `NimMain()` function reared its head. Since
JavaScript already provides automatic memory management, you can freely pass
objects between the two languages without problems. In C and derivate languages
you need to be careful about what you do and how you share memory. The
@@ -357,15 +359,15 @@ Strings and C strings
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
`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
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>`_.
A similar thing happens with C code invoking Nim code which returns a
``cstring``. Consider the following proc:
`cstring`. Consider the following proc:
.. code-block:: nim
@@ -373,8 +375,8 @@ A similar thing happens with C code invoking Nim code which returns a
result = "Hey there C code! " & $rand(100)
Since Nim's garbage collector is not aware of the C code, once the
``gimme`` proc has finished it can reclaim the memory of the ``cstring``.
However, from a practical standpoint, the C code invoking the ``gimme``
`gimme` proc has finished it can reclaim the memory of the `cstring`.
However, from a practical standpoint, the C code invoking the `gimme`
function directly will be able to use it since Nim's garbage collector has
not had a chance to run *yet*. This gives you enough time to make a copy for
the C side of the program, as calling any further Nim procs *might* trigger
@@ -397,14 +399,14 @@ Again, if you are wrapping a library which *mallocs* and *frees* data
structures, you need to expose the appropriate *free* function to Nim so
you can clean it up. And of course, once cleaned you should avoid accessing it
from Nim (or C for that matter). Typically C data structures have their own
``malloc_structure`` and ``free_structure`` specific functions, so wrapping
`malloc_structure` and `free_structure` specific functions, so wrapping
these for the Nim side should be enough.
Thread coordination
-------------------
When the ``NimMain()`` function is called Nim initializes the garbage
When the `NimMain()` function is called Nim initializes the garbage
collector to the current thread, which is usually the main thread of your
application. If your C code later spawns a different thread and calls Nim
code, the garbage collector will fail to work properly and you will crash.

View File

@@ -1,3 +1,5 @@
.. default-role:: code
==================================
Nim Destructors and Move Semantics
==================================
@@ -16,7 +18,7 @@ not use classical GC algorithms anymore but is based on destructors and
move semantics. The new runtime's advantages are that Nim programs become
oblivious to the involved heap sizes and programs are easier to write to make
effective use of multi-core machines. As a nice bonus, files and sockets and
the like will not require manual ``close`` calls anymore.
the like will not require manual `close` calls anymore.
This document aims to be a precise specification about how
move semantics and destructors work in Nim.
@@ -89,12 +91,12 @@ written as:
Lifetime-tracking hooks
=======================
The memory management for Nim's standard ``string`` and ``seq`` types as
The memory management for Nim's standard `string` and `seq` types as
well as other standard collections is performed via so-called
"Lifetime-tracking hooks", which are particular `type bound operators <manual.html#procedures-type-bound-operators>`_.
There are 3 different hooks for each (generic or concrete) object type ``T`` (``T`` can also be a
``distinct`` type) that are called implicitly by the compiler.
There are 3 different hooks for each (generic or concrete) object type `T` (`T` can also be a
`distinct` type) that are called implicitly by the compiler.
(Note: The word "hook" here does not imply any kind of dynamic binding
or runtime indirections, the implicit calls are statically bound and
@@ -109,14 +111,14 @@ other associated resources. Variables are destroyed via this hook when
they go out of scope or when the routine they were declared in is about
to return.
The prototype of this hook for a type ``T`` needs to be:
The prototype of this hook for a type `T` needs to be:
.. code-block:: nim
proc `=destroy`(x: var T)
The general pattern in ``=destroy`` looks like:
The general pattern in `=destroy` looks like:
.. code-block:: nim
@@ -133,20 +135,20 @@ The general pattern in ``=destroy`` looks like:
A `=sink` hook moves an object around, the resources are stolen from the source
and passed to the destination. It is ensured that the source's destructor does
not free the resources afterward by setting the object to its default value
(the value the object's state started in). Setting an object ``x`` back to its
default value is written as ``wasMoved(x)``. When not provided the compiler
(the value the object's state started in). Setting an object `x` back to its
default value is written as `wasMoved(x)`. When not provided the compiler
is using a combination of `=destroy` and `copyMem` instead. This is efficient
hence users rarely need to implement their own `=sink` operator, it is enough to
provide `=destroy` and `=copy`, compiler will take care of the rest.
The prototype of this hook for a type ``T`` needs to be:
The prototype of this hook for a type `T` needs to be:
.. code-block:: nim
proc `=sink`(dest: var T; source: T)
The general pattern in ``=sink`` looks like:
The general pattern in `=sink` looks like:
.. code-block:: nim
@@ -156,25 +158,25 @@ The general pattern in ``=sink`` looks like:
dest.field = source.field
**Note**: ``=sink`` does not need to check for self-assignments.
**Note**: `=sink` does not need to check for self-assignments.
How self-assignments are handled is explained later in this document.
`=copy` hook
---------------
The ordinary assignment in Nim conceptually copies the values. The ``=copy`` hook
is called for assignments that couldn't be transformed into ``=sink``
The ordinary assignment in Nim conceptually copies the values. The `=copy` hook
is called for assignments that couldn't be transformed into `=sink`
operations.
The prototype of this hook for a type ``T`` needs to be:
The prototype of this hook for a type `T` needs to be:
.. code-block:: nim
proc `=copy`(dest: var T; source: T)
The general pattern in ``=copy`` looks like:
The general pattern in `=copy` looks like:
.. code-block:: nim
@@ -186,48 +188,48 @@ The general pattern in ``=copy`` looks like:
dest.field = duplicateResource(source.field)
The ``=copy`` proc can be marked with the ``{.error.}`` pragma. Then any assignment
The `=copy` proc can be marked with the `{.error.}` pragma. Then any assignment
that otherwise would lead to a copy is prevented at compile-time. This looks like:
.. code-block:: nim
proc `=copy`(dest: var T; source: T) {.error.}
but a custom error message (e.g., ``{.error: "custom error".}``) will not be emitted
by the compiler. Notice that there is no ``=`` before the ``{.error.}`` pragma.
but a custom error message (e.g., `{.error: "custom error".}`) will not be emitted
by the compiler. Notice that there is no `=` before the `{.error.}` pragma.
Move semantics
==============
A "move" can be regarded as an optimized copy operation. If the source of the
copy operation is not used afterward, the copy can be replaced by a move. This
document uses the notation ``lastReadOf(x)`` to describe that ``x`` is not
document uses the notation `lastReadOf(x)` to describe that `x` is not
used afterwards. This property is computed by a static control flow analysis
but can also be enforced by using ``system.move`` explicitly.
but can also be enforced by using `system.move` explicitly.
Swap
====
The need to check for self-assignments and also the need to destroy previous
objects inside ``=copy`` and ``=sink`` is a strong indicator to treat
``system.swap`` as a builtin primitive of its own that simply swaps every
field in the involved objects via ``copyMem`` or a comparable mechanism.
In other words, ``swap(a, b)`` is **not** implemented
as ``let tmp = move(b); b = move(a); a = move(tmp)``.
objects inside `=copy` and `=sink` is a strong indicator to treat
`system.swap` as a builtin primitive of its own that simply swaps every
field in the involved objects via `copyMem` or a comparable mechanism.
In other words, `swap(a, b)` is **not** implemented
as `let tmp = move(b); b = move(a); a = move(tmp)`.
This has further consequences:
* Objects that contain pointers that point to the same object are not supported
by Nim's model. Otherwise swapped objects would end up in an inconsistent state.
* Seqs can use ``realloc`` in the implementation.
* Seqs can use `realloc` in the implementation.
Sink parameters
===============
To move a variable into a collection usually ``sink`` parameters are involved.
A location that is passed to a ``sink`` parameter should not be used afterward.
To move a variable into a collection usually `sink` parameters are involved.
A location that is passed to a `sink` parameter should not be used afterward.
This is ensured by a static analysis over a control flow graph. If it cannot be
proven to be the last usage of the location, a copy is done instead and this
copy is then passed to the sink parameter.
@@ -235,9 +237,9 @@ copy is then passed to the sink parameter.
A sink parameter
*may* be consumed once in the proc's body but doesn't have to be consumed at all.
The reason for this is that signatures
like ``proc put(t: var Table; k: sink Key, v: sink Value)`` should be possible
without any further overloads and ``put`` might not take ownership of ``k`` if
``k`` already exists in the table. Sink parameters enable an affine type system,
like `proc put(t: var Table; k: sink Key, v: sink Value)` should be possible
without any further overloads and `put` might not take ownership of `k` if
`k` already exists in the table. Sink parameters enable an affine type system,
not a linear type system.
The employed static analysis is limited and only concerned with local variables;
@@ -254,7 +256,7 @@ however, object and tuple fields are treated as separate entities:
echo tup[1]
Sometimes it is required to explicitly ``move`` a value into its final position:
Sometimes it is required to explicitly `move` a value into its final position:
.. code-block:: nim
@@ -294,9 +296,9 @@ Rewrite rules
**Note**: There are two different allowed implementation strategies:
1. The produced ``finally`` section can be a single section that is wrapped
1. The produced `finally` section can be a single section that is wrapped
around the complete routine body.
2. The produced ``finally`` section is wrapped around the enclosing scope.
2. The produced `finally` section is wrapped around the enclosing scope.
The current implementation follows strategy (2). This means that resources are
destroyed at the scope exit.
@@ -359,13 +361,13 @@ Object and array construction
=============================
Object and array construction is treated as a function call where the
function has ``sink`` parameters.
function has `sink` parameters.
Destructor removal
==================
``wasMoved(x);`` followed by a `=destroy(x)` operation cancel each other
`wasMoved(x);` followed by a `=destroy(x)` operation cancel each other
out. An implementation is encouraged to exploit this in order to improve
efficiency and code sizes. The current implementation does perform this
optimization.
@@ -374,22 +376,22 @@ optimization.
Self assignments
================
``=sink`` in combination with ``wasMoved`` can handle self-assignments but
`=sink` in combination with `wasMoved` can handle self-assignments but
it's subtle.
The simple case of ``x = x`` cannot be turned
into ``=sink(x, x); wasMoved(x)`` because that would lose ``x``'s value.
The simple case of `x = x` cannot be turned
into `=sink(x, x); wasMoved(x)` because that would lose `x`'s value.
The solution is that simple self-assignments that consist of
- Symbols: ``x = x``
- Field access: ``x.f = x.f``
- Array, sequence or string access with indices known at compile-time: ``x[0] = x[0]``
- Symbols: `x = x`
- Field access: `x.f = x.f`
- Array, sequence or string access with indices known at compile-time: `x[0] = x[0]`
are transformed into an empty statement that does nothing.
The compiler is free to optimize further cases.
The complex case looks like a variant of ``x = f(x)``, we consider
``x = select(rand() < 0.5, x, y)`` here:
The complex case looks like a variant of `x = f(x)`, we consider
`x = select(rand() < 0.5, x, y)` here:
.. code-block:: nim
@@ -450,17 +452,17 @@ self-assignments.
Lent type
=========
``proc p(x: sink T)`` means that the proc ``p`` takes ownership of ``x``.
`proc p(x: sink T)` means that the proc `p` takes ownership of `x`.
To eliminate even more creation/copy <-> destruction pairs, a proc's return
type can be annotated as ``lent T``. This is useful for "getter" accessors
type can be annotated as `lent T`. This is useful for "getter" accessors
that seek to allow an immutable view into a container.
The ``sink`` and ``lent`` annotations allow us to remove most (if not all)
The `sink` and `lent` annotations allow us to remove most (if not all)
superfluous copies and destructions.
``lent T`` is like ``var T`` a hidden pointer. It is proven by the compiler
`lent T` is like `var T` a hidden pointer. It is proven by the compiler
that the pointer does not outlive its origin. No destructor call is injected
for expressions of type ``lent T`` or of type ``var T``.
for expressions of type `lent T` or of type `var T`.
.. code-block:: nim
@@ -494,9 +496,9 @@ for expressions of type ``lent T`` or of type ``var T``.
The .cursor annotation
======================
Under the ``--gc:arc|orc`` modes Nim's `ref` type is implemented via the same runtime
Under the `--gc:arc|orc` modes Nim's `ref` type is implemented via the same runtime
"hooks" and thus via reference counting. This means that cyclic structures cannot be freed
immediately (``--gc:orc`` ships with a cycle collector). With the ``.cursor`` annotation
immediately (`--gc:orc` ships with a cycle collector). With the `.cursor` annotation
one can break up cycles declaratively:
.. code-block:: nim
@@ -510,7 +512,7 @@ But please notice that this is not C++'s weak_ptr, it means the right field is n
involved in the reference counting, it is a raw pointer without runtime checks.
Automatic reference counting also has the disadvantage that it introduces overhead
when iterating over linked structures. The ``.cursor`` annotation can also be used
when iterating over linked structures. The `.cursor` annotation can also be used
to avoid this overhead:
.. code-block:: nim
@@ -521,11 +523,11 @@ to avoid this overhead:
it = it.next
In fact, ``.cursor`` more generally prevents object construction/destruction pairs
In fact, `.cursor` more generally prevents object construction/destruction pairs
and so can also be useful in other contexts. The alternative solution would be to
use raw pointers (``ptr``) instead which is more cumbersome and also more dangerous
for Nim's evolution: Later on, the compiler can try to prove ``.cursor`` annotations
to be safe, but for ``ptr`` the compiler has to remain silent about possible
use raw pointers (`ptr`) instead which is more cumbersome and also more dangerous
for Nim's evolution: Later on, the compiler can try to prove `.cursor` annotations
to be safe, but for `ptr` the compiler has to remain silent about possible
problems.
@@ -556,13 +558,13 @@ indirections:
Hook lifting
============
The hooks of a tuple type ``(A, B, ...)`` are generated by lifting the
hooks of the involved types ``A``, ``B``, ... to the tuple type. In
other words, a copy ``x = y`` is implemented
as ``x[0] = y[0]; x[1] = y[1]; ...``, likewise for ``=sink`` and ``=destroy``.
The hooks of a tuple type `(A, B, ...)` are generated by lifting the
hooks of the involved types `A`, `B`, ... to the tuple type. In
other words, a copy `x = y` is implemented
as `x[0] = y[0]; x[1] = y[1]; ...`, likewise for `=sink` and `=destroy`.
Other value-based compound types like ``object`` and ``array`` are handled
correspondingly. For ``object`` however, the compiler-generated hooks
Other value-based compound types like `object` and `array` are handled
correspondingly. For `object` however, the compiler-generated hooks
can be overridden. This can also be important to use an alternative traversal
of the involved data structure that is more efficient or in order to avoid
deep recursions.
@@ -588,18 +590,18 @@ The ability to override a hook leads to a phase ordering problem:
discard
The solution is to define ``proc `=destroy`[T](f: var Foo[T])`` before
The solution is to define `proc `=destroy`[T](f: var Foo[T])` before
it is used. The compiler generates implicit
hooks for all types in *strategic places* so that an explicitly provided
hook that comes too "late" can be detected reliably. These *strategic places*
have been derived from the rewrite rules and are as follows:
- In the construct ``let/var x = ...`` (var/let binding)
hooks are generated for ``typeof(x)``.
- In ``x = ...`` (assignment) hooks are generated for ``typeof(x)``.
- In ``f(...)`` (function call) hooks are generated for ``typeof(f(...))``.
- For every sink parameter ``x: sink T`` the hooks are generated
for ``typeof(x)``.
- In the construct `let/var x = ...` (var/let binding)
hooks are generated for `typeof(x)`.
- In `x = ...` (assignment) hooks are generated for `typeof(x)`.
- In `f(...)` (function call) hooks are generated for `typeof(f(...))`.
- For every sink parameter `x: sink T` the hooks are generated
for `typeof(x)`.
nodestroy pragma
@@ -645,20 +647,18 @@ Instead the variable simply points to the literal.
The literal is shared between different variables which are pointing to it.
The copy operation is deferred until the first write.
```nim
var x = "abc" # no copy
var y = x # no copy
```
.. code-block:: nim
var x = "abc" # no copy
var y = x # no copy
The string literal "abc" is stored in static memory and not allocated on the heap.
The variable `x` points to the literal and the variable `y` points to the literal too.
There is no copy during assigning operations.
```nim
var x = "abc" # no copy
var y = x # no copy
y[0] = 'h' # copy
```
.. code-block:: nim
var x = "abc" # no copy
var y = x # no copy
y[0] = 'h' # copy
The program above shows when the copy operations happen.
When mutating the variable `y`, the Nim compiler creates a fresh copy of `x`,
@@ -670,37 +670,34 @@ and the variable `y` becomes a mutable string.
Let's look at a silly example demonstrating this behaviour:
```nim
var x = "abc"
var y = x
.. code-block:: nim
var x = "abc"
var y = x
moveMem(addr y[0], addr x[0], 3)
```
moveMem(addr y[0], addr x[0], 3)
The program fails because we need to prepare a fresh copy for the variable `y`.
`prepareMutation` should be called before the address operation.
```nim
var x = "abc"
var y = x
.. code-block:: nim
var x = "abc"
var y = x
prepareMutation(y)
moveMem(addr y[0], addr x[0], 3)
assert y == "abc"
```
prepareMutation(y)
moveMem(addr y[0], addr x[0], 3)
assert y == "abc"
Now `prepareMutation` solves the problem.
It manually creates a fresh copy and makes the variable `y` mutable.
```nim
var x = "abc"
var y = x
.. code-block:: nim
var x = "abc"
var y = x
prepareMutation(y)
moveMem(addr y[0], addr x[0], 3)
moveMem(addr y[0], addr x[0], 3)
moveMem(addr y[0], addr x[0], 3)
assert y == "abc"
```
prepareMutation(y)
moveMem(addr y[0], addr x[0], 3)
moveMem(addr y[0], addr x[0], 3)
moveMem(addr y[0], addr x[0], 3)
assert y == "abc"
No matter how many times `moveMem` is called, the program compiles and runs.

View File

@@ -1,3 +1,5 @@
.. default-role:: code
===================================
Nim DocGen Tools Guide
===================================
@@ -15,7 +17,7 @@ This document describes the `documentation generation tools`:idx: built into
the `Nim compiler <nimc.html>`_, which can generate HTML and JSON output
from input .nim files and projects, as well as HTML and LaTeX from input RST
(reStructuredText) files. The output documentation will include the module
dependencies (``import``), any top-level documentation comments (##), and
dependencies (`import`), any top-level documentation comments (##), and
exported symbols (*), including procedures, types, and variables.
Quick start
@@ -125,12 +127,12 @@ Document Types
HTML
----
The generation of HTML documents is done via the ``doc`` command. This command
The generation of HTML documents is done via the `doc` command. This command
takes either a single .nim file, outputting a single .html file with the same
base filename, or multiple .nim files, outputting multiple .html files and,
optionally, an index file.
The ``doc`` command::
The `doc` command::
nim doc sample
Partial Output::
@@ -146,12 +148,12 @@ compiler.
JSON
----
The generation of JSON documents is done via the ``jsondoc`` command. This command
The generation of JSON documents is done via the `jsondoc` command. This command
takes in a .nim file and outputs a .json file with the same base filename. Note
that this tool is built off of the ``doc`` command (previously ``doc2``), and
that this tool is built off of the `doc` command (previously `doc2`), and
contains the same information.
The ``jsondoc`` command::
The `jsondoc` command::
nim jsondoc sample
Output::
@@ -171,10 +173,10 @@ Output::
]
}
Similarly to the old ``doc`` command, the old ``jsondoc`` command has been
renamed to ``jsondoc0``.
Similarly to the old `doc` command, the old `jsondoc` command has been
renamed to `jsondoc0`.
The ``jsondoc0`` command::
The `jsondoc0` command::
nim jsondoc0 sample
Output::
@@ -190,8 +192,8 @@ Output::
}
]
Note that the ``jsondoc`` command outputs it's JSON without pretty-printing it,
while ``jsondoc0`` outputs pretty-printed JSON.
Note that the `jsondoc` command outputs it's JSON without pretty-printing it,
while `jsondoc0` outputs pretty-printed JSON.
Related Options
===============
@@ -203,7 +205,7 @@ Project switch
nim doc --project filename.nim
This will recursively generate documentation of all nim modules imported
into the input module that belong to the Nimble package that ``filename.nim``
into the input module that belong to the Nimble package that `filename.nim`
belongs to.
@@ -214,13 +216,13 @@ Index switch
nim doc --index:on filename.nim
This will generate an index of all the exported symbols in the input Nim
module, and put it into a neighboring file with the extension of ``.idx``. The
module, and put it into a neighboring file with the extension of `.idx`. The
index file is line-oriented (newlines have to be escaped). Each line
represents a tab-separated record of several columns, the first two mandatory,
the rest optional. See the `Index (idx) file format`_ section for details.
Once index files have been generated for one or more modules, the Nim
compiler command ``buildIndex directory`` can be run to go over all the index
compiler command `buildIndex directory` can be run to go over all the index
files in the specified directory to generate a `theindex.html <theindex.html>`_
file.
@@ -230,28 +232,28 @@ See source switch
::
nim doc --git.url:<url> filename.nim
With the ``git.url`` switch the *See source* hyperlink will appear below each
With the `git.url` switch the *See source* hyperlink will appear below each
documented item in your source code pointing to the implementation of that
item on a GitHub repository.
You can click the link to see the implementation of the item.
The ``git.commit`` switch overrides the hardcoded `devel` branch in config/nimdoc.cfg.
The `git.commit` switch overrides the hardcoded `devel` branch in config/nimdoc.cfg.
This is useful to link to a different branch e.g. `--git.commit:master`,
or to a tag e.g. `--git.commit:1.2.3` or a commit.
Source URLs are generated as `href="${url}/tree/${commit}/${path}#L${line}"` by default and this compatible with GitHub but not with GitLab.
Similarly, ``git.devel`` switch overrides the hardcoded `devel` branch for the `Edit` link which is also useful if you have a different working branch than `devel` e.g. `--git.devel:master`.
Similarly, `git.devel` switch overrides the hardcoded `devel` branch for the `Edit` link which is also useful if you have a different working branch than `devel` e.g. `--git.devel:master`.
Edit URLs are generated as `href="${url}/tree/${devel}/${path}#L${line}"` by default.
You can edit ``config/nimdoc.cfg`` and modify the ``doc.item.seesrc`` value with a hyperlink to your own code repository.
You can edit `config/nimdoc.cfg` and modify the `doc.item.seesrc` value with a hyperlink to your own code repository.
In the case of Nim's own documentation, the ``commit`` value is just a commit
In the case of Nim's own documentation, the `commit` value is just a commit
hash to append to a formatted URL to https://github.com/nim-lang/Nim. The
``tools/nimweb.nim`` helper queries the current git commit hash during the doc
`tools/nimweb.nim` helper queries the current git commit hash during the doc
generation, but since you might be working on an unpublished repository, it
also allows specifying a ``githash`` value in ``web/website.ini`` to force a
also allows specifying a `githash` value in `web/website.ini` to force a
specific commit in the output.
@@ -259,9 +261,9 @@ Other Input Formats
===================
The *Nim compiler* also has support for RST (reStructuredText) files with
the ``rst2html`` and ``rst2tex`` commands. Documents like this one are
the `rst2html` and `rst2tex` commands. Documents like this one are
initially written in a dialect of RST which adds support for nim source code
highlighting with the ``.. code-block:: nim`` prefix. ``code-block`` also
highlighting with the `.. code-block:: nim` prefix. `code-block` also
supports highlighting of C++ and some other c-like languages.
Usage::
@@ -270,17 +272,17 @@ Usage::
Output::
You're reading it!
The ``rst2tex`` command is invoked identically to ``rst2html``, but outputs
The `rst2tex` command is invoked identically to `rst2html`, but outputs
a .tex file instead of .html.
HTML anchor generation
======================
When you run the ``rst2html`` command, all sections in the RST document will
When you run the `rst2html` command, all sections in the RST document will
get an anchor you can hyperlink to. Usually, you can guess the anchor lower
casing the section title and replacing spaces with dashes, and in any case, you
can get it from the table of contents. But when you run the ``doc``
can get it from the table of contents. But when you run the `doc`
command to generate API documentation, some symbol get one or two anchors at
the same time: a numerical identifier, or a plain name plus a complex name.
@@ -312,31 +314,31 @@ suffix may be added depending on the type of the callable:
Callable type Suffix
------------- --------------
proc *empty string*
macro ``.m``
method ``.e``
iterator ``.i``
template ``.t``
converter ``.c``
macro `.m`
method `.e`
iterator `.i`
template `.t`
converter `.c`
------------- --------------
The relationship of type to suffix is made by the proc ``complexName`` in the
``compiler/docgen.nim`` file. Here are some examples of complex names for
The relationship of type to suffix is made by the proc `complexName` in the
`compiler/docgen.nim` file. Here are some examples of complex names for
symbols in the `system module <system.html>`_.
* ``type SomeSignedInt = int | int8 | int16 | int32 | int64`` **=>**
* `type SomeSignedInt = int | int8 | int16 | int32 | int64` **=>**
`#SomeSignedInt <system.html#SomeSignedInt>`_
* ``var globalRaiseHook: proc (e: ref E_Base): bool {.nimcall.}`` **=>**
* `var globalRaiseHook: proc (e: ref E_Base): bool {.nimcall.}` **=>**
`#globalRaiseHook <system.html#globalRaiseHook>`_
* ``const NimVersion = "0.0.0"`` **=>**
* `const NimVersion = "0.0.0"` **=>**
`#NimVersion <system.html#NimVersion>`_
* ``proc getTotalMem(): int {.rtl, raises: [], tags: [].}`` **=>**
* `proc getTotalMem(): int {.rtl, raises: [], tags: [].}` **=>**
`#getTotalMem, <system.html#getTotalMem>`_
* ``proc len[T](x: seq[T]): int {.magic: "LengthSeq", noSideEffect.}`` **=>**
* `proc len[T](x: seq[T]): int {.magic: "LengthSeq", noSideEffect.}` **=>**
`#len,seq[T] <system.html#len,seq[T]>`_
* ``iterator pairs[T](a: seq[T]): tuple[key: int, val: T] {.inline.}`` **=>**
* `iterator pairs[T](a: seq[T]): tuple[key: int, val: T] {.inline.}` **=>**
`#pairs.i,seq[T] <iterators.html#pairs.i,seq[T]>`_
* ``template newException[](exceptn: typedesc; message: string;
parentException: ref Exception = nil): untyped`` **=>**
* `template newException[](exceptn: typedesc; message: string;
parentException: ref Exception = nil): untyped` **=>**
`#newException.t,typedesc,string,ref.Exception
<system.html#newException.t,typedesc,string,ref.Exception>`_
@@ -344,13 +346,13 @@ symbols in the `system module <system.html>`_.
Index (idx) file format
=======================
Files with the ``.idx`` extension are generated when you use the `Index
Files with the `.idx` extension are generated when you use the `Index
switch <#related-options-index-switch>`_ along with commands to generate
documentation from source or text files. You can programmatically generate
indices with the `setIndexTerm()
<rstgen.html#setIndexTerm,RstGenerator,string,string,string,string,string>`_
and `writeIndexFile() <rstgen.html#writeIndexFile,RstGenerator,string>`_ procs.
The purpose of ``idx`` files is to hold the interesting symbols and their HTML
The purpose of `idx` files is to hold the interesting symbols and their HTML
references so they can be later concatenated into a big index file with
`mergeIndexes() <rstgen.html#mergeIndexes,string>`_. This section documents
the file format in detail.
@@ -362,7 +364,7 @@ columns is:
1. Mandatory term being indexed. Terms can include quoting according to
Nim's rules (e.g. \`^\`).
2. Base filename plus anchor hyperlink (e.g. ``algorithm.html#*,int,SortOrder``).
2. Base filename plus anchor hyperlink (e.g. `algorithm.html#*,int,SortOrder`).
3. Optional human-readable string to display as a hyperlink. If the value is not
present or is the empty string, the hyperlink will be rendered
using the term. Prefix whitespace indicates that this entry is
@@ -371,8 +373,8 @@ columns is:
this as a tooltip after hovering a moment over the hyperlink.
The index generation tools try to differentiate between documentation
generated from ``.nim`` files and documentation generated from ``.txt`` or
``.rst`` files. The former are always closely related to source code and
generated from `.nim` files and documentation generated from `.txt` or
`.rst` files. The former are always closely related to source code and
consist mainly of API entries. The latter are generic documents meant for
human reading.
@@ -391,7 +393,7 @@ the index file with their third column having as much prefix spaces as their
level is in the TOC (at least 1 character). The prefix whitespace helps to
filter TOC entries from API or text symbols. This is important because the
amount of spaces is used to replicate the hierarchy for document TOCs in the
final index, and TOC entries found in ``.nim`` files are discarded.
final index, and TOC entries found in `.nim` files are discarded.
Additional resources
@@ -402,8 +404,8 @@ Additional resources
`RST Quick Reference
<http://docutils.sourceforge.net/docs/user/rst/quickref.html>`_
The output for HTML and LaTeX comes from the ``config/nimdoc.cfg`` and
``config/nimdoc.tex.cfg`` configuration files. You can add and modify these
The output for HTML and LaTeX comes from the `config/nimdoc.cfg` and
`config/nimdoc.tex.cfg` configuration files. You can add and modify these
files to your project to change the look of the docgen output.
You can import the `packages/docutils/rstgen module <rstgen.html>`_ in your

View File

@@ -6,7 +6,7 @@ General Guidelines
* See also `nep1<https://nim-lang.github.io/Nim/nep1.html>`_ which should probably be merged here.
* Authors should document anything that is exported; documentation for private
procs can be useful too (visible via ``nim doc --docInternal foo.nim``).
procs can be useful too (visible via `nim doc --docInternal foo.nim`).
* Within documentation, a period (`.`) should follow each sentence (or sentence fragment) in a comment block.
The documentation may be limited to one sentence fragment, but if multiple sentences are within the documentation,
each sentence after the first should be complete and in present tense.
@@ -15,7 +15,7 @@ General Guidelines
and `nim doc` supports it. Likewise with rst files: `nim rst2html` will render those as monospace, and
adding `.. default-role:: code` to an rst file will also make those render as monospace when rendered directly
in tools such as github.
* In nim sources, for links, prefer `[link text](link.html)` to ``` `link text<link.html>`_ ```
* In nim sources, for links, prefer `[link text](link.html)` to `` `link text<link.html>`_ ``
since the syntax is simpler and markdown is more common (likewise, `nim rst2html` also supports it in rst files).
.. code-block:: nim
@@ -28,8 +28,8 @@ General Guidelines
Module-level documentation
--------------------------
Documentation of a module is placed at the top of the module itself. Each line of documentation begins with double hashes (``##``).
Sometimes ``##[ multiline docs containing code ]##`` is preferable, see ``lib/pure/times.nim``.
Documentation of a module is placed at the top of the module itself. Each line of documentation begins with double hashes (`##`).
Sometimes `##[ multiline docs containing code ]##` is preferable, see `lib/pure/times.nim`.
Code samples are encouraged, and should follow the general RST syntax:
.. code-block:: Nim
@@ -80,7 +80,7 @@ Whenever an example of usage would be helpful to the user, you should include on
doAssert addThree(3, 125, 6) == -122
result = x +% y +% z
The command ``nim doc`` will then correctly syntax highlight the Nim code within the documentation.
The command `nim doc` will then correctly syntax highlight the Nim code within the documentation.
Types
-----
@@ -116,8 +116,8 @@ Make sure to place the documentation beside or within the object.
.. code-block:: Nim
type
## Bad: this documentation disappears because it annotates the ``type`` keyword
## above, not ``NamedQueue``.
## Bad: this documentation disappears because it annotates the `type` keyword
## above, not `NamedQueue`.
NamedQueue*[T] = object
name*: string ## This becomes the main documentation for the object, which
## is not what we want.
@@ -127,7 +127,7 @@ Make sure to place the documentation beside or within the object.
Var, Let, and Const
-------------------
When declaring module-wide constants and values, documentation is encouraged. The placement of doc comments is similar to the ``type`` sections.
When declaring module-wide constants and values, documentation is encouraged. The placement of doc comments is similar to the `type` sections.
.. code-block:: Nim
@@ -137,9 +137,9 @@ When declaring module-wide constants and values, documentation is encouraged. Th
[1,2,3],
[2,3,1],
[3,1,2],
] ## Doc comment for ``SpreadArray``.
] ## Doc comment for `SpreadArray`.
Placement of comments in other areas is usually allowed, but will not become part of the documentation output and should therefore be prefaced by a single hash (``#``).
Placement of comments in other areas is usually allowed, but will not become part of the documentation output and should therefore be prefaced by a single hash (`#`).
.. code-block:: Nim

View File

@@ -1,3 +1,5 @@
.. default-role:: code
===================================
DrNim User Guide
===================================
@@ -18,7 +20,7 @@ DrNim's command-line options are the same as the Nim compiler's.
DrNim currently only checks the sections of your code that are marked
via ``staticBoundChecks: on``:
via `staticBoundChecks: on`:
.. code-block:: nim
@@ -31,9 +33,9 @@ overflow errors are *not* prevented. Overflows will be checked for in
the future.
Later versions of the **Nim compiler** will **assume** that the checks inside
the ``staticBoundChecks: on`` environment have been proven correct and so
the `staticBoundChecks: on` environment have been proven correct and so
it will **omit** the runtime checks. If you do not want this behavior, use
instead ``{.push staticBoundChecks: defined(nimDrNim).}``. This way the
instead `{.push staticBoundChecks: defined(nimDrNim).}`. This way the
Nim compiler remains unaware of the performed proofs but DrNim will prove
your code.
@@ -41,7 +43,7 @@ your code.
Installation
============
Run ``koch drnim``, the executable will afterwards be in ``$nim/bin/drnim``.
Run `koch drnim`, the executable will afterwards be in `$nim/bin/drnim`.
Motivating Example
@@ -67,7 +69,7 @@ detects it and produces the following error message::
cannot prove: i <= len(a) + -1; counter example: i -> 0 a.len -> 0 [IndexCheck]
In other words for ``i == 0`` and ``a.len == 0`` (for example!) there would be
In other words for `i == 0` and `a.len == 0` (for example!) there would be
an index out of bounds error.
@@ -82,37 +84,37 @@ DrNim adds 4 additional annotations (pragmas) to Nim:
- `assume`:idx:
These pragmas are ignored by the Nim compiler so that they don't have to
be disabled via ``when defined(nimDrNim)``.
be disabled via `when defined(nimDrNim)`.
Invariant
---------
An ``invariant`` is a proposition that must be true after every loop
An `invariant` is a proposition that must be true after every loop
iteration, it's tied to the loop body it's part of.
Requires
--------
A ``requires`` annotation describes what the function expects to be true
before it's called so that it can perform its operation. A ``requires``
A `requires` annotation describes what the function expects to be true
before it's called so that it can perform its operation. A `requires`
annotation is also called a `precondition`:idx:.
Ensures
-------
An ``ensures`` annotation describes what will be true after the function
call. An ``ensures`` annotation is also called a `postcondition`:idx:.
An `ensures` annotation describes what will be true after the function
call. An `ensures` annotation is also called a `postcondition`:idx:.
Assume
------
An ``assume`` annotation describes what DrNim should **assume** to be true
An `assume` annotation describes what DrNim should **assume** to be true
in this section of the program. It is an unsafe escape mechanism comparable
to Nim's ``cast`` statement. Use it only when you really know better
to Nim's `cast` statement. Use it only when you really know better
than DrNim. You should add a comment to a paper that proves the proposition
you assume.
@@ -143,12 +145,12 @@ Example: insertionSort
Unfortunately, the invariants required to prove that this code is correct take more
code than the imperative instructions. However, this effort can be compensated
by the fact that the result needs very little testing. Be aware though that
DrNim only proves that after ``insertionSort`` this condition holds::
DrNim only proves that after `insertionSort` this condition holds::
forall(i in 1..<a.len, a[i-1] <= a[i])
This is required, but not sufficient to describe that a ``sort`` operation
This is required, but not sufficient to describe that a `sort` operation
was performed. For example, the same postcondition is true for this proc
which doesn't sort at all:
@@ -166,8 +168,8 @@ which doesn't sort at all:
Syntax of propositions
======================
The basic syntax is ``ensures|requires|invariant: <prop>``.
A ``prop`` is either a comparison or a compound::
The basic syntax is `ensures|requires|invariant: <prop>`.
A `prop` is either a comparison or a compound::
prop = nim_bool_expression
| prop 'and' prop
@@ -186,17 +188,17 @@ A ``prop`` is either a comparison or a compound::
quantifier = <new identifier> 'in' nim_iteration_expression
``nim_iteration_expression`` here is an ordinary expression of Nim code
that describes an iteration space, for example ``1..4`` or ``1..<a.len``.
`nim_iteration_expression` here is an ordinary expression of Nim code
that describes an iteration space, for example `1..4` or `1..<a.len`.
``nim_bool_expression`` here is an ordinary expression of Nim code of
type ``bool`` like ``a == 3`` or ``23 > a.len``.
`nim_bool_expression` here is an ordinary expression of Nim code of
type `bool` like `a == 3` or `23 > a.len`.
The supported subset of Nim code that can be used in these expressions
is currently underspecified but ``let`` variables, function parameters
and ``result`` (which represents the function's final result) are amenable
is currently underspecified but `let` variables, function parameters
and `result` (which represents the function's final result) are amenable
for verification. The expressions must not have any side-effects and must
terminate.
The operators ``forall``, ``exists``, ``->``, ``<->`` have to imported
from ``std / logic``.
The operators `forall`, `exists`, `->`, `<->` have to imported
from `std / logic`.

View File

@@ -1,3 +1,5 @@
.. default-role:: code
===================================================
Embedded Stack Trace Profiler (ESTP) User Guide
===================================================
@@ -10,21 +12,21 @@ Nim comes with a platform independent profiler -
the Embedded Stack Trace Profiler (ESTP). The profiler
is *embedded* into your executable. To activate the profiler you need to do:
* compile your program with the ``--profiler:on --stackTrace:on`` command
* compile your program with the `--profiler:on --stackTrace:on` command
line options
* import the ``nimprof`` module
* import the `nimprof` module
* run your program as usual.
You can in fact look at ``nimprof``'s source code to see how to implement
You can in fact look at `nimprof`'s source code to see how to implement
your own profiler.
The setting ``--profiler:on`` defines the conditional symbol ``profiler``.
The setting `--profiler:on` defines the conditional symbol `profiler`.
After your program has finished the profiler will create a
file ``profile_results.txt`` containing the profiling results.
file `profile_results.txt` containing the profiling results.
Since the profiler works by examining stack traces, it's essential that
the option ``--stackTrace:on`` is active! Unfortunately this means that a
the option `--stackTrace:on` is active! Unfortunately this means that a
profiling build is much slower than a release build.
@@ -35,12 +37,12 @@ You can also use ESTP as a memory profiler to see which stack traces allocate
the most memory and thus create the most GC pressure. It may also help to
find memory leaks. To activate the memory profiler you need to do:
* compile your program with the ``--profiler:off --stackTrace:on -d:memProfiler``
command line options. Yes it's ``--profiler:off``.
* import the ``nimprof`` module
* compile your program with the `--profiler:off --stackTrace:on -d:memProfiler`
command line options. Yes it's `--profiler:off`.
* import the `nimprof` module
* run your program as usual.
Define the symbol ``ignoreAllocationSize`` so that only the number of
Define the symbol `ignoreAllocationSize` so that only the number of
allocations is counted and the sizes of the memory allocations do not matter.
@@ -51,7 +53,7 @@ The results file lists stack traces ordered by significance.
The following example file has been generated by profiling the Nim compiler
itself: It shows that in total 5.4% of the runtime has been spent
in ``crcFromRope`` or its children.
in `crcFromRope` or its children.
In general the stack traces show you immediately where the problem is because
the trace acts like an explanation; in traditional profilers you can only find

View File

@@ -1,3 +1,5 @@
.. default-role:: code
===================
Source Code Filters
===================
@@ -8,7 +10,7 @@ A `Source Code Filter (SCF)` transforms the input character stream to an in-mem
output stream before parsing. A filter can be used to provide templating
systems or preprocessors.
To use a filter for a source file the ``#?`` notation is used::
To use a filter for a source file the `#?` notation is used::
#? stdtmpl(subsChar = '$', metaChar = '#')
#proc generateXML(name, age: string): string =
@@ -21,9 +23,9 @@ To use a filter for a source file the ``#?`` notation is used::
As the example shows, passing arguments to a filter can be done
just like an ordinary procedure call with named or positional arguments. The
available parameters depend on the invoked filter. Before version 0.12.0 of
the language ``#!`` was used instead of ``#?``.
the language `#!` was used instead of `#?`.
**Hint:** With ``--hint[codeBegin]:on`` or ``--verbosity:2``
**Hint:** With `--hint[codeBegin]:on` or `--verbosity:2`
(or higher) while compiling or `nim check`, Nim lists the processed code after
each filter application.
@@ -32,8 +34,8 @@ Usage
First, put your SCF code in a separate file with filters specified in the first line.
**Note:** You can name your SCF file with any file extension you want, but the
conventional extension is ``.nimf``
(it used to be ``.tmpl`` but that was too generic, for example preventing github to
conventional extension is `.nimf`
(it used to be `.tmpl` but that was too generic, for example preventing github to
recognize it as Nim source file).
If we use `generateXML` code shown above and call the SCF file `xmlGen.nimf`
@@ -47,7 +49,7 @@ In your `main.nim`:
Pipe operator
=============
Filters can be combined with the ``|`` pipe operator::
Filters can be combined with the `|` pipe operator::
#? strip(startswith="<") | stdtmpl
#proc generateXML(name, age: string): string =
@@ -68,10 +70,10 @@ The replace filter replaces substrings in each line.
Parameters and their defaults:
``sub: string = ""``
`sub: string = ""`
the substring that is searched for
``by: string = ""``
`by: string = ""`
the string the substring is replaced with
@@ -83,14 +85,14 @@ each line.
Parameters and their defaults:
``startswith: string = ""``
`startswith: string = ""`
strip only the lines that start with *startswith* (ignoring leading
whitespace). If empty every line is stripped.
``leading: bool = true``
`leading: bool = true`
strip leading whitespace
``trailing: bool = true``
`trailing: bool = true`
strip trailing whitespace
@@ -99,25 +101,25 @@ StdTmpl filter
The stdtmpl filter provides a simple templating engine for Nim. The
filter uses a line based parser: Lines prefixed with a *meta character*
(default: ``#``) contain Nim code, other lines are verbatim. Because
(default: `#`) contain Nim code, other lines are verbatim. Because
indentation-based parsing is not suited for a templating engine, control flow
statements need ``end X`` delimiters.
statements need `end X` delimiters.
Parameters and their defaults:
``metaChar: char = '#'``
`metaChar: char = '#'`
prefix for a line that contains Nim code
``subsChar: char = '$'``
`subsChar: char = '$'`
prefix for a Nim expression within a template line
``conc: string = " & "``
`conc: string = " & "`
the operation for concatenation
``emit: string = "result.add"``
`emit: string = "result.add"`
the operation to emit a string literal
``toString: string = "$"``
`toString: string = "$"`
the operation that is applied to each expression
Example::
@@ -174,18 +176,18 @@ The filter transforms this into:
Each line that does not start with the meta character (ignoring leading
whitespace) is converted to a string literal that is added to ``result``.
whitespace) is converted to a string literal that is added to `result`.
The substitution character introduces a Nim expression *e* within the
string literal. *e* is converted to a string with the *toString* operation
which defaults to ``$``. For strong type checking, set ``toString`` to the
which defaults to `$`. For strong type checking, set `toString` to the
empty string. *e* must match this PEG pattern::
e <- [a-zA-Z\128-\255][a-zA-Z0-9\128-\255_.]* / '{' x '}'
x <- '{' x+ '}' / [^}]*
To produce a single substitution character it has to be doubled: ``$$``
produces ``$``.
To produce a single substitution character it has to be doubled: `$$`
produces `$`.
The template engine is quite flexible. It is easy to produce a procedure that
writes the template code directly to a file::

View File

@@ -1,3 +1,5 @@
.. default-role:: code
=======================
Nim's Memory Management
=======================
@@ -27,37 +29,37 @@ and how the memory management strategies other than garbage collectors work.
Multi-paradigm Memory Management Strategies
===========================================
To choose the memory management strategy use the ``--gc:`` switch.
To choose the memory management strategy use the `--gc:` switch.
- ``--gc:refc``. This is the default GC. It's a
- `--gc:refc`. This is the default GC. It's a
deferred reference counting based garbage collector
with a simple Mark&Sweep backup GC in order to collect cycles. Heaps are thread-local.
- ``--gc:markAndSweep``. Simple Mark-And-Sweep based garbage collector. Heaps are thread-local.
- ``--gc:boehm``. Boehm based garbage collector, it offers a shared heap.
- ``--gc:go``. Go's garbage collector, useful for interoperability with Go. Offers a shared heap.
- ``--gc:arc``. Plain reference counting with
- `--gc:markAndSweep`. Simple Mark-And-Sweep based garbage collector. Heaps are thread-local.
- `--gc:boehm`. Boehm based garbage collector, it offers a shared heap.
- `--gc:go`. Go's garbage collector, useful for interoperability with Go. Offers a shared heap.
- `--gc:arc`. Plain reference counting with
`move semantic optimizations <destructors.html#move-semantics>`_, offers a shared heap.
It offers deterministic performance for `hard realtime`:idx: systems. Reference cycles
cause memory leaks, beware.
- ``--gc:orc``. Same as ``--gc:arc`` but adds a cycle collector based on "trial deletion".
- `--gc:orc`. Same as `--gc:arc` but adds a cycle collector based on "trial deletion".
Unfortunately, that makes its performance profile hard to reason about so it is less
useful for hard real-time systems.
- ``--gc:none``. No memory management strategy nor a garbage collector. Allocated memory is
simply never freed. You should use ``--gc:arc`` instead.
- `--gc:none`. No memory management strategy nor a garbage collector. Allocated memory is
simply never freed. You should use `--gc:arc` instead.
================== ======== ================= ============== ===================
Memory Management Heap Reference Cycles Stop-The-World Command line switch
================== ======== ================= ============== ===================
RefC Local Cycle Collector No ``--gc:refc``
Mark & Sweep Local Cycle Collector No ``--gc:markAndSweep``
ARC Shared Leak No ``--gc:arc``
ORC Shared Cycle Collector No ``--gc:orc``
Boehm Shared Cycle Collector Yes ``--gc:boehm``
Go Shared Cycle Collector Yes ``--gc:go``
None Manual Manual Manual ``--gc:none``
RefC Local Cycle Collector No `--gc:refc`
Mark & Sweep Local Cycle Collector No `--gc:markAndSweep`
ARC Shared Leak No `--gc:arc`
ORC Shared Cycle Collector No `--gc:orc`
Boehm Shared Cycle Collector Yes `--gc:boehm`
Go Shared Cycle Collector Yes `--gc:go`
None Manual Manual Manual `--gc:none`
================== ======== ================= ============== ===================
JavaScript's garbage collector is used for the `JavaScript and NodeJS
@@ -73,14 +75,14 @@ Cycle collector
---------------
The cycle collector can be en-/disabled independently from the other parts of
the garbage collector with ``GC_enableMarkAndSweep`` and ``GC_disableMarkAndSweep``.
the garbage collector with `GC_enableMarkAndSweep` and `GC_disableMarkAndSweep`.
Soft real-time support
----------------------
To enable real-time support, the symbol `useRealtimeGC`:idx: needs to be
defined via ``--define:useRealtimeGC`` (you can put this into your config
defined via `--define:useRealtimeGC` (you can put this into your config
file as well).
With this switch the garbage collector supports the following operations:
@@ -88,29 +90,29 @@ With this switch the garbage collector supports the following operations:
proc GC_setMaxPause*(maxPauseInUs: int)
proc GC_step*(us: int, strongAdvice = false, stackSize = -1)
The unit of the parameters ``maxPauseInUs`` and ``us`` is microseconds.
The unit of the parameters `maxPauseInUs` and `us` is microseconds.
These two procs are the two modus operandi of the real-time garbage collector:
(1) GC_SetMaxPause Mode
You can call ``GC_SetMaxPause`` at program startup and then each triggered
garbage collector run tries to not take longer than ``maxPause`` time. However, it is
You can call `GC_SetMaxPause` at program startup and then each triggered
garbage collector run tries to not take longer than `maxPause` time. However, it is
possible (and common) that the work is nevertheless not evenly distributed
as each call to ``new`` can trigger the garbage collector and thus take ``maxPause``
as each call to `new` can trigger the garbage collector and thus take `maxPause`
time.
(2) GC_step Mode
This allows the garbage collector to perform some work for up to ``us`` time.
This allows the garbage collector to perform some work for up to `us` time.
This is useful to call in the main loop to ensure the garbage collector can do its work.
To bind all garbage collector activity to a ``GC_step`` call,
deactivate the garbage collector with ``GC_disable`` at program startup.
If ``strongAdvice`` is set to ``true``,
To bind all garbage collector activity to a `GC_step` call,
deactivate the garbage collector with `GC_disable` at program startup.
If `strongAdvice` is set to `true`,
then the garbage collector will be forced to perform the collection cycle.
Otherwise, the garbage collector may decide not to do anything,
if there is not much garbage to collect.
You may also specify the current stack size via ``stackSize`` parameter.
You may also specify the current stack size via `stackSize` parameter.
It can improve performance when you know that there are no unique Nim references
below a certain point on the stack. Make sure the size you specify is greater
than the potential worst-case size.
@@ -130,16 +132,16 @@ Time measurement with garbage collectors
----------------------------------------
The garbage collectors' way of measuring time uses
(see ``lib/system/timers.nim`` for the implementation):
(see `lib/system/timers.nim` for the implementation):
1) ``QueryPerformanceCounter`` and ``QueryPerformanceFrequency`` on Windows.
2) ``mach_absolute_time`` on Mac OS X.
3) ``gettimeofday`` on Posix systems.
1) `QueryPerformanceCounter` and `QueryPerformanceFrequency` on Windows.
2) `mach_absolute_time` on Mac OS X.
3) `gettimeofday` on Posix systems.
As such it supports a resolution of nanoseconds internally; however, the API
uses microseconds for convenience.
Define the symbol ``reportMissedDeadlines`` to make the
Define the symbol `reportMissedDeadlines` to make the
garbage collector output whenever it missed a deadline.
The reporting will be enhanced and supported by the API in later versions of the collector.
@@ -148,9 +150,9 @@ Tweaking the garbage collector
------------------------------
The collector checks whether there is still time left for its work after
every ``workPackage``'th iteration. This is currently set to 100 which means
every `workPackage`'th iteration. This is currently set to 100 which means
that up to 100 objects are traversed and freed before it checks again. Thus
``workPackage`` affects the timing granularity and may need to be tweaked in
`workPackage` affects the timing granularity and may need to be tweaked in
highly specialized environments or for older hardware.
@@ -158,22 +160,22 @@ Keeping track of memory
=======================
If you need to pass around memory allocated by Nim to C, you can use the
procs ``GC_ref`` and ``GC_unref`` to mark objects as referenced to avoid them
procs `GC_ref` and `GC_unref` to mark objects as referenced to avoid them
being freed by the garbage collector.
Other useful procs from `system <system.html>`_ you can use to keep track of memory are:
* ``getTotalMem()`` Returns the amount of total memory managed by the garbage collector.
* ``getOccupiedMem()`` Bytes reserved by the garbage collector and used by objects.
* ``getFreeMem()`` Bytes reserved by the garbage collector and not in use.
* ``GC_getStatistics()`` Garbage collector statistics as a human-readable string.
* `getTotalMem()` Returns the amount of total memory managed by the garbage collector.
* `getOccupiedMem()` Bytes reserved by the garbage collector and used by objects.
* `getFreeMem()` Bytes reserved by the garbage collector and not in use.
* `GC_getStatistics()` Garbage collector statistics as a human-readable string.
These numbers are usually only for the running thread, not for the whole heap,
with the exception of ``--gc:boehm`` and ``--gc:go``.
with the exception of `--gc:boehm` and `--gc:go`.
In addition to ``GC_ref`` and ``GC_unref`` you can avoid the garbage collector by manually
allocating memory with procs like ``alloc``, ``alloc0``, ``allocShared``, ``allocShared0`` or ``allocCStringArray``.
In addition to `GC_ref` and `GC_unref` you can avoid the garbage collector by manually
allocating memory with procs like `alloc`, `alloc0`, `allocShared`, `allocShared0` or `allocCStringArray`.
The garbage collector won't try to free them, you need to call their respective *dealloc* pairs
(``dealloc``, ``deallocShared``, ``deallocCStringArray``, etc)
(`dealloc`, `deallocShared`, `deallocCStringArray`, etc)
when you are done with them or they will leak.
@@ -182,12 +184,12 @@ Heap dump
The heap dump feature is still in its infancy, but it already proved
useful for us, so it might be useful for you. To get a heap dump, compile
with ``-d:nimTypeNames`` and call ``dumpNumberOfInstances`` at a strategic place in your program.
with `-d:nimTypeNames` and call `dumpNumberOfInstances` at a strategic place in your program.
This produces a list of the used types in your program and for every type
the total amount of object instances for this type as well as the total
amount of bytes these instances take up.
The numbers count the number of objects in all garbage collector heaps, they refer to
all running threads, not only to the current thread. (The current thread
would be the thread that calls ``dumpNumberOfInstances``.) This might
would be the thread that calls `dumpNumberOfInstances`.) This might
change in later versions.

View File

@@ -1,3 +1,5 @@
.. default-role:: code
===================================
Hot code reloading
===================================
@@ -19,8 +21,8 @@ so we have to use a helper module where the major logic we want to change
during development resides.
In this example, we use SDL2 to create a window and we reload the logic
code when ``F9`` is pressed. The important lines are marked with ``#***``.
To install SDL2 you can use ``nimble install sdl2``.
code when `F9` is pressed. The important lines are marked with `#***`.
To install SDL2 you can use `nimble install sdl2`.
.. code-block:: nim
@@ -125,7 +127,7 @@ Then recompile the project, but do not restart or quit the mymain.exe program!
nim c --hotcodereloading:on mymain.nim
Now give the ``mymain`` SDL window the focus, press F9, and watch the
Now give the `mymain` SDL window the focus, press F9, and watch the
updated version of the program.
@@ -133,8 +135,8 @@ updated version of the program.
Reloading API
=============
One can use the special event handlers ``beforeCodeReload`` and
``afterCodeReload`` to reset the state of a particular variable or to force
One can use the special event handlers `beforeCodeReload` and
`afterCodeReload` to reset the state of a particular variable or to force
the execution of certain statements:
.. code-block:: Nim
@@ -178,8 +180,8 @@ It's expected that most projects will implement the reloading with a suitable
build-system triggered IPC notification mechanism, but a polling solution is
also possible through the provided `hasAnyModuleChanged()`:idx: API.
In order to access ``beforeCodeReload``, ``afterCodeReload``, ``hasModuleChanged``
or ``hasAnyModuleChanged`` one must import the `hotcodereloading`:idx: module.
In order to access `beforeCodeReload`, `afterCodeReload`, `hasModuleChanged`
or `hasAnyModuleChanged` one must import the `hotcodereloading`:idx: module.
Native code targets
@@ -187,11 +189,11 @@ Native code targets
Native projects using the hot code reloading option will be implicitly
compiled with the `-d:useNimRtl` option and they will depend on both
the ``nimrtl`` library and the ``nimhcr`` library which implements the
hot code reloading run-time. Both libraries can be found in the ``lib``
the `nimrtl` library and the `nimhcr` library which implements the
hot code reloading run-time. Both libraries can be found in the `lib`
folder of Nim and can be compiled into dynamic libraries to satisfy
runtime demands of the example code above. An example of compiling
``nimhcr.nim`` and ``nimrtl.nim`` when the source dir of Nim is installed
`nimhcr.nim` and `nimrtl.nim` when the source dir of Nim is installed
with choosenim follows.
::
@@ -208,16 +210,16 @@ with choosenim follows.
# source directory (.dll for Windows, .so for Unix, .dylib for MacOS)
All modules of the project will be compiled to separate dynamic link
libraries placed in the ``nimcache`` directory. Please note that during
libraries placed in the `nimcache` directory. Please note that during
the execution of the program, the hot code reloading run-time will load
only copies of these libraries in order to not interfere with any newly
issued build commands.
The main module of the program is considered non-reloadable. Please note
that procs from reloadable modules should not appear in the call stack of
program while ``performCodeReload`` is being called. Thus, the main module
program while `performCodeReload` is being called. Thus, the main module
is a suitable place for implementing a program loop capable of calling
``performCodeReload``.
`performCodeReload`.
Please note that reloading won't be possible when any of the type definitions
in the program has been changed. When closure iterators are used (directly or

View File

@@ -1,3 +1,5 @@
.. default-role:: code
================================
Nim IDE Integration Guide
================================
@@ -18,8 +20,8 @@ Note: this is mostly outdated, see instead `nimsuggest <nimsuggest.html>`_
Nim differs from many other compilers in that it is really fast,
and being so fast makes it suited to provide external queries for
text editors about the source code being written. Through the
``idetools`` command of `the compiler <nimc.html>`_, any IDE
can query a ``.nim`` source file and obtain useful information like
`idetools` command of `the compiler <nimc.html>`_, any IDE
can query a `.nim` source file and obtain useful information like
definition of symbols or suggestions for completion.
This document will guide you through the available options. If you
@@ -36,7 +38,7 @@ Specifying the location of the query
------------------------------------
All of the available idetools commands require you to specify a
query location through the ``--track`` or ``--trackDirty`` switches.
query location through the `--track` or `--trackDirty` switches.
The general idetools invocations are::
nim idetools --track:FILE,LINE,COL <switches> proj.nim
@@ -45,35 +47,35 @@ Or::
nim idetools --trackDirty:DIRTY_FILE,FILE,LINE,COL <switches> proj.nim
``proj.nim``
`proj.nim`
This is the main *project* filename. Most of the time you will
pass in the same as **FILE**, but for bigger projects this is
the file which is used as main entry point for the program, the
one which users compile to generate a final binary.
``<switches>``
`<switches>`
This would be any of the other idetools available options, like
``--def`` or ``--suggest`` explained in the following sections.
`--def` or `--suggest` explained in the following sections.
``COL``
`COL`
An integer with the column you are going to query. For the
compiler columns start at zero, so the first column will be
**0** and the last in an 80 column terminal will be **79**.
``LINE``
`LINE`
An integer with the line you are going to query. For the compiler
lines start at **1**.
``FILE``
`FILE`
The file you want to perform the query on. Usually you will
pass in the same value as **proj.nim**.
``DIRTY_FILE``
`DIRTY_FILE`
The **FILE** parameter is enough for static analysis, but IDEs
tend to have *unsaved buffers* where the user may still be in
the middle of typing a line. In such situations the IDE can
save the current contents to a temporary file and then use the
``--trackDirty`` switch.
`--trackDirty` switch.
Dirty files are likely to contain errors and they are usually
compiled partially only to the point needed to service the
@@ -91,7 +93,7 @@ Or::
Definitions
-----------
The ``--def`` idetools switch performs a query about the definition
The `--def` idetools switch performs a query about the definition
of a specific symbol. If available, idetools will answer with the
type, source file, line/column information and other accessory data
if available like a docstring. With this information an IDE can
@@ -112,7 +114,7 @@ can't find any valid symbol matching the position of the query.
Suggestions
-----------
The ``--suggest`` idetools switch performs a query about possible
The `--suggest` idetools switch performs a query about possible
completion symbols at some point in the file. IDEs can easily provide
an autocompletion feature where the IDE scans the current file (and
related ones, if it knows about the language being edited and follows
@@ -134,7 +136,7 @@ Idetools will try to return the suggestions sorted first by scope
Invocation context
------------------
The ``--context`` idetools switch is very similar to the suggestions
The `--context` idetools switch is very similar to the suggestions
switch, but instead of being used after the user has typed a dot
character, this one is meant to be used after the user has typed
an opening brace to start typing parameters.
@@ -143,7 +145,7 @@ an opening brace to start typing parameters.
Symbol usages
-------------
The ``--usages`` idetools switch lists all usages of the symbol at
The `--usages` idetools switch lists all usages of the symbol at
a position. IDEs can use this to find all the places in the file
where the symbol is used and offer the user to rename it in all
places at the same time. Again, a pure string based search and
@@ -207,15 +209,15 @@ Idetools outputs is always returned on single lines separated by
tab characters (``\t``). The values of each column are:
1. Three characters indicating the type of returned answer (e.g.
def for definition, ``sug`` for suggestion, etc).
2. Type of the symbol. This can be ``skProc``, ``skLet``, and just
about any of the enums defined in the module ``compiler/ast.nim``.
def for definition, `sug` for suggestion, etc).
2. Type of the symbol. This can be `skProc`, `skLet`, and just
about any of the enums defined in the module `compiler/ast.nim`.
3. Full qualified path of the symbol. If you are querying a symbol
defined in the ``proj.nim`` file, this would have the form
``proj.symbolName``.
defined in the `proj.nim` file, this would have the form
`proj.symbolName`.
4. Type/signature. For variables and enums this will contain the
type of the symbol, for procs, methods and templates this will
contain the full unique signature (e.g. ``proc (File)``).
contain the full unique signature (e.g. `proc (File)`).
5. Full path to the file containing the symbol.
6. Line where the symbol is located in the file. Lines start to
count at **1**.
@@ -374,8 +376,8 @@ While at the language level a method is differentiated from others
by the parameters and return value, the signature of the method
returned by idetools returns also the pragmas for the method.
Note that at the moment the word ``proc`` is returned for the
signature of the found method instead of the expected ``method``.
Note that at the moment the word `proc` is returned for the
signature of the found method instead of the expected `method`.
This may change in the future.
| **Third column**: module + [n scope nesting] + method name.
@@ -517,7 +519,7 @@ Test suite
==========
To verify that idetools is working properly there are files in the
``tests/caas/`` directory which provide unit testing. If you find
`tests/caas/` directory which provide unit testing. If you find
odd idetools behaviour and are able to reproduce it, you are welcome
to report it as a bug and add a test to the suite to avoid future
regressions.
@@ -533,27 +535,27 @@ run it manually. First you have to compile the tester::
$ cd my/nim/checkout/tests
$ nim c testament/caasdriver.nim
Running the ``caasdriver`` without parameters will attempt to process
Running the `caasdriver` without parameters will attempt to process
all the test cases in all three operation modes. If a test succeeds
nothing will be printed and the process will exit with zero. If any
test fails, the specific line of the test preceding the failure
and the failure itself will be dumped to stdout, along with a final
indicator of the success state and operation mode. You can pass the
parameter ``verbose`` to force all output even on successful tests.
parameter `verbose` to force all output even on successful tests.
The normal operation mode is called ``ProcRun`` and it involves
The normal operation mode is called `ProcRun` and it involves
starting a process for each command or query, similar to running
manually the Nim compiler from the commandline. The ``CaasRun``
mode starts a server process to answer all queries. The ``SymbolProcRun``
manually the Nim compiler from the commandline. The `CaasRun`
mode starts a server process to answer all queries. The `SymbolProcRun`
mode is used by compiler developers. This means that running all
tests involves processing all ``*.txt`` files three times, which
tests involves processing all `*.txt` files three times, which
can be quite time consuming.
If you don't want to run all the test case files you can pass any
substring as a parameter to ``caasdriver``. Only files matching the
substring as a parameter to `caasdriver`. Only files matching the
passed substring will be run. The filtering doesn't use any globbing
metacharacters, it's a plain match. For example, to run only
``*-compile*.txt`` tests in verbose mode::
`*-compile*.txt` tests in verbose mode::
./caasdriver verbose -compile
@@ -561,18 +563,18 @@ metacharacters, it's a plain match. For example, to run only
Test case file format
---------------------
All the ``tests/caas/*.txt`` files encode a session with the compiler:
All the `tests/caas/*.txt` files encode a session with the compiler:
* The first line indicates the main project file.
* Lines starting with ``>`` indicate a command to be sent to the
* Lines starting with `>` indicate a command to be sent to the
compiler and the lines following a command include checks for
expected or forbidden output (``!`` for forbidden).
expected or forbidden output (`!` for forbidden).
* If a line starts with ``#`` it will be ignored completely, so you
* If a line starts with `#` it will be ignored completely, so you
can use that for comments.
* Since some cases are specific to either ``ProcRun`` or ``CaasRun``
* Since some cases are specific to either `ProcRun` or `CaasRun`
modes, you can prefix a line with the mode and the line will be
processed only in that mode.

View File

@@ -1,3 +1,5 @@
.. default-role:: code
=========================================
Internals of the Nim Compiler
=========================================
@@ -19,19 +21,19 @@ The Nim project's directory structure is:
============ ===================================================
Path Purpose
============ ===================================================
``bin`` generated binary files
``build`` generated C code for the installation
``compiler`` the Nim compiler itself; note that this
`bin` generated binary files
`build` generated C code for the installation
`compiler` the Nim compiler itself; note that this
code has been translated from a bootstrapping
version written in Pascal, so the code is **not**
a poster child of good Nim code
``config`` configuration files for Nim
``dist`` additional packages for the distribution
``doc`` the documentation; it is a bunch of
`config` configuration files for Nim
`dist` additional packages for the distribution
`doc` the documentation; it is a bunch of
reStructuredText files
``lib`` the Nim library
``web`` website of Nim; generated by ``nimweb``
from the ``*.txt`` and ``*.nimf`` files
`lib` the Nim library
`web` website of Nim; generated by `nimweb`
from the `*.txt` and `*.nimf` files
============ ===================================================
@@ -53,7 +55,7 @@ And for a debug version compatible with GDB::
nim c koch.nim
./koch boot --debuginfo --linedir:on
The ``koch`` program is Nim's maintenance script. It is a replacement for
The `koch` program is Nim's maintenance script. It is a replacement for
make and shell scripting with the advantage that it is much more portable.
More information about its options can be found in the `koch <koch.html>`_
documentation.
@@ -67,8 +69,8 @@ Coding Guidelines
* Max line length is 80 characters.
* Provide spaces around binary operators if that enhances readability.
* Use a space after a colon, but not before it.
* [deprecated] Start types with a capital ``T``, unless they are
pointers/references which start with ``P``.
* [deprecated] Start types with a capital `T`, unless they are
pointers/references which start with `P`.
See also the `API naming design <apis.html>`_ document.
@@ -81,12 +83,12 @@ portable programming language (within certain limits) and Nim generates
C code, porting the code generator is not necessary.
POSIX-compliant systems on conventional hardware are usually pretty easy to
port: Add the platform to ``platform`` (if it is not already listed there),
port: Add the platform to `platform` (if it is not already listed there),
check that the OS, System modules work and recompile Nim.
The only case where things aren't as easy is when the garbage
collector needs some assembler tweaking to work. The standard
version of the GC uses C's ``setjmp`` function to store all registers
version of the GC uses C's `setjmp` function to store all registers
on the hardware stack. It may be necessary that the new platform needs to
replace this generic code by some assembler code.
@@ -111,7 +113,7 @@ Complex assignments
We already know the type information as a graph in the compiler.
Thus we need to serialize this graph as RTTI for C code generation.
Look at the file ``lib/system/hti.nim`` for more information.
Look at the file `lib/system/hti.nim` for more information.
Rebuilding the compiler
========================
@@ -139,7 +141,7 @@ Debugging the compiler
======================
You can of course use GDB or Visual Studio to debug the
compiler (via ``--debuginfo --lineDir:on``). However, there
compiler (via `--debuginfo --lineDir:on`). However, there
are also lots of procs that aid in debugging:
@@ -170,19 +172,19 @@ These procs may not be imported by a module. You can import them directly for de
from renderer import renderTree
from msgs import `??`
To create a new compiler for each run, use ``koch temp``::
To create a new compiler for each run, use `koch temp`::
./koch temp c /tmp/test.nim
``koch temp`` creates a debug build of the compiler, which is useful
`koch temp` creates a debug build of the compiler, which is useful
to create stacktraces for compiler debugging. See also
`Rebuilding the compiler`_ if you need more control.
Bisecting for regressions
=========================
``koch temp`` returns 125 as the exit code in case the compiler
compilation fails. This exit code tells ``git bisect`` to skip the
`koch temp` returns 125 as the exit code in case the compiler
compilation fails. This exit code tells `git bisect` to skip the
current commit.::
git bisect start bad-commit good-commit
@@ -219,15 +221,15 @@ examples how the AST represents each syntactic structure.
How the RTL is compiled
=======================
The ``system`` module contains the part of the RTL which needs support by
The `system` module contains the part of the RTL which needs support by
compiler magic (and the stuff that needs to be in it because the spec
says so). The C code generator generates the C code for it, just like any other
module. However, calls to some procedures like ``addInt`` are inserted by
the CCG. Therefore the module ``magicsys`` contains a table (``compilerprocs``)
with all symbols that are marked as ``compilerproc``. ``compilerprocs`` are
needed by the code generator. A ``magic`` proc is not the same as a
``compilerproc``: A ``magic`` is a proc that needs compiler magic for its
semantic checking, a ``compilerproc`` is a proc that is used by the code
module. However, calls to some procedures like `addInt` are inserted by
the CCG. Therefore the module `magicsys` contains a table (`compilerprocs`)
with all symbols that are marked as `compilerproc`. `compilerprocs` are
needed by the code generator. A `magic` proc is not the same as a
`compilerproc`: A `magic` is a proc that needs compiler magic for its
semantic checking, a `compilerproc` is a proc that is used by the code
generator.
@@ -254,7 +256,7 @@ This solves the problem without having to special case the logic
that fills the internal seqs which are affected by the pragmas.
In fact, this describes how the AST should be stored in the database,
as a "shallow" tree. Let's assume we compile module ``m`` with the
as a "shallow" tree. Let's assume we compile module `m` with the
following contents:
.. code-block:: nim
@@ -279,21 +281,21 @@ Conceptually this is the AST we store for the module:
static:
echo "static"
The symbol's ``ast`` field is loaded lazily, on demand. This is where most
The symbol's `ast` field is loaded lazily, on demand. This is where most
savings come from, only the shallow outer AST is reconstructed immediately.
It is also important that the replay involves the ``import`` statement so
It is also important that the replay involves the `import` statement so
that dependencies are resolved properly.
Shared global compiletime state
-------------------------------
Nim allows ``.global, compiletime`` variables that can be filled by macro
Nim allows `.global, compiletime` variables that can be filled by macro
invocations across different modules. This feature breaks modularity in a
severe way. Plenty of different solutions have been proposed:
- Restrict the types of global compiletime variables to ``Set[T]`` or
- Restrict the types of global compiletime variables to `Set[T]` or
similar unordered, only-growable collections so that we can track
the module's write effects to these variables and reapply the changes
in a different order.
@@ -306,7 +308,7 @@ severe way. Plenty of different solutions have been proposed:
Since we adopt the "replay the top level statements" idea, the natural
solution to this problem is to emit pseudo top level statements that
reflect the mutations done to the global variable. However, this is
MUCH harder than it sounds, for example ``squeaknim`` uses this
MUCH harder than it sounds, for example `squeaknim` uses this
snippet:
.. code-block:: nim
@@ -314,12 +316,12 @@ snippet:
"\t^self externalCallFailed\C!\C\C")
stCode.add(st & "\C\t\"Generated by NimSqueak\"\C\t" & apicall)
We can "replay" ``stCode.add`` only if the values of ``st``
and ``apicall`` are known. And even then a hash table's ``add`` with its
We can "replay" `stCode.add` only if the values of `st`
and `apicall` are known. And even then a hash table's `add` with its
hashing mechanism is too hard to replay.
In practice, things are worse still, consider ``someGlobal[i][j].add arg``.
We only know the root is ``someGlobal`` but the concrete path to the data
In practice, things are worse still, consider `someGlobal[i][j].add arg`.
We only know the root is `someGlobal` but the concrete path to the data
is unknown as is the value that is added. We could compute a "diff" between
the global states and use that to compute a symbol patchset, but this is
quite some work, expensive to do at runtime (it would need to run after
@@ -342,7 +344,7 @@ an alien API and works with some existing Nimble packages, at least.
On the other hand, in Nim's future I would like to replace the VM
by native code. A diff algorithm wouldn't work for that.
Instead the native code would work with an API like ``put``, ``get``:
Instead the native code would work with an API like `put`, `get`:
.. code-block:: nim
@@ -350,7 +352,7 @@ Instead the native code would work with an API like ``put``, ``get``:
proc cacheGet*(key: string): NimNode
The API should embrace the AST diffing notion: See the
module ``macrocache`` for the final details.
module `macrocache` for the final details.
@@ -382,9 +384,9 @@ too. Type converters fall into this category:
if 1:
echo "ugly, but should work"
If in the above example module ``B`` is re-compiled, but ``A`` is not then
``B`` needs to be aware of ``toBool`` even though ``toBool`` is not referenced
in ``B`` *explicitly*.
If in the above example module `B` is re-compiled, but `A` is not then
`B` needs to be aware of `toBool` even though `toBool` is not referenced
in `B` *explicitly*.
Both the multi method and the type converter problems are solved by the
AST replay implementation.
@@ -395,7 +397,7 @@ Generics
We cache generic instantiations and need to ensure this caching works
well with the incremental compilation feature. Since the cache is
attached to the ``PSym`` datastructure, it should work without any
attached to the `PSym` datastructure, it should work without any
special logic.
@@ -405,22 +407,22 @@ Backend issues
- Init procs must not be "forgotten" to be called.
- Files must not be "forgotten" to be linked.
- Method dispatchers are global.
- DLL loading via ``dlsym`` is global.
- DLL loading via `dlsym` is global.
- Emulated thread vars are global.
However the biggest problem is that dead code elimination breaks modularity!
To see why, consider this scenario: The module ``G`` (for example the huge
To see why, consider this scenario: The module `G` (for example the huge
Gtk2 module...) is compiled with dead code elimination turned on. So none
of ``G``'s procs is generated at all.
of `G`'s procs is generated at all.
Then module ``B`` is compiled that requires ``G.P1``. Ok, no problem,
``G.P1`` is loaded from the symbol file and ``G.c`` now contains ``G.P1``.
Then module `B` is compiled that requires `G.P1`. Ok, no problem,
`G.P1` is loaded from the symbol file and `G.c` now contains `G.P1`.
Then module ``A`` (that depends on ``B`` and ``G``) is compiled and ``B``
and ``G`` are left unchanged. ``A`` requires ``G.P2``.
Then module `A` (that depends on `B` and `G`) is compiled and `B`
and `G` are left unchanged. `A` requires `G.P2`.
So now ``G.c`` MUST contain both ``P1`` and ``P2``, but we haven't even
loaded ``P1`` from the symbol file, nor do we want to because we then quickly
So now `G.c` MUST contain both `P1` and `P2`, but we haven't even
loaded `P1` from the symbol file, nor do we want to because we then quickly
would restore large parts of the whole program.
@@ -428,7 +430,7 @@ Solution
~~~~~~~~
The backend must have some logic so that if the currently processed module
is from the compilation cache, the ``ast`` field is not accessed. Instead
is from the compilation cache, the `ast` field is not accessed. Instead
the generated C(++) for the symbol's body needs to be cached too and
inserted back into the produced C file. This approach seems to deal with
all the outlined problems above.
@@ -444,8 +446,8 @@ in mind:
keeps allocating memory! Thus a stack overflow may happen, hiding the
real issue.
* What seem to be C code generation problems is often a bug resulting from
not producing prototypes, so that some types default to ``cint``. Testing
without the ``-w`` option helps!
not producing prototypes, so that some types default to `cint`. Testing
without the `-w` option helps!
The Garbage Collector
@@ -464,9 +466,9 @@ code generation.
Each cell has a header consisting of a RC and a pointer to its type
descriptor. However the program does not know about these, so they are placed at
negative offsets. In the GC code the type ``PCell`` denotes a pointer
negative offsets. In the GC code the type `PCell` denotes a pointer
decremented by the right offset, so that the header can be accessed easily. It
is extremely important that ``pointer`` is not confused with a ``PCell``
is extremely important that `pointer` is not confused with a `PCell`
as this would lead to a memory corruption.
@@ -474,9 +476,9 @@ The CellSet data structure
--------------------------
The GC depends on an extremely efficient datastructure for storing a
set of pointers - this is called a ``TCellSet`` in the source code.
set of pointers - this is called a `TCellSet` in the source code.
Inserting, deleting and searching are done in constant time. However,
modifying a ``TCellSet`` during traversal leads to undefined behaviour.
modifying a `TCellSet` during traversal leads to undefined behaviour.
.. code-block:: Nim
type
@@ -559,11 +561,11 @@ Code generation for closures is implemented by `lambda lifting`:idx:.
Design
------
A ``closure`` proc var can call ordinary procs of the default Nim calling
A `closure` proc var can call ordinary procs of the default Nim calling
convention. But not the other way round! A closure is implemented as a
``tuple[prc, env]``. ``env`` can be nil implying a call without a closure.
This means that a call through a closure generates an ``if`` but the
interoperability is worth the cost of the ``if``. Thunk generation would be
`tuple[prc, env]`. `env` can be nil implying a call without a closure.
This means that a call through a closure generates an `if` but the
interoperability is worth the cost of the `if`. Thunk generation would be
possible too, but it's slightly more effort to implement.
Tests with GCC on Amd64 showed that it's really beneficial if the
@@ -579,7 +581,7 @@ A thunk would need to call 'returnsDefaultCC[i]' somehow and that would require
an *additional* closure generation... Ok, not really, but it requires to pass
the function to call. So we'd end up with 2 indirect calls instead of one.
Another much more severe problem which this solution is that it's not GC-safe
to pass a proc pointer around via a generic ``ref`` type.
to pass a proc pointer around via a generic `ref` type.
Example code:
@@ -695,15 +697,15 @@ Accumulator
Internals
---------
Lambda lifting is implemented as part of the ``transf`` pass. The ``transf``
Lambda lifting is implemented as part of the `transf` pass. The `transf`
pass generates code to setup the environment and to pass it around. However,
this pass does not change the types! So we have some kind of mismatch here; on
the one hand the proc expression becomes an explicit tuple, on the other hand
the tyProc(ccClosure) type is not changed. For C code generation it's also
important the hidden formal param is ``void*`` and not something more
important the hidden formal param is `void*` and not something more
specialized. However the more specialized env type needs to passed to the
backend somehow. We deal with this by modifying ``s.ast[paramPos]`` to contain
the formal hidden parameter, but not ``s.typ``!
backend somehow. We deal with this by modifying `s.ast[paramPos]` to contain
the formal hidden parameter, but not `s.typ`!
Integer literals:

View File

@@ -1,3 +1,5 @@
.. default-role:: code
===============================
Nim maintenance script
===============================
@@ -17,7 +19,7 @@ Introduction
The `koch`:idx: program is Nim's maintenance script. It is a replacement
for make and shell scripting with the advantage that it is much more portable.
The word *koch* means *cook* in German. ``koch`` is used mainly to build the
The word *koch* means *cook* in German. `koch` is used mainly to build the
Nim compiler, but it can also be used for other tasks. This document
describes the supported commands and their options.
@@ -39,8 +41,8 @@ options:
Use the linenoise library for interactive mode (not needed on Windows).
After compilation is finished you will hopefully end up with the nim
compiler in the ``bin`` directory. You can add Nim's ``bin`` directory to
your ``$PATH`` or use the install command to place it where it will be
compiler in the `bin` directory. You can add Nim's `bin` directory to
your `$PATH` or use the install command to place it where it will be
found.
csource command
@@ -54,33 +56,33 @@ temp command
------------
The temp command builds the Nim compiler but with a different final name
(``nim_temp``), so it doesn't overwrite your normal compiler. You can use
(`nim_temp`), so it doesn't overwrite your normal compiler. You can use
this command to test different options, the same you would issue for the `boot
command <#commands-boot-command>`_.
test command
------------
The `test`:idx: command can also be invoked with the alias ``tests``. This
command will compile and run ``testament/tester.nim``, which is the main
driver of Nim's test suite. You can pass options to the ``test`` command,
The `test`:idx: command can also be invoked with the alias `tests`. This
command will compile and run `testament/tester.nim`, which is the main
driver of Nim's test suite. You can pass options to the `test` command,
they will be forwarded to the tester. See its source code for available
options.
web command
-----------
The `web`:idx: command converts the documentation in the ``doc`` directory
The `web`:idx: command converts the documentation in the `doc` directory
from rst to HTML. It also repeats the same operation but places the result in
the ``web/upload`` which can be used to update the website at
the `web/upload` which can be used to update the website at
https://nim-lang.org.
By default, the documentation will be built in parallel using the number of
available CPU cores. If any documentation build sub-commands fail, they will
be rerun in serial fashion so that meaningful error output can be gathered for
inspection. The ``--parallelBuild:n`` switch or configuration option can be
inspection. The `--parallelBuild:n` switch or configuration option can be
used to force a specific number of parallel jobs or run everything serially
from the start (``n == 1``).
from the start (`n == 1`).
pdf command
-----------

View File

@@ -1,3 +1,5 @@
.. default-role:: code
====================
Nim Standard Library
====================
@@ -9,7 +11,7 @@ Nim Standard Library
Nim's library is divided into *pure libraries*, *impure libraries*, and *wrappers*.
Pure libraries do not depend on any external ``*.dll`` or ``lib*.so`` binary
Pure libraries do not depend on any external `*.dll` or `lib*.so` binary
while impure libraries do. A wrapper is an impure library that is a very
low-level interface to a C library.
@@ -37,11 +39,11 @@ Automatic imports
* `threads <threads.html>`_
Basic Nim thread support. **Note:** This is part of the system module. Do not
import it explicitly. Enabled with ``--threads:on``.
import it explicitly. Enabled with `--threads:on`.
* `channels <channels_builtin.html>`_
Nim message passing support for threads. **Note:** This is part of the
system module. Do not import it explicitly. Enabled with ``--threads:on``.
system module. Do not import it explicitly. Enabled with `--threads:on`.
Core
@@ -86,14 +88,14 @@ Algorithms
This module implements some common generic algorithms like sort or binary search.
* `std/enumutils <enumutils.html>`_
This module adds functionality for the built-in ``enum`` type.
This module adds functionality for the built-in `enum` type.
* `sequtils <sequtils.html>`_
This module implements operations for the built-in ``seq`` type
This module implements operations for the built-in `seq` type
which were inspired by functional programming languages.
* `std/setutils <setutils.html>`_
This module adds functionality for the built-in ``set`` type.
This module adds functionality for the built-in `set` type.
Collections
@@ -105,7 +107,7 @@ Collections
* `deques <deques.html>`_
Implementation of a double-ended queue.
The underlying implementation uses a ``seq``.
The underlying implementation uses a `seq`.
* `heapqueue <heapqueue.html>`_
Implementation of a heap data structure that can be used as a priority queue.
@@ -140,7 +142,7 @@ String handling
---------------
* `cstrutils <cstrutils.html>`_
Utilities for ``cstring`` handling.
Utilities for `cstring` handling.
* `std/editdistance <editdistance.html>`_
This module contains an algorithm to compute the edit distance between two
@@ -148,7 +150,7 @@ String handling
* `encodings <encodings.html>`_
Converts between different character encodings. On UNIX, this uses
the ``iconv`` library, on Windows the Windows API.
the `iconv` library, on Windows the Windows API.
* `parseutils <parseutils.html>`_
This module contains helpers for parsing tokens, numbers, identifiers, etc.
@@ -166,17 +168,17 @@ String handling
* `strformat <strformat.html>`_
Macro based standard string interpolation/formatting. Inspired by
Python's ``f``-strings.
Python's `f`-strings.
* `strmisc <strmisc.html>`_
This module contains uncommon string handling operations that do not
fit with the commonly used operations in strutils.
* `strscans <strscans.html>`_
This module contains a ``scanf`` macro for convenient parsing of mini languages.
This module contains a `scanf` macro for convenient parsing of mini languages.
* `strtabs <strtabs.html>`_
The ``strtabs`` module implements an efficient hash table that is a mapping
The `strtabs` module implements an efficient hash table that is a mapping
from strings to strings. Supports a case-sensitive, case-insensitive and
style-insensitive modes.
@@ -200,10 +202,10 @@ Time handling
-------------
* `std/monotimes <monotimes.html>`_
The ``monotimes`` module implements monotonic timestamps.
The `monotimes` module implements monotonic timestamps.
* `times <times.html>`_
The ``times`` module contains support for working with time.
The `times` module contains support for working with time.
Generic Operating System Services
@@ -225,7 +227,7 @@ Generic Operating System Services
data structures.
* `memfiles <memfiles.html>`_
This module provides support for memory-mapped files (Posix's ``mmap``)
This module provides support for memory-mapped files (Posix's `mmap`)
on the different operating systems.
* `os <os.html>`_
@@ -234,12 +236,12 @@ Generic Operating System Services
commands, etc.
* `osproc <osproc.html>`_
Module for process communication beyond ``os.execShellCmd``.
Module for process communication beyond `os.execShellCmd`.
* `streams <streams.html>`_
This module provides a stream interface and two implementations thereof:
the ``FileStream`` and the ``StringStream`` which implement the stream
interface for Nim file objects (``File``) and strings. Other modules
the `FileStream` and the `StringStream` which implement the stream
interface for Nim file objects (`File`) and strings. Other modules
may provide other implementations for this standard stream interface.
* `terminal <terminal.html>`_
@@ -288,22 +290,22 @@ Internet Protocols and Support
* `asyncfile <asyncfile.html>`_
This module implements asynchronous file reading and writing using
``asyncdispatch``.
`asyncdispatch`.
* `asyncftpclient <asyncftpclient.html>`_
This module implements an asynchronous FTP client using the ``asyncnet``
This module implements an asynchronous FTP client using the `asyncnet`
module.
* `asynchttpserver <asynchttpserver.html>`_
This module implements an asynchronous HTTP server using the ``asyncnet``
This module implements an asynchronous HTTP server using the `asyncnet`
module.
* `asyncnet <asyncnet.html>`_
This module implements asynchronous sockets based on the ``asyncdispatch``
This module implements asynchronous sockets based on the `asyncdispatch`
module.
* `asyncstreams <asyncstreams.html>`_
This module provides ``FutureStream`` - a future that acts as a queue.
This module provides `FutureStream` - a future that acts as a queue.
* `cgi <cgi.html>`_
This module implements helpers for CGI applications.
@@ -323,7 +325,7 @@ Internet Protocols and Support
* `net <net.html>`_
This module implements a high-level sockets API. It replaces the
``sockets`` module.
`sockets` module.
* `selectors <selectors.html>`_
This module implements a selector API with backends specific to each OS.
@@ -357,23 +359,23 @@ Parsers
scheme for lexers and parsers. This is used by the diverse parsing modules.
* `parsecfg <parsecfg.html>`_
The ``parsecfg`` module implements a high-performance configuration file
parser. The configuration file's syntax is similar to the Windows ``.ini``
The `parsecfg` module implements a high-performance configuration file
parser. The configuration file's syntax is similar to the Windows `.ini`
format, but much more powerful, as it is not a line based parser. String
literals, raw string literals, and triple quote string literals are supported
as in the Nim programming language.
* `parsecsv <parsecsv.html>`_
The ``parsecsv`` module implements a simple high-performance CSV parser.
The `parsecsv` module implements a simple high-performance CSV parser.
* `parseopt <parseopt.html>`_
The ``parseopt`` module implements a command line option parser.
The `parseopt` module implements a command line option parser.
* `parsesql <parsesql.html>`_
The ``parsesql`` module implements a simple high-performance SQL parser.
The `parsesql` module implements a simple high-performance SQL parser.
* `parsexml <parsexml.html>`_
The ``parsexml`` module implements a simple high performance XML/HTML parser.
The `parsexml` module implements a simple high performance XML/HTML parser.
The only encoding that is supported is UTF-8. The parser has been designed
to be somewhat error-correcting, so that even some "wild HTML" found on the
web can be parsed with it.
@@ -458,7 +460,7 @@ Miscellaneous
This module implements a simple logger.
* `segfaults <segfaults.html>`_
Turns access violations or segfaults into a ``NilAccessDefect`` exception.
Turns access violations or segfaults into a `NilAccessDefect` exception.
* `sugar <sugar.html>`_
This module implements nice syntactic sugar based on Nim's macro system.
@@ -480,11 +482,11 @@ Modules for JS backend
Declaration of the Document Object Model for the JS backend.
* `jsconsole <jsconsole.html>`_
Wrapper for the ``console`` object.
Wrapper for the `console` object.
* `jscore <jscore.html>`_
The wrapper of core JavaScript functions. For most purposes, you should be using
the ``math``, ``json``, and ``times`` stdlib modules instead of this module.
the `math`, `json`, and `times` stdlib modules instead of this module.
* `jsffi <jsffi.html>`_
Types and macros for easier interaction with JavaScript.

View File

@@ -1,6 +1,8 @@
Memory safety for returning by ``var T`` is ensured by a simple borrowing
rule: If ``result`` does not refer to a location pointing to the heap
(that is in ``result = X`` the ``X`` involves a ``ptr`` or ``ref`` access)
.. default-role:: code
Memory safety for returning by `var T` is ensured by a simple borrowing
rule: If `result` does not refer to a location pointing to the heap
(that is in `result = X` the `X` involves a `ptr` or `ref` access)
then it has to be derived from the routine's first parameter:
.. code-block:: nim
@@ -11,10 +13,10 @@ then it has to be derived from the routine's first parameter:
var x: int
# we know 'forward' provides a view into the location derived from
# its first argument 'x'.
result = forward(x) # Error: location is derived from ``x``
result = forward(x) # Error: location is derived from `x`
# which is not p's first parameter and lives
# on the stack.
In other words, the lifetime of what ``result`` points to is attached to the
In other words, the lifetime of what `result` points to is attached to the
lifetime of the first parameter and that is enough knowledge to verify
memory safety at the call site.

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,4 @@
.. default-role:: code
Strict not nil checking
=========================
@@ -14,9 +15,9 @@ or
In the second case it would check builtin and imported modules as well.
It checks the nilability of ref-like types and makes dereferencing safer based on flow typing and ``not nil`` annotations.
It checks the nilability of ref-like types and makes dereferencing safer based on flow typing and `not nil` annotations.
Its implementation is different than the ``notnil`` one: defined under ``strictNotNil``. Keep in mind the difference in option names, be careful with distinguishing them.
Its implementation is different than the `notnil` one: defined under `strictNotNil`. Keep in mind the difference in option names, be careful with distinguishing them.
We check several kinds of types for nilability:
@@ -28,14 +29,14 @@ We check several kinds of types for nilability:
nil
-------
The default kind of nilability types is the nilable kind: they can have the value ``nil``.
If you have a non-nilable type ``T``, you can use ``T nil`` to get a nilable type for it.
The default kind of nilability types is the nilable kind: they can have the value `nil`.
If you have a non-nilable type `T`, you can use `T nil` to get a nilable type for it.
not nil
--------
You can annotate a type where nil isn't a valid value with ``not nil``.
You can annotate a type where nil isn't a valid value with `not nil`.
.. code-block:: nim
type
@@ -58,40 +59,40 @@ You can annotate a type where nil isn't a valid value with ``not nil``.
If a type can include ``nil`` as a valid value, dereferencing values of the type
is checked by the compiler: if a value which might be nil is derefenced, this produces a warning by default, you can turn this into an error using the compiler options ``--warningAsError:strictNotNil``
If a type can include `nil` as a valid value, dereferencing values of the type
is checked by the compiler: if a value which might be nil is derefenced, this produces a warning by default, you can turn this into an error using the compiler options `--warningAsError:strictNotNil`
If a type is nilable, you should dereference its values only after a ``isNil`` or equivalent check.
If a type is nilable, you should dereference its values only after a `isNil` or equivalent check.
local turn on/off
---------------------
You can still turn off nil checking on function/module level by using a ``{.strictNotNil: off}.`` pragma.
You can still turn off nil checking on function/module level by using a `{.strictNotNil: off}.` pragma.
Note: test that/TODO for code/manual.
nilability state
-----------------
Currently a nilable value can be ``Safe``, ``MaybeNil`` or ``Nil`` : we use internally ``Parent`` and ``Unreachable`` but this is an implementation detail(a parent layer has the actual nilability).
Currently a nilable value can be `Safe`, `MaybeNil` or `Nil` : we use internally `Parent` and `Unreachable` but this is an implementation detail(a parent layer has the actual nilability).
``Safe`` means it shouldn't be nil at that point: e.g. after assignment to a non-nil value or ``not a.isNil`` check
``MaybeNil`` means it might be nil, but it might not be nil: e.g. an argument, a call argument or a value after an ``if`` and ``else``.
``Nil`` means it should be nil at that point; e.g. after an assignment to ``nil`` or a ``.isNil`` check.
`Safe` means it shouldn't be nil at that point: e.g. after assignment to a non-nil value or `not a.isNil` check
`MaybeNil` means it might be nil, but it might not be nil: e.g. an argument, a call argument or a value after an `if` and `else`.
`Nil` means it should be nil at that point; e.g. after an assignment to `nil` or a `.isNil` check.
``Unreachable`` means it shouldn't be possible to access this in this branch: so we do generate a warning as well.
`Unreachable` means it shouldn't be possible to access this in this branch: so we do generate a warning as well.
We show an error for each dereference (``[]``, ``.field``, ``[index]`` ``()`` etc) which is of a tracked expression which is
in ``MaybeNil`` or ``Nil`` state.
We show an error for each dereference (`[]`, `.field`, `[index]` `()` etc) which is of a tracked expression which is
in `MaybeNil` or `Nil` state.
type nilability
----------------
Types are either nilable or non-nilable.
When you pass a param or a default value, we use the type : for nilable types we return ``MaybeNil``
and for non-nilable ``Safe``.
When you pass a param or a default value, we use the type : for nilable types we return `MaybeNil`
and for non-nilable `Safe`.
TODO: fix the manual here. (This is not great, as default values for non-nilables and nilables are usually actually ``nil`` , so we should think a bit more about this section.)
TODO: fix the manual here. (This is not great, as default values for non-nilables and nilables are usually actually `nil` , so we should think a bit more about this section.)
params rules
------------
@@ -102,9 +103,9 @@ Param's nilability is detected based on type nilability. We use the type of the
assignment rules
-----------------
Let's say we have ``left = right``.
Let's say we have `left = right`.
When we assign, we pass the right's nilability to the left's expression. There should be special handling of aliasing and compound expressions which we specify in their sections. (Assignment is a possible alias ``move`` or ``move out``).
When we assign, we pass the right's nilability to the left's expression. There should be special handling of aliasing and compound expressions which we specify in their sections. (Assignment is a possible alias `move` or `move out`).
call args rules
-----------------
@@ -114,20 +115,20 @@ When we call with arguments, we have two cases when we might change the nilabili
.. code-block:: nim
callByVar(a)
Here ``callByVar`` can re-assign ``a``, so this might change ``a``'s nilability, so we change it to ``MaybeNil``.
This is also a possible aliasing ``move out`` (moving out of a current alias set).
Here `callByVar` can re-assign `a`, so this might change `a`'s nilability, so we change it to `MaybeNil`.
This is also a possible aliasing `move out` (moving out of a current alias set).
.. code-block:: nim
call(a)
Here ``call`` can change a field or element of ``a``, so if we have a dependant expression of ``a`` : e.g. ``a.field``. Dependats become ``MaybeNil``.
Here `call` can change a field or element of `a`, so if we have a dependant expression of `a` : e.g. `a.field`. Dependats become `MaybeNil`.
branches rules
---------------
Branches are the reason we do nil checking like this: with flow checking.
Sources of brancing are ``if``, ``while``, ``for``, ``and``, ``or``, ``case``, ``try`` and combinations with ``return``, ``break``, ``continue`` and ``raise``
Sources of brancing are `if`, `while`, `for`, `and`, `or`, `case`, `try` and combinations with `return`, `break`, `continue` and `raise`
We create a new layer/"scope" for each branch where we map expressions to nilability. This happens when we "fork": usually on the beginning of a construct.
When branches "join" we usually unify their expression maps or/and nilabilities.
@@ -142,33 +143,33 @@ Merging usually merges maps and alias sets: nilabilities are merged like this:
else:
MaybeNil
Special handling is for ``.isNil`` and `` == nil``, also for ``not``, ``and`` and ``or``.
Special handling is for `.isNil` and ` == nil`, also for `not`, `and` and `or`.
``not`` reverses the nilability, ``and`` is similar to "forking" : the right expression is checked in the layer resulting from the left one and ``or`` is similar to "merging": the right and left expression should be both checked in the original layer.
`not` reverses the nilability, `and` is similar to "forking" : the right expression is checked in the layer resulting from the left one and `or` is similar to "merging": the right and left expression should be both checked in the original layer.
``isNil``, ``== nil`` make expressions ``Nil``. If there is a ``not`` or ``!= nil``, they make them ``Safe``.
We also reverse the nilability in the opposite branch: e.g. ``else``.
`isNil`, `== nil` make expressions `Nil`. If there is a `not` or `!= nil`, they make them `Safe`.
We also reverse the nilability in the opposite branch: e.g. `else`.
compound expressions: field, index expressions
-----------------------------------------------
We want to track also field(dot) and index(bracket) expressions.
We track some of those compound expressions which might be nilable as dependants of their bases: ``a.field`` is changed if ``a`` is moved (re-assigned),
similarly ``a[index]`` is dependent on ``a`` and ``a.field.field`` on ``a.field``.
We track some of those compound expressions which might be nilable as dependants of their bases: `a.field` is changed if `a` is moved (re-assigned),
similarly `a[index]` is dependent on `a` and `a.field.field` on `a.field`.
When we move the base, we update dependants to ``MaybeNil``. Otherwise we usually start with type nilability.
When we move the base, we update dependants to `MaybeNil`. Otherwise we usually start with type nilability.
When we call args, we update the nilability of their dependants to ``MaybeNil`` as the calls usually can change them.
We might need to check for ``strictFuncs`` pure funcs and not do that then.
When we call args, we update the nilability of their dependants to `MaybeNil` as the calls usually can change them.
We might need to check for `strictFuncs` pure funcs and not do that then.
For field expressions ``a.field``, we calculate an integer value based on a hash of the tree and just accept equivalent trees as equivalent expressions.
For field expressions `a.field`, we calculate an integer value based on a hash of the tree and just accept equivalent trees as equivalent expressions.
For item expression ``a[index]``, we also calculate an integer value based on a hash of the tree and accept equivalent trees as equivalent expressions: for static values only.
For now we support only constant indices: we dont track expression with no-const indices. For those we just report a warning even if they are safe for now: one can use a local variable to workaround. For loops this might be annoying: so one should be able to turn off locally the warning using the ``{.warning[StrictCheckNotNil]:off}.``.
For item expression `a[index]`, we also calculate an integer value based on a hash of the tree and accept equivalent trees as equivalent expressions: for static values only.
For now we support only constant indices: we dont track expression with no-const indices. For those we just report a warning even if they are safe for now: one can use a local variable to workaround. For loops this might be annoying: so one should be able to turn off locally the warning using the `{.warning[StrictCheckNotNil]:off}.`.
For bracket expressions, in the future we might count ``a[<any>]`` as the same general expression.
This means we should should the index but otherwise handle it the same for assign (maybe "aliasing" all the non-static elements) and differentiate only for static: e.g. ``a[0]`` and ``a[1]``.
For bracket expressions, in the future we might count `a[<any>]` as the same general expression.
This means we should should the index but otherwise handle it the same for assign (maybe "aliasing" all the non-static elements) and differentiate only for static: e.g. `a[0]` and `a[1]`.
element tracking
-----------------
@@ -185,8 +186,8 @@ Also related to tracking initialization of expressions/fields.
unstructured control flow rules
-------------------------------
Unstructured control flow keywords as ``return``, ``break``, ``continue``, ``raise`` mean that we jump from a branch out.
This means that if there is code after the finishing of the branch, it would be ran if one hasn't hit the direct parent branch of those: so it is similar to an ``else``. In those cases we should use the reverse nilabilities for the local to the condition expressions. E.g.
Unstructured control flow keywords as `return`, `break`, `continue`, `raise` mean that we jump from a branch out.
This means that if there is code after the finishing of the branch, it would be ran if one hasn't hit the direct parent branch of those: so it is similar to an `else`. In those cases we should use the reverse nilabilities for the local to the condition expressions. E.g.
.. code-block:: nim
for a in c:
@@ -204,14 +205,14 @@ We support alias detection for local expressions.
We track sets of aliased expressions. We start with all nilable local expressions in separate sets.
Assignments and other changes to nilability can move / move out expressions of sets.
``move``: Moving ``left`` to ``right`` means we remove ``left`` from its current set and unify it with the ``right``'s set.
`move`: Moving `left` to `right` means we remove `left` from its current set and unify it with the `right`'s set.
This means it stops being aliased with its previous aliases.
.. code-block:: nim
var left = b
left = right # moving left to right
``move out``: Moving out ``left`` might remove it from the current set and ensure that it's in its own set as a single element.
`move out`: Moving out `left` might remove it from the current set and ensure that it's in its own set as a single element.
e.g.
@@ -229,7 +230,7 @@ warnings and errors
---------------------
We show an error for each dereference (`[]`, `.field`, `[index]` `()` etc) which is of a tracked expression which is
in ``MaybeNil`` or ``Nil`` state.
in `MaybeNil` or `Nil` state.
We might also show a history of the transitions and the reasons for them that might change the nilability of the expression.

View File

@@ -1,3 +1,5 @@
.. default-role:: code
==========================================================
Nim Enhancement Proposal #1 - Standard Library Style Guide
==========================================================
@@ -124,11 +126,11 @@ Naming Conventions
- In the age of HTTP, HTML, FTP, TCP, IP, UTF, WWW it is foolish to pretend
these are somewhat special words requiring all uppercase. Instead treat them
as what they are: Real words. So it's ``parseUrl`` rather than
``parseURL``, ``checkHttpHeader`` instead of ``checkHTTPHeader`` etc.
as what they are: Real words. So it's `parseUrl` rather than
`parseURL`, `checkHttpHeader` instead of `checkHTTPHeader` etc.
- Operations like ``mitems`` or ``mpairs`` (or the now deprecated ``mget``)
that allow a *mutating view* into some data structure should start with an ``m``.
- Operations like `mitems` or `mpairs` (or the now deprecated `mget`)
that allow a *mutating view* into some data structure should start with an `m`.
- When both in-place mutation and 'returns transformed copy' are available the latter
is a past participle of the former:
@@ -136,8 +138,8 @@ Naming Conventions
- sort and sorted
- rotate and rotated
- When the 'returns transformed copy' version already exists like ``strutils.replace``
an in-place version should get an ``-In`` suffix (``replaceIn`` for this example).
- When the 'returns transformed copy' version already exists like `strutils.replace`
an in-place version should get an `-In` suffix (`replaceIn` for this example).
- Use `subjectVerb`, not `verbSubject`, e.g.: `fileExists`, not `existsFile`.
@@ -153,25 +155,25 @@ to keep the names short but meaningful.
------------------- ------------ --------------------------------------
English word To use Notes
------------------- ------------ --------------------------------------
initialize initFoo initializes a value type ``Foo``
new newFoo initializes a reference type ``Foo``
via ``new``
initialize initFoo initializes a value type `Foo`
new newFoo initializes a reference type `Foo`
via `new`
this or self self for method like procs, e.g.:
`proc fun(self: Foo, a: int)`
rationale: `self` is more unique in English
than `this`, and `foo` would not be DRY.
find find should return the position where
something was found; for a bool result
use ``contains``
contains contains often short for ``find() >= 0``
append add use ``add`` instead of ``append``
use `contains`
contains contains often short for `find() >= 0`
append add use `add` instead of `append`
compare cmp should return an int with the
``< 0`` ``== 0`` or ``> 0`` semantics;
for a bool result use ``sameXYZ``
put put, ``[]=`` consider overloading ``[]=`` for put
get get, ``[]`` consider overloading ``[]`` for get;
consider to not use ``get`` as a
prefix: ``len`` instead of ``getLen``
`< 0` `== 0` or `> 0` semantics;
for a bool result use `sameXYZ`
put put, `[]=` consider overloading `[]=` for put
get get, `[]` consider overloading `[]` for get;
consider to not use `get` as a
prefix: `len` instead of `getLen`
length len also used for *number of elements*
size size, len size should refer to a byte size
capacity cap
@@ -236,8 +238,8 @@ Coding Conventions
- Use a proc when possible, only using the more powerful facilities of macros,
templates, iterators, and converters when necessary.
- Use the ``let`` statement (not the ``var`` statement) when declaring variables that
do not change within their scope. Using the ``let`` statement ensures that
- Use the `let` statement (not the `var` statement) when declaring variables that
do not change within their scope. Using the `let` statement ensures that
variables remain immutable, and gives those who read the code a better idea
of the code's purpose.

View File

@@ -1,3 +1,5 @@
.. default-role:: code
===================================
Nim Compiler User Guide
===================================
@@ -45,8 +47,8 @@ Advanced command-line switches are:
List of warnings
----------------
Each warning can be activated individually with ``--warning[NAME]:on|off`` or
in a ``push`` pragma.
Each warning can be activated individually with `--warning[NAME]:on|off` or
in a `push` pragma.
========================== ============================================
Name Description
@@ -60,7 +62,7 @@ ConfigDeprecated The project makes use of a deprecated config
file.
SmallLshouldNotBeUsed The letter 'l' should not be used as an
identifier.
EachIdentIsTuple The code contains a confusing ``var``
EachIdentIsTuple The code contains a confusing `var`
declaration.
User Some user-defined warning.
========================== ============================================
@@ -69,8 +71,8 @@ User Some user-defined warning.
List of hints
-------------
Each hint can be activated individually with ``--hint[NAME]:on|off`` or in a
``push`` pragma.
Each hint can be activated individually with `--hint[NAME]:on|off` or in a
`push` pragma.
========================== ============================================
Name Description
@@ -129,52 +131,52 @@ Level Description
Compile-time symbols
--------------------
Through the ``-d:x`` or ``--define:x`` switch you can define compile-time
Through the `-d:x` or `--define:x` switch you can define compile-time
symbols for conditional compilation. The defined switches can be checked in
source code with the `when statement
<manual.html#statements-and-expressions-when-statement>`_ and
`defined proc <system.html#defined,untyped>`_. The typical use of this switch is
to enable builds in release mode (``-d:release``) where optimizations are
enabled for better performance. Another common use is the ``-d:ssl`` switch to
to enable builds in release mode (`-d:release`) where optimizations are
enabled for better performance. Another common use is the `-d:ssl` switch to
activate SSL sockets.
Additionally, you may pass a value along with the symbol: ``-d:x=y``
Additionally, you may pass a value along with the symbol: `-d:x=y`
which may be used in conjunction with the `compile-time define
pragmas<manual.html#implementation-specific-pragmas-compileminustime-define-pragmas>`_
to override symbols during build time.
Compile-time symbols are completely **case insensitive** and underscores are
ignored too. ``--define:FOO`` and ``--define:foo`` are identical.
ignored too. `--define:FOO` and `--define:foo` are identical.
Compile-time symbols starting with the ``nim`` prefix are reserved for the
Compile-time symbols starting with the `nim` prefix are reserved for the
implementation and should not be used elsewhere.
Configuration files
-------------------
**Note:** The *project file name* is the name of the ``.nim`` file that is
**Note:** The *project file name* is the name of the `.nim` file that is
passed as a command-line argument to the compiler.
The ``nim`` executable processes configuration files in the following
The `nim` executable processes configuration files in the following
directories (in this order; later files overwrite previous settings):
1) ``$nim/config/nim.cfg``, ``/etc/nim/nim.cfg`` (UNIX) or ``<Nim's installation directory>\config\nim.cfg`` (Windows). This file can be skipped with the ``--skipCfg`` command line option.
2) If environment variable ``XDG_CONFIG_HOME`` is defined, ``$XDG_CONFIG_HOME/nim/nim.cfg`` or ``~/.config/nim/nim.cfg`` (POSIX) or ``%APPDATA%/nim/nim.cfg`` (Windows). This file can be skipped with the ``--skipUserCfg`` command line option.
3) ``$parentDir/nim.cfg`` where ``$parentDir`` stands for any parent directory of the project file's path. These files can be skipped with the ``--skipParentCfg`` command-line option.
4) ``$projectDir/nim.cfg`` where ``$projectDir`` stands for the project file's path. This file can be skipped with the ``--skipProjCfg`` command-line option.
5) A project can also have a project-specific configuration file named ``$project.nim.cfg`` that resides in the same directory as ``$project.nim``. This file can be skipped with the ``--skipProjCfg`` command-line option.
1) `$nim/config/nim.cfg`, `/etc/nim/nim.cfg` (UNIX) or ``<Nim's installation directory>\config\nim.cfg`` (Windows). This file can be skipped with the `--skipCfg` command line option.
2) If environment variable `XDG_CONFIG_HOME` is defined, `$XDG_CONFIG_HOME/nim/nim.cfg` or `~/.config/nim/nim.cfg` (POSIX) or `%APPDATA%/nim/nim.cfg` (Windows). This file can be skipped with the `--skipUserCfg` command line option.
3) `$parentDir/nim.cfg` where `$parentDir` stands for any parent directory of the project file's path. These files can be skipped with the `--skipParentCfg` command-line option.
4) `$projectDir/nim.cfg` where `$projectDir` stands for the project file's path. This file can be skipped with the `--skipProjCfg` command-line option.
5) A project can also have a project-specific configuration file named `$project.nim.cfg` that resides in the same directory as `$project.nim`. This file can be skipped with the `--skipProjCfg` command-line option.
Command-line settings have priority over configuration file settings.
The default build of a project is a `debug build`:idx:. To compile a
`release build`:idx: define the ``release`` symbol::
`release build`:idx: define the `release` symbol::
nim c -d:release myproject.nim
To compile a `dangerous release build`:idx: define the ``danger`` symbol::
To compile a `dangerous release build`:idx: define the `danger` symbol::
nim c -d:danger myproject.nim
@@ -186,10 +188,10 @@ Nim has the concept of a global search path (PATH) that is queried to
determine where to find imported modules or include files. If multiple files are
found an ambiguity error is produced.
``nim dump`` shows the contents of the PATH.
`nim dump` shows the contents of the PATH.
However before the PATH is used the current directory is checked for the
file's existence. So if PATH contains ``$lib`` and ``$lib/bar`` and the
file's existence. So if PATH contains `$lib` and `$lib/bar` and the
directory structure looks like this::
$lib/x.nim
@@ -198,27 +200,27 @@ directory structure looks like this::
foo/main.nim
other.nim
And ``main`` imports ``x``, ``foo/x`` is imported. If ``other`` imports ``x``
then both ``$lib/x.nim`` and ``$lib/bar/x.nim`` match but ``$lib/x.nim`` is used
And `main` imports `x`, `foo/x` is imported. If `other` imports `x`
then both `$lib/x.nim` and `$lib/bar/x.nim` match but `$lib/x.nim` is used
as it is the first match.
Generated C code directory
--------------------------
The generated files that Nim produces all go into a subdirectory called
``nimcache``. Its full path is
`nimcache`. Its full path is
- ``$XDG_CACHE_HOME/nim/$projectname(_r|_d)`` or ``~/.cache/nim/$projectname(_r|_d)``
- `$XDG_CACHE_HOME/nim/$projectname(_r|_d)` or `~/.cache/nim/$projectname(_r|_d)`
on Posix
- ``$HOME/nimcache/$projectname(_r|_d)`` on Windows.
- `$HOME/nimcache/$projectname(_r|_d)` on Windows.
The ``_r`` suffix is used for release builds, ``_d`` is for debug builds.
The `_r` suffix is used for release builds, `_d` is for debug builds.
This makes it easy to delete all generated files.
The ``--nimcache``
The `--nimcache`
`compiler switch <#compiler-usage-commandminusline-switches>`_ can be used to
to change the ``nimcache`` directory.
to change the `nimcache` directory.
However, the generated C code is not platform-independent. C code generated for
Linux does not compile on Windows, for instance. The comment on top of the
@@ -232,16 +234,16 @@ To change the compiler from the default compiler (at the command line)::
nim c --cc:llvm_gcc --compile_only myfile.nim
This uses the configuration defined in ``config\nim.cfg`` for ``lvm_gcc``.
This uses the configuration defined in ``config\nim.cfg`` for `lvm_gcc`.
If nimcache already contains compiled code from a different compiler for the same project,
add the ``-f`` flag to force all files to be recompiled.
add the `-f` flag to force all files to be recompiled.
The default compiler is defined at the top of ``config\nim.cfg``.
Changing this setting affects the compiler used by ``koch`` to (re)build Nim.
Changing this setting affects the compiler used by `koch` to (re)build Nim.
To use the ``CC`` environment variable, use ``nim c --cc:env myfile.nim``. To use the
``CXX`` environment variable, use ``nim cpp --cc:env myfile.nim``. ``--cc:env`` is available
To use the `CC` environment variable, use `nim c --cc:env myfile.nim`. To use the
`CXX` environment variable, use `nim cpp --cc:env myfile.nim`. `--cc:env` is available
since Nim version 1.4.
@@ -252,7 +254,7 @@ To cross compile, use for example::
nim c --cpu:i386 --os:linux --compileOnly --genScript myproject.nim
Then move the C code and the compile script ``compile_myproject.sh`` to your
Then move the C code and the compile script `compile_myproject.sh` to your
Linux i386 machine and run the script.
Another way is to make Nim invoke a cross compiler toolchain::
@@ -260,8 +262,8 @@ Another way is to make Nim invoke a cross compiler toolchain::
nim c --cpu:arm --os:linux myproject.nim
For cross compilation, the compiler invokes a C compiler named
like ``$cpu.$os.$cc`` (for example arm.linux.gcc) and the configuration
system is used to provide meaningful defaults. For example for ``ARM`` your
like `$cpu.$os.$cc` (for example arm.linux.gcc) and the configuration
system is used to provide meaningful defaults. For example for `ARM` your
configuration file should contain something like::
arm.linux.gcc.path = "/usr/bin"
@@ -275,7 +277,7 @@ To cross-compile for Windows from Linux or macOS using the MinGW-w64 toolchain::
nim c -d:mingw myproject.nim
Use ``--cpu:i386`` or ``--cpu:amd64`` to switch the CPU architecture.
Use `--cpu:i386` or `--cpu:amd64` to switch the CPU architecture.
The MinGW-w64 toolchain can be installed as follows::
@@ -295,7 +297,7 @@ The first one is to treat Android as a simple Linux and use
directly on android as if it was Linux. These programs are console-only
programs that can't be distributed in the Play Store.
Use regular ``nim c`` inside termux to make Android terminal programs.
Use regular `nim c` inside termux to make Android terminal programs.
Normal Android apps are written in Java, to use Nim inside an Android app
you need a small Java stub that calls out to a native library written in
@@ -303,16 +305,16 @@ Nim using the `NDK <https://developer.android.com/ndk>`_. You can also use
`native-activity <https://developer.android.com/ndk/samples/sample_na>`_
to have the Java stub be auto-generated for you.
Use ``nim c -c --cpu:arm --os:android -d:androidNDK --noMain:on`` to
Use `nim c -c --cpu:arm --os:android -d:androidNDK --noMain:on` to
generate the C source files you need to include in your Android Studio
project. Add the generated C files to CMake build script in your Android
project. Then do the final compile with Android Studio which uses Gradle
to call CMake to compile the project.
Because Nim is part of a library it can't have its own c style ``main()``
so you would need to define your own ``android_main`` and init the Java
Because Nim is part of a library it can't have its own c style `main()`
so you would need to define your own `android_main` and init the Java
environment, or use a library like SDL2 or GLFM to do it. After the Android
stuff is done, it's very important to call ``NimMain()`` in order to
stuff is done, it's very important to call `NimMain()` in order to
initialize Nim's garbage collector and to run the top level statements
of your program.
@@ -331,14 +333,14 @@ Normal languages for iOS development are Swift and Objective C. Both of these
use LLVM and can be compiled into object files linked together with C, C++
or Objective C code produced by Nim.
Use ``nim c -c --os:ios --noMain:on`` to generate C files and include them in
Use `nim c -c --os:ios --noMain:on` to generate C files and include them in
your XCode project. Then you can use XCode to compile, link, package and
sign everything.
Because Nim is part of a library it can't have its own c style ``main()`` so you
would need to define `main` that calls ``autoreleasepool`` and
``UIApplicationMain`` to do it, or use a library like SDL2 or GLFM. After
the iOS setup is done, it's very important to call ``NimMain()`` to
Because Nim is part of a library it can't have its own c style `main()` so you
would need to define `main` that calls `autoreleasepool` and
`UIApplicationMain` to do it, or use a library like SDL2 or GLFM. After
the iOS setup is done, it's very important to call `NimMain()` to
initialize Nim's garbage collector and to run the top-level statements
of your program.
@@ -356,8 +358,8 @@ Cross-compilation for Nintendo Switch
=====================================
Simply add --os:nintendoswitch
to your usual ``nim c`` or ``nim cpp`` command and set the ``passC``
and ``passL`` command line switches to something like:
to your usual `nim c` or `nim cpp` command and set the `passC`
and `passL` command line switches to something like:
.. code-block:: console
nim c ... --passC="-I$DEVKITPRO/libnx/include" ...
@@ -378,8 +380,8 @@ For example, with the above-mentioned config::
nim c --os:nintendoswitch switchhomebrew.nim
This will generate a file called ``switchhomebrew.elf`` which can then be turned into
an nro file with the ``elf2nro`` tool in the DevkitPro release. Examples can be found at
This will generate a file called `switchhomebrew.elf` which can then be turned into
an nro file with the `elf2nro` tool in the DevkitPro release. Examples can be found at
`the nim-libnx github repo <https://github.com/jyapayne/nim-libnx.git>`_.
There are a few things that don't work because the DevkitPro libraries don't support them.
@@ -399,62 +401,62 @@ DLL generation
Nim supports the generation of DLLs. However, there must be only one
instance of the GC per process/address space. This instance is contained in
``nimrtl.dll``. This means that every generated Nim DLL depends
on ``nimrtl.dll``. To generate the "nimrtl.dll" file, use the command::
`nimrtl.dll`. This means that every generated Nim DLL depends
on `nimrtl.dll`. To generate the "nimrtl.dll" file, use the command::
nim c -d:release lib/nimrtl.nim
To link against ``nimrtl.dll`` use the command::
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
**Note**: Currently the creation of `nimrtl.dll` with thread support has
never been tested and is unlikely to work!
Additional compilation switches
===============================
The standard library supports a growing number of ``useX`` conditional defines
The standard library supports a growing number of `useX` conditional defines
affecting how some features are implemented. This section tries to give a
complete list.
====================== =========================================================
Define Effect
====================== =========================================================
``release`` Turns on the optimizer.
`release` Turns on the optimizer.
More aggressive optimizations are possible, e.g.:
``--passC:-ffast-math`` (but see issue #10305)
``danger`` Turns off all runtime checks and turns on the optimizer.
``useFork`` Makes ``osproc`` use ``fork`` instead of ``posix_spawn``.
``useNimRtl`` Compile and link against ``nimrtl.dll``.
``useMalloc`` Makes Nim use C's `malloc`:idx: instead of Nim's
`--passC:-ffast-math` (but see issue #10305)
`danger` Turns off all runtime checks and turns on the optimizer.
`useFork` Makes `osproc` use `fork` instead of `posix_spawn`.
`useNimRtl` Compile and link against `nimrtl.dll`.
`useMalloc` Makes Nim use C's `malloc`:idx: instead of Nim's
own memory manager, albeit prefixing each allocation with
its size to support clearing memory on reallocation.
This only works with ``gc:none``, ``gc:arc`` and
``--gc:orc``.
``useRealtimeGC`` Enables support of Nim's GC for *soft* realtime
This only works with `gc:none`, `gc:arc` and
`--gc:orc`.
`useRealtimeGC` Enables support of Nim's GC for *soft* realtime
systems. See the documentation of the `gc <gc.html>`_
for further information.
``logGC`` Enable GC logging to stdout.
``nodejs`` The JS target is actually ``node.js``.
``ssl`` Enables OpenSSL support for the sockets module.
``memProfiler`` Enables memory profiling for the native GC.
``uClibc`` Use uClibc instead of libc. (Relevant for Unix-like OSes)
``checkAbi`` When using types from C headers, add checks that compare
`logGC` Enable GC logging to stdout.
`nodejs` The JS target is actually `node.js`.
`ssl` Enables OpenSSL support for the sockets module.
`memProfiler` Enables memory profiling for the native GC.
`uClibc` Use uClibc instead of libc. (Relevant for Unix-like OSes)
`checkAbi` When using types from C headers, add checks that compare
what's in the Nim file with what's in the C header.
This may become enabled by default in the future.
``tempDir`` This symbol takes a string as its value, like
``--define:tempDir:/some/temp/path`` to override the
temporary directory returned by ``os.getTempDir()``.
`tempDir` This symbol takes a string as its value, like
`--define:tempDir:/some/temp/path` to override the
temporary directory returned by `os.getTempDir()`.
The value **should** end with a directory separator
character. (Relevant for the Android platform)
``useShPath`` This symbol takes a string as its value, like
``--define:useShPath:/opt/sh/bin/sh`` to override the
path for the ``sh`` binary, in cases where it is not
located in the default location ``/bin/sh``.
``noSignalHandler`` Disable the crash handler from ``system.nim``.
``globalSymbols`` Load all ``{.dynlib.}`` libraries with the ``RTLD_GLOBAL``
`useShPath` This symbol takes a string as its value, like
`--define:useShPath:/opt/sh/bin/sh` to override the
path for the `sh` binary, in cases where it is not
located in the default location `/bin/sh`.
`noSignalHandler` Disable the crash handler from `system.nim`.
`globalSymbols` Load all `{.dynlib.}` libraries with the `RTLD_GLOBAL`
flag on Posix systems to resolve symbols in subsequently
loaded libraries.
====================== =========================================================
@@ -471,20 +473,20 @@ generator and are subject to change.
LineDir option
--------------
The ``lineDir`` option can be turned on or off. If turned on the
generated C code contains ``#line`` directives. This may be helpful for
The `lineDir` option can be turned on or off. If turned on the
generated C code contains `#line` directives. This may be helpful for
debugging with GDB.
StackTrace option
-----------------
If the ``stackTrace`` option is turned on, the generated C contains code to
If the `stackTrace` option is turned on, the generated C contains code to
ensure that proper stack traces are given if the program crashes or some uncaught exception is raised.
LineTrace option
----------------
The ``lineTrace`` option implies the ``stackTrace`` option. If turned on,
The `lineTrace` option implies the `stackTrace` option. If turned on,
the generated C contains code to ensure that proper stack traces with line
number information are given if the program crashes or an uncaught exception
is raised.
@@ -493,10 +495,10 @@ is raised.
DynlibOverride
==============
By default Nim's ``dynlib`` pragma causes the compiler to generate
``GetProcAddress`` (or their Unix counterparts)
calls to bind to a DLL. With the ``dynlibOverride`` command line switch this
can be prevented and then via ``--passL`` the static library can be linked
By default Nim's `dynlib` pragma causes the compiler to generate
`GetProcAddress` (or their Unix counterparts)
calls to bind to a DLL. With the `dynlibOverride` command line switch this
can be prevented and then via `--passL` the static library can be linked
against. For instance, to link statically against Lua this command might work
on Linux::
@@ -506,8 +508,8 @@ on Linux::
Backend language options
========================
The typical compiler usage involves using the ``compile`` or ``c`` command to
transform a ``.nim`` file into one or more ``.c`` files which are then
The typical compiler usage involves using the `compile` or `c` command to
transform a `.nim` file into one or more `.c` files which are then
compiled with the platform's C compiler into a static binary. However, there
are other commands to compile to C++, Objective-C, or JavaScript. More details
can be read in the `Nim Backend Integration document <backends.html>`_.
@@ -517,7 +519,7 @@ Nim documentation tools
=======================
Nim provides the `doc`:idx: command to generate HTML
documentation from ``.nim`` source files. Only exported symbols will appear in
documentation from `.nim` source files. Only exported symbols will appear in
the output. For more details `see the docgen documentation <docgen.html>`_.
Nim idetools integration
@@ -533,15 +535,15 @@ for further information.
The Nim compiler supports an interactive mode. This is also known as
a `REPL`:idx: (*read eval print loop*). If Nim has been built with the
``-d:nimUseLinenoise`` switch, it uses the GNU readline library for terminal
`-d:nimUseLinenoise` switch, it uses the GNU readline library for terminal
input management. To start Nim in interactive mode use the command
``nim secret``. To quit use the ``quit()`` command. To determine whether an input
`nim secret`. To quit use the `quit()` command. To determine whether an input
line is an incomplete statement to be continued these rules are used:
1. The line ends with ``[-+*/\\<>!\?\|%&$@~,;:=#^]\s*$`` (operator symbol followed by optional whitespace).
2. The line starts with a space (indentation).
3. The line is within a triple quoted string literal. However, the detection
does not work if the line contains more than one ``"""``.
does not work if the line contains more than one `"""`.
Nim for embedded systems
@@ -552,22 +554,22 @@ modern PC hardware and operating systems with ample memory, it is very well
possible to run Nim code and a good part of the Nim standard libraries on small
embedded microprocessors with only a few kilobytes of memory.
A good start is to use the ``any`` operating target together with the
``malloc`` memory allocator and the ``arc`` garbage collector. For example:
A good start is to use the `any` operating target together with the
`malloc` memory allocator and the `arc` garbage collector. For example:
``nim c --os:any --gc:arc -d:useMalloc [...] x.nim``
`nim c --os:any --gc:arc -d:useMalloc [...] x.nim`
- ``--gc:arc`` will enable the reference counting memory management instead
- `--gc:arc` will enable the reference counting memory management instead
of the default garbage collector. This enables Nim to use heap memory which
is required for strings and seqs, for example.
- The ``--os:any`` target makes sure Nim does not depend on any specific
- The `--os:any` target makes sure Nim does not depend on any specific
operating system primitives. Your platform should support only some basic
ANSI C library ``stdlib`` and ``stdio`` functions which should be available
ANSI C library `stdlib` and `stdio` functions which should be available
on almost any platform.
- The ``-d:useMalloc`` option configures Nim to use only the standard C memory
manage primitives ``malloc()``, ``free()``, ``realloc()``.
- The `-d:useMalloc` option configures Nim to use only the standard C memory
manage primitives `malloc()`, `free()`, `realloc()`.
If your platform does not provide these functions it should be trivial to
provide an implementation for them and link these to your program.
@@ -577,10 +579,10 @@ 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``
`--opt:size --passC:-flto --passL:-flto`
The ``--opt:size`` flag instructs Nim to optimize code generation for small
size (with the help of the C compiler), the ``flto`` flags enable link-time
The `--opt:size` flag instructs Nim to optimize code generation for small
size (with the help of the C compiler), the `flto` flags enable link-time
optimization in the compiler and linker.
Check the `Cross-compilation` section for instructions on how to compile the
@@ -600,7 +602,7 @@ The Nim programming language has no concept of Posix's signal handling
mechanisms. However, the standard library offers some rudimentary support
for signal handling, in particular, segmentation faults are turned into
fatal errors that produce a stack trace. This can be disabled with the
``-d:noSignalHandler`` switch.
`-d:noSignalHandler` switch.
Optimizing for Nim
@@ -642,7 +644,7 @@ However, it is not efficient to do:
.. code-block:: Nim
var s = varA # assignment has to copy the whole string into a new buffer!
For ``let`` symbols a copy is not always necessary:
For `let` symbols a copy is not always necessary:
.. code-block:: Nim
let s = varA # may only copy a pointer if it safe to do so
@@ -656,7 +658,7 @@ objects as `shallow`:idx:\:
shallow(s) # mark 's' as a shallow string
var x = s # now might not copy the string!
Usage of ``shallow`` is always safe once you know the string won't be modified
Usage of `shallow` is always safe once you know the string won't be modified
anymore, similar to Ruby's `freeze`:idx:.

View File

@@ -1,3 +1,5 @@
.. default-role:: code
=====================
Nimfix User Guide
=====================
@@ -14,12 +16,12 @@ It performs 3 different actions:
1. It makes your code case consistent.
2. It renames every symbol that has a deprecation rule. So if a module has a
rule ``{.deprecated: [TFoo: Foo].}`` then ``TFoo`` is replaced by ``Foo``.
rule `{.deprecated: [TFoo: Foo].}` then `TFoo` is replaced by `Foo`.
3. It can also check that your identifiers adhere to the official style guide
and optionally modify them to do so (via ``--styleCheck:auto``).
and optionally modify them to do so (via `--styleCheck:auto`).
Note that ``nimfix`` defaults to **overwrite** your code unless you
use ``--overwriteFiles:off``! But hey, if you do not use a version control
Note that `nimfix` defaults to **overwrite** your code unless you
use `--overwriteFiles:off`! But hey, if you do not use a version control
system by this day and age, your project is already in big trouble.

View File

@@ -1,3 +1,5 @@
.. default-role:: code
=========================
nimgrep User's manual
=========================
@@ -22,7 +24,7 @@ Compile nimgrep with the command::
nim c -d:release tools/nimgrep.nim
And copy the executable somewhere in your ``$PATH``.
And copy the executable somewhere in your `$PATH`.
Command line switches

View File

@@ -1,3 +1,5 @@
.. default-role:: code
=========================
niminst User's manual
=========================
@@ -31,8 +33,8 @@ configuration file. Here's an example of how the syntax looks like:
:literal:
The value of a key-value pair can reference user-defined variables via
the ``$variable`` notation: They can be defined in the command line with the
``--var:name=value`` switch. This is useful to not hard-coding the
the `$variable` notation: They can be defined in the command line with the
`--var:name=value` switch. This is useful to not hard-coding the
program's version number into the configuration file, for instance.
It follows a description of each possible section and how it affects the
@@ -47,28 +49,28 @@ contain the following key-value pairs:
==================== =======================================================
Key description
==================== =======================================================
``Name`` the project's name; this needs to be a single word
``DisplayName`` the project's long name; this can contain spaces. If
not specified, this is the same as ``Name``.
``Version`` the project's version
``OS`` the OSes to generate C code for; for example:
``"windows;linux;macosx"``
``CPU`` the CPUs to generate C code for; for example:
``"i386;amd64;powerpc"``
``Authors`` the project's authors
``Description`` the project's description
``App`` the application's type: "Console" or "GUI". If
`Name` the project's name; this needs to be a single word
`DisplayName` the project's long name; this can contain spaces. If
not specified, this is the same as `Name`.
`Version` the project's version
`OS` the OSes to generate C code for; for example:
`"windows;linux;macosx"`
`CPU` the CPUs to generate C code for; for example:
`"i386;amd64;powerpc"`
`Authors` the project's authors
`Description` the project's description
`App` the application's type: "Console" or "GUI". If
"Console", niminst generates a special batch file
for Windows to open up the command-line shell.
``License`` the filename of the application's license
`License` the filename of the application's license
==================== =======================================================
``files`` key
`files` key
-------------
Many sections support the ``files`` key. Listed filenames
can be separated by semicolon or the ``files`` key can be repeated. Wildcards
Many sections support the `files` key. Listed filenames
can be separated by semicolon or the `files` key can be repeated. Wildcards
in filenames are supported. If it is a directory name, all files in the
directory are used::
@@ -80,63 +82,63 @@ directory are used::
Config section
--------------
The ``config`` section currently only supports the ``files`` key. Listed files
The `config` section currently only supports the `files` key. Listed files
will be installed into the OS's configuration directory.
Documentation section
---------------------
The ``documentation`` section supports the ``files`` key.
The `documentation` section supports the `files` key.
Listed files will be installed into the OS's native documentation directory
(which might be ``$appdir/doc``).
(which might be `$appdir/doc`).
There is a ``start`` key which determines whether the Windows installer
generates a link to e.g. the ``index.html`` of your documentation.
There is a `start` key which determines whether the Windows installer
generates a link to e.g. the `index.html` of your documentation.
Other section
-------------
The ``other`` section currently only supports the ``files`` key.
The `other` section currently only supports the `files` key.
Listed files will be installed into the application installation directory
(``$appdir``).
(`$appdir`).
Lib section
-----------
The ``lib`` section currently only supports the ``files`` key.
The `lib` section currently only supports the `files` key.
Listed files will be installed into the OS's native library directory
(which might be ``$appdir/lib``).
(which might be `$appdir/lib`).
Windows section
---------------
The ``windows`` section supports the ``files`` key for Windows-specific files.
The `windows` section supports the `files` key for Windows-specific files.
Listed files will be installed into the application installation directory
(``$appdir``).
(`$appdir`).
Other possible options are:
==================== =======================================================
Key description
==================== =======================================================
``BinPath`` paths to add to the Windows ``%PATH%`` environment
`BinPath` paths to add to the Windows `%PATH%` environment
variable. Example: ``BinPath: r"bin;dist\mingw\bin"``
``InnoSetup`` boolean flag whether an Inno Setup installer should be
generated for Windows. Example: ``InnoSetup: "Yes"``
`InnoSetup` boolean flag whether an Inno Setup installer should be
generated for Windows. Example: `InnoSetup: "Yes"`
==================== =======================================================
UnixBin section
---------------
The ``UnixBin`` section currently only supports the ``files`` key.
The `UnixBin` section currently only supports the `files` key.
Listed files will be installed into the OS's native bin directory
(e.g. ``/usr/local/bin``). The exact location depends on the
installation path the user specifies when running the ``install.sh`` script.
(e.g. `/usr/local/bin`). The exact location depends on the
installation path the user specifies when running the `install.sh` script.
Unix section
@@ -147,11 +149,11 @@ Possible options are:
==================== =======================================================
Key description
==================== =======================================================
``InstallScript`` boolean flag whether an installation shell script
should be generated. Example: ``InstallScript: "Yes"``
``UninstallScript`` boolean flag whether a de-installation shell script
`InstallScript` boolean flag whether an installation shell script
should be generated. Example: `InstallScript: "Yes"`
`UninstallScript` boolean flag whether a de-installation shell script
should be generated.
Example: ``UninstallScript: "Yes"``
Example: `UninstallScript: "Yes"`
==================== =======================================================
@@ -163,10 +165,10 @@ Possible options are:
==================== =======================================================
Key description
==================== =======================================================
``path`` Path to Inno Setup.
`path` Path to Inno Setup.
Example: ``path = r"c:\inno setup 5\iscc.exe"``
``flags`` Flags to pass to Inno Setup.
Example: ``flags = "/Q"``
`flags` Flags to pass to Inno Setup.
Example: `flags = "/Q"`
==================== =======================================================
@@ -178,9 +180,9 @@ Possible options are:
==================== =======================================================
Key description
==================== =======================================================
``path`` Path to the C compiler.
``flags`` Flags to pass to the C Compiler.
Example: ``flags = "-w"``
`path` Path to the C compiler.
`flags` Flags to pass to the C Compiler.
Example: `flags = "-w"`
==================== =======================================================

View File

@@ -1,30 +1,32 @@
.. default-role:: code
================================
NimScript
================================
Strictly speaking, ``NimScript`` is the subset of Nim that can be evaluated
Strictly speaking, `NimScript` is the subset of Nim that can be evaluated
by Nim's builtin virtual machine (VM). This VM is used for Nim's compiletime
function evaluation features.
The ``nim`` executable processes the ``.nims`` configuration files in
The `nim` executable processes the `.nims` configuration files in
the following directories (in this order; later files overwrite
previous settings):
1) If environment variable ``XDG_CONFIG_HOME`` is defined,
``$XDG_CONFIG_HOME/nim/config.nims`` or
``~/.config/nim/config.nims`` (POSIX) or
``%APPDATA%/nim/config.nims`` (Windows). This file can be skipped
with the ``--skipUserCfg`` command line option.
2) ``$parentDir/config.nims`` where ``$parentDir`` stands for any
1) If environment variable `XDG_CONFIG_HOME` is defined,
`$XDG_CONFIG_HOME/nim/config.nims` or
`~/.config/nim/config.nims` (POSIX) or
`%APPDATA%/nim/config.nims` (Windows). This file can be skipped
with the `--skipUserCfg` command line option.
2) `$parentDir/config.nims` where `$parentDir` stands for any
parent directory of the project file's path. These files can be
skipped with the ``--skipParentCfg`` command line option.
3) ``$projectDir/config.nims`` where ``$projectDir`` stands for the
project's path. This file can be skipped with the ``--skipProjCfg``
skipped with the `--skipParentCfg` command line option.
3) `$projectDir/config.nims` where `$projectDir` stands for the
project's path. This file can be skipped with the `--skipProjCfg`
command line option.
4) A project can also have a project specific configuration file named
``$project.nims`` that resides in the same directory as
``$project.nim``. This file can be skipped with the same
``--skipProjCfg`` command line option.
`$project.nims` that resides in the same directory as
`$project.nim`. This file can be skipped with the same
`--skipProjCfg` command line option.
For available procs and implementation details see `nimscript <nimscript.html>`_.
@@ -36,13 +38,13 @@ NimScript is subject to some limitations caused by the implementation of the VM
(virtual machine):
* Nim's FFI (foreign function interface) is not available in NimScript. This
means that any stdlib module which relies on ``importc`` can not be used in
means that any stdlib module which relies on `importc` can not be used in
the VM.
* ``ptr`` operations are are hard to emulate with the symbolic representation
* `ptr` operations are are hard to emulate with the symbolic representation
the VM uses. They are available and tested extensively but there are bugs left.
* ``var T`` function arguments rely on ``ptr`` operations internally and might
* `var T` function arguments rely on `ptr` operations internally and might
also be problematic in some cases.
* More than one level of `ref` is generally not supported (for example, the type
@@ -50,7 +52,7 @@ NimScript is subject to some limitations caused by the implementation of the VM
* Multimethods are not available.
* ``random.randomize()`` requires an ``int64`` explicitly passed as argument, you *must* pass a Seed integer.
* `random.randomize()` requires an `int64` explicitly passed as argument, you *must* pass a Seed integer.
Standard library modules
@@ -109,11 +111,11 @@ See also:
NimScript as a configuration file
=================================
A command-line switch ``--FOO`` is written as ``switch("FOO")`` in
NimScript. Similarly, command-line ``--FOO:VAL`` translates to
``switch("FOO", "VAL")``.
A command-line switch `--FOO` is written as `switch("FOO")` in
NimScript. Similarly, command-line `--FOO:VAL` translates to
`switch("FOO", "VAL")`.
Here are few examples of using the ``switch`` proc:
Here are few examples of using the `switch` proc:
.. code-block:: nim
# command-line: --opt:size
@@ -123,7 +125,7 @@ Here are few examples of using the ``switch`` proc:
# command-line: --forceBuild
switch("forceBuild")
NimScripts also support ``--`` templates for convenience, which look
NimScripts also support `--` templates for convenience, which look
like command-line switches written as-is in the NimScript file. So the
above example can be rewritten as:
@@ -133,17 +135,17 @@ above example can be rewritten as:
--forceBuild
**Note**: In general, the *define* switches can also be set in
NimScripts using ``switch`` or ``--``, as shown in above
examples. Only the ``release`` define (``-d:release``) cannot be set
NimScripts using `switch` or `--`, as shown in above
examples. Only the `release` define (`-d:release`) cannot be set
in NimScripts.
NimScript as a build tool
=========================
The ``task`` template that the ``system`` module defines allows a NimScript
The `task` template that the `system` module defines allows a NimScript
file to be used as a build tool. The following example defines a
task ``build`` that is an alias for the ``c`` command:
task `build` that is an alias for the `c` command:
.. code-block:: nim
task build, "builds an example":
@@ -155,11 +157,11 @@ In fact, as a convention the following tasks should be available:
========= ===================================================
Task Description
========= ===================================================
``help`` List all the available NimScript tasks along with their docstrings.
``build`` Build the project with the required
backend (``c``, ``cpp`` or ``js``).
``tests`` Runs the tests belonging to the project.
``bench`` Runs benchmarks belonging to the project.
`help` List all the available NimScript tasks along with their docstrings.
`build` Build the project with the required
backend (`c`, `cpp` or `js`).
`tests` Runs the tests belonging to the project.
`bench` Runs benchmarks belonging to the project.
========= ===================================================
@@ -178,7 +180,7 @@ Standalone NimScript
====================
NimScript can also be used directly as a portable replacement for Bash and
Batch files. Use ``nim myscript.nims`` to run ``myscript.nims``. For example,
Batch files. Use `nim myscript.nims` to run `myscript.nims`. For example,
installation of Nimble could be accomplished with this simple script:
.. code-block:: nim
@@ -196,8 +198,8 @@ installation of Nimble could be accomplished with this simple script:
mvFile "nimble" & $id & "/src/nimble".toExe, "bin/nimble".toExe
On Unix, you can also use the shebang ``#!/usr/bin/env nim``, as long as your filename
ends with ``.nims``:
On Unix, you can also use the shebang `#!/usr/bin/env nim`, as long as your filename
ends with `.nims`:
.. code-block:: nim
@@ -206,7 +208,7 @@ ends with ``.nims``:
echo "hello world"
Use ``#!/usr/bin/env -S nim --hints:off`` to disable hints.
Use `#!/usr/bin/env -S nim --hints:off` to disable hints.
Benefits
@@ -268,7 +270,7 @@ Powerful Metaprogramming
NimScript can use Nim's templates, macros, types, concepts, effect tracking system, and more,
you can create modules that work on compiled Nim and also on interpreted NimScript.
``func`` will still check for side effects, ``debugEcho`` also works as expected,
`func` will still check for side effects, `debugEcho` also works as expected,
making it ideal for functional scripting metaprogramming.
This is an example of a third party module that uses macros and templates to
@@ -315,7 +317,7 @@ See the following NimScript:
echo CompileDate
``likely()``, ``unlikely()``, ``static:`` and ``{.compiletime.}``
`likely()`, `unlikely()`, `static:` and `{.compiletime.}`
will produce no code at all when run on NimScript,
but still no error nor warning is produced and the code just works.

View File

@@ -1,3 +1,5 @@
.. default-role:: code
================================
Nim IDE Integration Guide
================================
@@ -11,8 +13,8 @@
Nim differs from many other compilers in that it is really fast,
and being so fast makes it suited to provide external queries for
text editors about the source code being written. Through the
``nimsuggest`` tool, any IDE
can query a ``.nim`` source file and obtain useful information like
`nimsuggest` tool, any IDE
can query a `.nim` source file and obtain useful information like
definition of symbols or suggestions for completion.
This document will guide you through the available options. If you
@@ -33,50 +35,50 @@ Nimsuggest is part of Nim's core. Build it via::
Nimsuggest invocation
=====================
Run it via ``nimsuggest --stdin --debug myproject.nim``. Nimsuggest is a
server that takes queries that are related to ``myproject``. There is some
support so that you can throw random ``.nim`` files which are not part
of ``myproject`` at Nimsuggest too, but usually the query refer to modules/files
that are part of ``myproject``.
Run it via `nimsuggest --stdin --debug myproject.nim`. Nimsuggest is a
server that takes queries that are related to `myproject`. There is some
support so that you can throw random `.nim` files which are not part
of `myproject` at Nimsuggest too, but usually the query refer to modules/files
that are part of `myproject`.
``--stdin`` means that Nimsuggest reads the query from ``stdin``. This is great
`--stdin` means that Nimsuggest reads the query from `stdin`. This is great
for testing things out and playing with it but for an editor communication
via sockets is more reasonable so that is the default. It listens to port 6000
by default.
Nimsuggest is basically a frontend for the nim compiler so ``--path`` flags and
Nimsuggest is basically a frontend for the nim compiler so `--path` flags and
`config files <https://nim-lang.org/docs/nimc.html#compiler-usage-configuration-files>`_
can be used to specify additional dependencies like
``nimsuggest --stdin --debug --path:"dependencies" myproject.nim``.
`nimsuggest --stdin --debug --path:"dependencies" myproject.nim`.
Specifying the location of the query
------------------------------------
Nimsuggest then waits for queries to process. A query consists of a
cryptic 3 letter "command" ``def`` or ``con`` or ``sug`` or ``use`` followed by
cryptic 3 letter "command" `def` or `con` or `sug` or `use` followed by
a location. A query location consists of:
``file.nim``
`file.nim`
This is the name of the module or include file the query refers to.
``dirtyfile.nim``
`dirtyfile.nim`
This is optional.
The ``file`` parameter is enough for static analysis, but IDEs
The `file` parameter is enough for static analysis, but IDEs
tend to have *unsaved buffers* where the user may still be in
the middle of typing a line. In such situations the IDE can
save the current contents to a temporary file and then use the
``dirtyfile.nim`` option to tell Nimsuggest that ``foobar.nim`` should
be taken from ``temporary/foobar.nim``.
`dirtyfile.nim` option to tell Nimsuggest that `foobar.nim` should
be taken from `temporary/foobar.nim`.
``line``
`line`
An integer with the line you are going to query. For the compiler
lines start at **1**.
``col``
`col`
An integer with the column you are going to query. For the
compiler columns start at **0**.
@@ -84,7 +86,7 @@ a location. A query location consists of:
Definitions
-----------
The ``def`` Nimsuggest command performs a query about the definition
The `def` Nimsuggest command performs a query about the definition
of a specific symbol. If available, Nimsuggest will answer with the
type, source file, line/column information and other accessory data
if available like a docstring. With this information an IDE can
@@ -105,7 +107,7 @@ can't find any valid symbol matching the position of the query.
Suggestions
-----------
The ``sug`` Nimsuggest command performs a query about possible
The `sug` Nimsuggest command performs a query about possible
completion symbols at some point in the file.
The typical usage scenario for this option is to call it after the
@@ -118,7 +120,7 @@ Nimsuggest will try to return the suggestions sorted first by scope
Invocation context
------------------
The ``con`` Nimsuggest command is very similar to the suggestions
The `con` Nimsuggest command is very similar to the suggestions
command, but instead of being used after the user has typed a dot
character, this one is meant to be used after the user has typed
an opening brace to start typing parameters.
@@ -127,7 +129,7 @@ an opening brace to start typing parameters.
Symbol usages
-------------
The ``use`` Nimsuggest command lists all usages of the symbol at
The `use` Nimsuggest command lists all usages of the symbol at
a position. IDEs can use this to find all the places in the file
where the symbol is used and offer the user to rename it in all
places at the same time.
@@ -145,15 +147,15 @@ Nimsuggest output is always returned on single lines separated by
tab characters (``\t``). The values of each column are:
1. Three characters indicating the type of returned answer (e.g.
``def`` for definition, ``sug`` for suggestion, etc).
2. Type of the symbol. This can be ``skProc``, ``skLet``, and just
about any of the enums defined in the module ``compiler/ast.nim``.
`def` for definition, `sug` for suggestion, etc).
2. Type of the symbol. This can be `skProc`, `skLet`, and just
about any of the enums defined in the module `compiler/ast.nim`.
3. Fully qualified path of the symbol. If you are querying a symbol
defined in the ``proj.nim`` file, this would have the form
``proj.symbolName``.
defined in the `proj.nim` file, this would have the form
`proj.symbolName`.
4. Type/signature. For variables and enums this will contain the
type of the symbol, for procs, methods and templates this will
contain the full unique signature (e.g. ``proc (File)``).
contain the full unique signature (e.g. `proc (File)`).
5. Full path to the file containing the symbol.
6. Line where the symbol is located in the file. Lines start to
count at **1**.

View File

@@ -1,3 +1,5 @@
.. default-role:: code
Testament is an advanced automatic unittests runner for Nim tests, is used for the development of Nim itself,
offers process isolation for your tests, it can generate statistics about test cases,
supports multiple targets (C, C++, ObjectiveC, JavaScript, etc),
@@ -9,29 +11,29 @@ so can be useful to run your tests, even the most complex ones.
Test files location
===================
By default Testament looks for test files on ``"./tests/*.nim"``.
You can overwrite this pattern glob using ``pattern <glob>``.
By default Testament looks for test files on `"./tests/*.nim"`.
You can overwrite this pattern glob using `pattern <glob>`.
The default working directory path can be changed using
``--directory:"folder/subfolder/"``.
`--directory:"folder/subfolder/"`.
Testament uses the ``nim`` compiler on ``PATH``.
You can change that using ``--nim:"folder/subfolder/nim"``.
Running JavaScript tests with ``--targets:"js"`` requires a working NodeJS on
``PATH``.
Testament uses the `nim` compiler on `PATH`.
You can change that using `--nim:"folder/subfolder/nim"`.
Running JavaScript tests with `--targets:"js"` requires a working NodeJS on
`PATH`.
Options
=======
* ``--print`` Also print results to the console
* ``--simulate`` See what tests would be run but don't run them (for debugging)
* ``--failing`` Only show failing/ignored tests
* ``--targets:"c cpp js objc"`` Run tests for specified targets (default: all)
* ``--nim:path`` Use a particular nim executable (default: ``$PATH/nim``)
* ``--directory:dir`` Change to directory dir before reading the tests or doing anything else.
* ``--colors:on|off`` Turn messages coloring on|off.
* ``--backendLogging:on|off`` Disable or enable backend logging. By default turned on.
* ``--skipFrom:file`` Read tests to skip from ``file`` - one test per line, # comments ignored
* `--print` Also print results to the console
* `--simulate` See what tests would be run but don't run them (for debugging)
* `--failing` Only show failing/ignored tests
* `--targets:"c cpp js objc"` Run tests for specified targets (default: all)
* `--nim:path` Use a particular nim executable (default: `$PATH/nim`)
* `--directory:dir` Change to directory dir before reading the tests or doing anything else.
* `--colors:on|off` Turn messages coloring on|off.
* `--backendLogging:on|off` Disable or enable backend logging. By default turned on.
* `--skipFrom:file` Read tests to skip from `file` - one test per line, # comments ignored
Running a single test
@@ -68,7 +70,7 @@ To search for tests deeper in a directory, use
HTML Reports
============
Generate HTML Reports ``testresults.html`` from unittests,
Generate HTML Reports `testresults.html` from unittests,
you have to run at least 1 test *before* generating a report:
.. code::
@@ -172,7 +174,7 @@ Example "template" **to edit** and write a Testament unittest:
assert 42 == 42, "Assert error message"
* As you can see the "Spec" is just a ``discard """ """``.
* As you can see the "Spec" is just a `discard """ """`.
* Spec has sane defaults, so you don't need to provide them all, any simple assert will work just fine.
* `This is not the full spec of Testament, check the Testament Spec on GitHub, see parseSpec(). <https://github.com/nim-lang/Nim/blob/devel/testament/specs.nim#L238>`_
* `Nim itself uses Testament, so there are plenty of test examples. <https://github.com/nim-lang/Nim/tree/devel/tests>`_

View File

@@ -1,3 +1,5 @@
.. default-role:: code
========================
Tools available with Nim
========================
@@ -9,11 +11,11 @@ The standard distribution ships with the following tools:
document explaining how it works.
- | `Documentation generator <docgen.html>`_
| The builtin document generator ``nim doc`` generates HTML documentation
from ``.nim`` source files.
| The builtin document generator `nim doc` generates HTML documentation
from `.nim` source files.
- | `Nimsuggest for IDE support <nimsuggest.html>`_
| Through the ``nimsuggest`` tool, any IDE can query a ``.nim`` source file
| Through the `nimsuggest` tool, any IDE can query a `.nim` source file
and obtain useful information like the definition of symbols or suggestions for
completion.
@@ -27,11 +29,11 @@ The standard distribution ships with the following tools:
| Nim search and replace utility.
- | nimpretty
| ``nimpretty`` is a Nim source code beautifier,
| `nimpretty` is a Nim source code beautifier,
to format code according to the official style guide.
- | `testament <https://nim-lang.github.io/Nim/testament.html>`_
| ``testament`` is an advanced automatic *unittests runner* for Nim tests,
| `testament` is an advanced automatic *unittests runner* for Nim tests,
is used for the development of Nim itself, offers process isolation for your tests,
it can generate statistics about test cases, supports multiple targets (C, JS, etc),
`simulated Dry-Runs <https://en.wikipedia.org/wiki/Dry_run_(testing)>`_,

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,5 @@
.. default-role:: code
======================
Nim Tutorial (Part II)
======================
@@ -24,7 +26,7 @@ Pragmas
Pragmas are Nim's method to give the compiler additional information/
commands without introducing a massive number of new keywords. Pragmas are
enclosed in the special ``{.`` and ``.}`` curly dot brackets. This tutorial
enclosed in the special `{.` and `.}` curly dot brackets. This tutorial
does not cover pragmas. See the `manual <manual.html#pragmas>`_ or `user guide
<nimc.html#additional-features>`_ for a description of the available
pragmas.
@@ -45,11 +47,11 @@ Inheritance
Inheritance in Nim is entirely optional. To enable inheritance with
runtime type information the object needs to inherit from
``RootObj``. This can be done directly, or indirectly by
inheriting from an object that inherits from ``RootObj``. Usually
types with inheritance are also marked as ``ref`` types even though
`RootObj`. This can be done directly, or indirectly by
inheriting from an object that inherits from `RootObj`. Usually
types with inheritance are also marked as `ref` types even though
this isn't strictly enforced. To check at runtime if an object is of a certain
type, the ``of`` operator can be used.
type, the `of` operator can be used.
.. code-block:: nim
:test: "nim c $1"
@@ -69,16 +71,16 @@ type, the ``of`` operator can be used.
student = Student(name: "Anton", age: 5, id: 2)
echo student[]
Inheritance is done with the ``object of`` syntax. Multiple inheritance is
currently not supported. If an object type has no suitable ancestor, ``RootObj``
Inheritance is done with the `object of` syntax. Multiple inheritance is
currently not supported. If an object type has no suitable ancestor, `RootObj`
can be used as its ancestor, but this is only a convention. Objects that have
no ancestor are implicitly ``final``. You can use the ``inheritable`` pragma
to introduce new object roots apart from ``system.RootObj``. (This is used
no ancestor are implicitly `final`. You can use the `inheritable` pragma
to introduce new object roots apart from `system.RootObj`. (This is used
in the GTK wrapper for instance.)
Ref objects should be used whenever inheritance is used. It isn't strictly
necessary, but with non-ref objects assignments such as ``let person: Person =
Student(id: 123)`` will truncate subclass fields.
necessary, but with non-ref objects assignments such as `let person: Person =
Student(id: 123)` will truncate subclass fields.
**Note**: Composition (*has-a* relation) is often preferable to inheritance
(*is-a* relation) for simple code reuse. Since objects are value types in
@@ -111,7 +113,7 @@ Example:
Type conversions
----------------
Nim distinguishes between `type casts`:idx: and `type conversions`:idx:.
Casts are done with the ``cast`` operator and force the compiler to
Casts are done with the `cast` operator and force the compiler to
interpret a bit pattern to be of another type.
Type conversions are a much more polite way to convert a type into another:
@@ -119,15 +121,15 @@ They preserve the abstract *value*, not necessarily the *bit-pattern*. If a
type conversion is not possible, the compiler complains or an exception is
raised.
The syntax for type conversions is ``destination_type(expression_to_convert)``
The syntax for type conversions is `destination_type(expression_to_convert)`
(like an ordinary call):
.. code-block:: nim
proc getID(x: Person): int =
Student(x).id
The ``InvalidObjectConversionDefect`` exception is raised if ``x`` is not a
``Student``.
The `InvalidObjectConversionDefect` exception is raised if `x` is not a
`Student`.
Object variants
@@ -150,7 +152,7 @@ An example:
nkSub, # a subtraction
nkIf # an if statement
Node = ref object
case kind: NodeKind # the ``kind`` field is the discriminator
case kind: NodeKind # the `kind` field is the discriminator
of nkInt: intVal: int
of nkFloat: floatVal: float
of nkString: strVal: string
@@ -173,9 +175,9 @@ Method call syntax
------------------
There is a syntactic sugar for calling routines:
The syntax ``obj.method(args)`` can be used instead of ``method(obj, args)``.
The syntax `obj.method(args)` can be used instead of `method(obj, args)`.
If there are no remaining arguments, the parentheses can be omitted:
``obj.len`` (instead of ``len(obj)``).
`obj.len` (instead of `len(obj)`).
This method call syntax is not restricted to objects, it can be used
for any type:
@@ -229,10 +231,10 @@ is needed:
new s
s.host = 34 # same as `host=`(s, 34)
(The example also shows ``inline`` procedures.)
(The example also shows `inline` procedures.)
The ``[]`` array access operator can be overloaded to provide
The `[]` array access operator can be overloaded to provide
`array properties`:idx:\ :
.. code-block:: nim
@@ -258,14 +260,14 @@ The ``[]`` array access operator can be overloaded to provide
else: assert(false)
The example is silly, since a vector is better modelled by a tuple which
already provides ``v[]`` access.
already provides `v[]` access.
Dynamic dispatch
----------------
Procedures always use static dispatch. For dynamic dispatch replace the
``proc`` keyword by ``method``:
`proc` keyword by `method`:
.. code-block:: nim
:test: "nim c $1"
@@ -289,12 +291,12 @@ Procedures always use static dispatch. For dynamic dispatch replace the
echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4)))
Note that in the example the constructors ``newLit`` and ``newPlus`` are procs
because it makes more sense for them to use static binding, but ``eval`` is a
Note that in the example the constructors `newLit` and `newPlus` are procs
because it makes more sense for them to use static binding, but `eval` is a
method because it requires dynamic binding.
**Note:** Starting from Nim 0.20, to use multi-methods one must explicitly pass
``--multimethods:on`` when compiling.
`--multimethods:on` when compiling.
In a multi-method all parameters that have an object type are used for the
dispatching:
@@ -324,7 +326,7 @@ dispatching:
As the example demonstrates, invocation of a multi-method cannot be ambiguous:
Collide 2 is preferred over collide 1 because the resolution works from left to
right. Thus ``Unit, Thing`` is preferred over ``Thing, Unit``.
right. Thus `Unit, Thing` is preferred over `Thing, Unit`.
**Performance note**: Nim does not produce a virtual method table, but
generates dispatch trees. This avoids the expensive indirect branch for method
@@ -338,19 +340,19 @@ Exceptions
In Nim exceptions are objects. By convention, exception types are
suffixed with 'Error'. The `system <system.html>`_ module defines an
exception hierarchy that you might want to stick to. Exceptions derive from
``system.Exception``, which provides the common interface.
`system.Exception`, which provides the common interface.
Exceptions have to be allocated on the heap because their lifetime is unknown.
The compiler will prevent you from raising an exception created on the stack.
All raised exceptions should at least specify the reason for being raised in
the ``msg`` field.
the `msg` field.
A convention is that exceptions should be raised in *exceptional* cases,
they should not be used as an alternative method of control flow.
Raise statement
---------------
Raising an exception is done with the ``raise`` statement:
Raising an exception is done with the `raise` statement:
.. code-block:: nim
:test: "nim c $1"
@@ -360,9 +362,9 @@ Raising an exception is done with the ``raise`` statement:
e.msg = "the request to the OS failed"
raise e
If the ``raise`` keyword is not followed by an expression, the last exception
If the `raise` keyword is not followed by an expression, the last exception
is *re-raised*. For the purpose of avoiding repeating this common code pattern,
the template ``newException`` in the ``system`` module can be used:
the template `newException` in the `system` module can be used:
.. code-block:: nim
raise newException(OSError, "the request to the OS failed")
@@ -371,7 +373,7 @@ the template ``newException`` in the ``system`` module can be used:
Try statement
-------------
The ``try`` statement handles exceptions:
The `try` statement handles exceptions:
.. code-block:: nim
:test: "nim c $1"
@@ -399,23 +401,23 @@ The ``try`` statement handles exceptions:
finally:
close(f)
The statements after the ``try`` are executed unless an exception is
raised. Then the appropriate ``except`` part is executed.
The statements after the `try` are executed unless an exception is
raised. Then the appropriate `except` part is executed.
The empty ``except`` part is executed if there is an exception that is
not explicitly listed. It is similar to an ``else`` part in ``if``
The empty `except` part is executed if there is an exception that is
not explicitly listed. It is similar to an `else` part in `if`
statements.
If there is a ``finally`` part, it is always executed after the
If there is a `finally` part, it is always executed after the
exception handlers.
The exception is *consumed* in an ``except`` part. If an exception is not
The exception is *consumed* in an `except` part. If an exception is not
handled, it is propagated through the call stack. This means that often
the rest of the procedure - that is not within a ``finally`` clause -
the rest of the procedure - that is not within a `finally` clause -
is not executed (if an exception occurs).
If you need to *access* the actual exception object or message inside an
``except`` branch you can use the `getCurrentException()
`except` branch you can use the `getCurrentException()
<system.html#getCurrentException>`_ and `getCurrentExceptionMsg()
<system.html#getCurrentExceptionMsg>`_ procs from the `system <system.html>`_
module. Example:
@@ -433,10 +435,10 @@ module. Example:
Annotating procs with raised exceptions
---------------------------------------
Through the use of the optional ``{.raises.}`` pragma you can specify that a
Through the use of the optional `{.raises.}` pragma you can specify that a
proc is meant to raise a specific set of exceptions, or none at all. If the
``{.raises.}`` pragma is used, the compiler will verify that this is true. For
instance, if you specify that a proc raises ``IOError``, and at some point it
`{.raises.}` pragma is used, the compiler will verify that this is true. For
instance, if you specify that a proc raises `IOError`, and at some point it
(or one of the procs it calls) starts raising a new exception the compiler will
prevent that proc from compiling. Usage example:
@@ -453,11 +455,11 @@ stopped validating the pragma and the raised exception not being caught, along
with the file and line where the uncaught exception is being raised, which may
help you locate the offending code which has changed.
If you want to add the ``{.raises.}`` pragma to existing code, the compiler can
also help you. You can add the ``{.effects.}`` pragma statement to your proc and
If you want to add the `{.raises.}` pragma to existing code, the compiler can
also help you. You can add the `{.effects.}` pragma statement to your proc and
the compiler will output all inferred effects up to that point (exception
tracking is part of Nim's effect system). Another more roundabout way to
find out the list of exceptions raised by a proc is to use the Nim ``doc``
find out the list of exceptions raised by a proc is to use the Nim `doc`
command which generates documentation for a whole module and decorates all
procs with the list of raised exceptions. You can read more about Nim's
`effect system and related pragmas in the manual <manual.html#effect-system>`_.
@@ -468,14 +470,14 @@ Generics
Generics are Nim's means to parametrize procs, iterators or types
with `type parameters`:idx:. Generic parameters are written within square
brackets, for example ``Foo[T]``. They are most useful for efficient type safe
brackets, for example `Foo[T]`. They are most useful for efficient type safe
containers:
.. code-block:: nim
:test: "nim c $1"
type
BinaryTree*[T] = ref object # BinaryTree is a generic type with
# generic param ``T``
# generic param `T`
le, ri: BinaryTree[T] # left and right subtrees; may be nil
data: T # the data stored in a node
@@ -491,8 +493,8 @@ containers:
else:
var it = root
while it != nil:
# compare the data items; uses the generic ``cmp`` proc
# that works for any type that has a ``==`` and ``<`` operator
# compare the data items; uses the generic `cmp` proc
# that works for any type that has a `==` and `<` operator
var c = cmp(it.data, n.data)
if c < 0:
if it.le == nil:
@@ -522,19 +524,19 @@ containers:
n = n.le # and follow the left pointer
var
root: BinaryTree[string] # instantiate a BinaryTree with ``string``
add(root, newNode("hello")) # instantiates ``newNode`` and ``add``
add(root, "world") # instantiates the second ``add`` proc
root: BinaryTree[string] # instantiate a BinaryTree with `string`
add(root, newNode("hello")) # instantiates `newNode` and `add`
add(root, "world") # instantiates the second `add` proc
for str in preorder(root):
stdout.writeLine(str)
The example shows a generic binary tree. Depending on context, the brackets are
used either to introduce type parameters or to instantiate a generic proc,
iterator or type. As the example shows, generics work with overloading: the
best match of ``add`` is used. The built-in ``add`` procedure for sequences
is not hidden and is used in the ``preorder`` iterator.
best match of `add` is used. The built-in `add` procedure for sequences
is not hidden and is used in the `preorder` iterator.
There is a special ``[:T]`` syntax when using generics with the method call syntax:
There is a special `[:T]` syntax when using generics with the method call syntax:
.. code-block:: nim
:test: "nim c $1"
@@ -567,14 +569,14 @@ Example:
assert(5 != 6) # the compiler rewrites that to: assert(not (5 == 6))
The ``!=``, ``>``, ``>=``, ``in``, ``notin``, ``isnot`` operators are in fact
templates: this has the benefit that if you overload the ``==`` operator,
the ``!=`` operator is available automatically and does the right thing. (Except
The `!=`, `>`, `>=`, `in`, `notin`, `isnot` operators are in fact
templates: this has the benefit that if you overload the `==` operator,
the `!=` operator is available automatically and does the right thing. (Except
for IEEE floating point numbers - NaN breaks basic boolean logic.)
``a > b`` is transformed into ``b < a``.
``a in b`` is transformed into ``contains(b, a)``.
``notin`` and ``isnot`` have the obvious meanings.
`a > b` is transformed into `b < a`.
`a in b` is transformed into `contains(b, a)`.
`notin` and `isnot` have the obvious meanings.
Templates are especially useful for lazy evaluation purposes. Consider a
simple proc for logging:
@@ -591,11 +593,11 @@ simple proc for logging:
x = 4
log("x has the value: " & $x)
This code has a shortcoming: if ``debug`` is set to false someday, the quite
expensive ``$`` and ``&`` operations are still performed! (The argument
This code has a shortcoming: if `debug` is set to false someday, the quite
expensive `$` and `&` operations are still performed! (The argument
evaluation for procedures is *eager*).
Turning the ``log`` proc into a template solves this problem:
Turning the `log` proc into a template solves this problem:
.. code-block:: nim
:test: "nim c $1"
@@ -609,15 +611,15 @@ Turning the ``log`` proc into a template solves this problem:
x = 4
log("x has the value: " & $x)
The parameters' types can be ordinary types or the meta types ``untyped``,
``typed``, or ``type``. ``type`` suggests that only a type symbol may be given
as an argument, and ``untyped`` means symbol lookups and type resolution is not
The parameters' types can be ordinary types or the meta types `untyped`,
`typed`, or `type`. `type` suggests that only a type symbol may be given
as an argument, and `untyped` means symbol lookups and type resolution is not
performed before the expression is passed to the template.
If the template has no explicit return type,
``void`` is used for consistency with procs and methods.
`void` is used for consistency with procs and methods.
To pass a block of statements to a template, use ``untyped`` for the last parameter:
To pass a block of statements to a template, use `untyped` for the last parameter:
.. code-block:: nim
:test: "nim c $1"
@@ -638,10 +640,10 @@ To pass a block of statements to a template, use ``untyped`` for the last parame
txt.writeLine("line 1")
txt.writeLine("line 2")
In the example the two ``writeLine`` statements are bound to the ``body``
parameter. The ``withFile`` template contains boilerplate code and helps to
In the example the two `writeLine` statements are bound to the `body`
parameter. The `withFile` template contains boilerplate code and helps to
avoid a common bug: to forget to close the file. Note how the
``let fn = filename`` statement ensures that ``filename`` is evaluated only
`let fn = filename` statement ensures that `filename` is evaluated only
once.
Example: Lifting Procs
@@ -653,7 +655,7 @@ Example: Lifting Procs
template liftScalarProc(fname) =
## Lift a proc taking one scalar parameter and returning a
## scalar value (eg ``proc sssss[T](x: T): float``),
## scalar value (eg `proc sssss[T](x: T): float`),
## to provide templated procs that can handle a single
## parameter of seq[T] or nested seq[seq[]] or the same type
##
@@ -675,15 +677,15 @@ Compilation to JavaScript
Nim code can be compiled to JavaScript. However in order to write
JavaScript-compatible code you should remember the following:
- ``addr`` and ``ptr`` have slightly different semantic meaning in JavaScript.
- `addr` and `ptr` have slightly different semantic meaning in JavaScript.
It is recommended to avoid those if you're not sure how they are translated
to JavaScript.
- ``cast[T](x)`` in JavaScript is translated to ``(x)``, except for casting
- `cast[T](x)` in JavaScript is translated to `(x)`, except for casting
between signed/unsigned ints, in which case it behaves as static cast in
C language.
- ``cstring`` in JavaScript means JavaScript string. It is a good practice to
use ``cstring`` only when it is semantically appropriate. E.g. don't use
``cstring`` as a binary data buffer.
- `cstring` in JavaScript means JavaScript string. It is a good practice to
use `cstring` only when it is semantically appropriate. E.g. don't use
`cstring` as a binary data buffer.
Part 3

View File

@@ -1,3 +1,5 @@
.. default-role:: code
=======================
Nim Tutorial (Part III)
=======================

View File

@@ -1,3 +1,5 @@
.. default-role:: code
The System module imports several separate modules, and their documentation
is in separate files:
@@ -36,7 +38,7 @@ Proc Usage
* `strutils module <strutils.html>`_ for common string functions
* `strformat module <strformat.html>`_ for string interpolation and formatting
* `unicode module <unicode.html>`_ for Unicode UTF-8 handling
* `strscans <strscans.html>`_ for ``scanf`` and ``scanp`` macros, which offer
* `strscans <strscans.html>`_ for `scanf` and `scanp` macros, which offer
easier substring extraction than regular expressions
* `strtabs module <strtabs.html>`_ for efficient hash tables
(dictionaries, in some programming languages) mapping from strings to strings