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
commit 83ae70cb54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 1402 additions and 1350 deletions

View file

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

View file

@ -1,3 +1,5 @@
.. default-role:: code
================================ ================================
Nim Backend Integration Nim Backend Integration
================================ ================================
@ -13,8 +15,8 @@ Introduction
============ ============
The `Nim Compiler User Guide <nimc.html>`_ documents the typical The `Nim Compiler User Guide <nimc.html>`_ documents the typical
compiler invocation, using the ``compile`` or ``c`` command to transform a 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 `.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 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 to compile to C++, Objective-C, or JavaScript. This document tries to
concentrate in a single place all the backend and interfacing options. 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 Objective-C targets and the JavaScript target. `The C like targets
<#backends-the-c-like-targets>`_ creates source files that can be compiled <#backends-the-c-like-targets>`_ creates source files that can be compiled
into a library or a final executable. `The JavaScript target 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 reference from an HTML file or create a `standalone Node.js program
<http://nodejs.org>`_. <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 //compileToOC, objc compile project to Objective C code
The most significant difference between these commands is that if you look 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 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 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- into a project using any of these languages. Here are some typical command-
@ -64,17 +66,17 @@ or compiler/linker commands.
The JavaScript target 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. 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, 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 Features or modules that the JavaScript platform does not support are not
available. This includes: available. This includes:
* manual memory management (``alloc``, etc.) * manual memory management (`alloc`, etc.)
* casting and other unsafe operations (``cast`` operator, ``zeroMem``, etc.) * casting and other unsafe operations (`cast` operator, `zeroMem`, etc.)
* file management * file management
* OS-specific operations * OS-specific operations
* threading, coroutines * 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 and more support will come in the future (for instance, Node.js bindings
to get OS info). to get OS info).
To compile a Nim module into a ``.js`` file use the ``js`` command; the 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`` 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: file. However, you can also run the code with `nodejs`:idx:
(`<http://nodejs.org>`_):: (`<http://nodejs.org>`_)::
nim js -d:nodejs -r examples/hallo.nim 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). 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 Nim code can interface with the backend through the `Foreign function
interface <manual.html#foreign-function-interface>`_ mainly through the interface <manual.html#foreign-function-interface>`_ mainly through the
`importc pragma <manual.html#foreign-function-interface-importc-pragma>`_. `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++ in Nim and is available in all the target backends (JavaScript too). The C++
or Objective-C backends have their respective `ImportCpp or Objective-C backends have their respective `ImportCpp
<manual.html#implementation-specific-pragmas-importcpp-pragma>`_ and <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 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 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 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 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 statically or dynamically. The preferred way of integrating native code is to
@ -148,7 +150,7 @@ interface.
C invocation example C invocation example
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
Create a ``logic.c`` file with the following content: Create a `logic.c` file with the following content:
.. code-block:: c .. code-block:: c
int addTwoIntegers(int a, int b) int addTwoIntegers(int a, int b)
@ -156,7 +158,7 @@ Create a ``logic.c`` file with the following content:
return a + b; return a + b;
} }
Create a ``calculator.nim`` file with the following content: Create a `calculator.nim` file with the following content:
.. code-block:: nim .. code-block:: nim
@ -166,26 +168,26 @@ Create a ``calculator.nim`` file with the following content:
when isMainModule: when isMainModule:
echo addTwoIntegers(3, 7) echo addTwoIntegers(3, 7)
With these two files in place, you can run ``nim c -r calculator.nim`` and 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 the Nim compiler will compile the `logic.c` file in addition to
``calculator.nim`` and link both into an executable, which outputs ``10`` when `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 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:: Unix commands::
$ gcc -c logic.c $ gcc -c logic.c
$ ar rvs mylib.a logic.o $ ar rvs mylib.a logic.o
$ nim c --passL:mylib.a -r calculator.nim $ nim c --passL:mylib.a -r calculator.nim
Just like in this example we pass the path to the ``mylib.a`` library (and we 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 could as well pass `logic.o`) we could be passing switches to link any other
static C library. static C library.
JavaScript invocation example JavaScript invocation example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Create a ``host.html`` file with the following content: Create a `host.html` file with the following content:
.. code-block:: .. code-block::
@ -199,7 +201,7 @@ Create a ``host.html`` file with the following content:
<script type="text/javascript" src="calculator.js"></script> <script type="text/javascript" src="calculator.js"></script>
</body></html> </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): from the previous section):
.. code-block:: nim .. code-block:: nim
@ -209,9 +211,9 @@ from the previous section):
when isMainModule: when isMainModule:
echo addTwoIntegers(3, 7) echo addTwoIntegers(3, 7)
Compile the Nim code to JavaScript with ``nim js -o:calculator.js 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 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 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 `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 or take a look at `karax <https://github.com/pragmagic/karax>`_ for how to
develop browser-based applications. develop browser-based applications.
@ -222,29 +224,29 @@ Backend code calling Nim
Backend code can interface with Nim code exposed through the `exportc Backend code can interface with Nim code exposed through the `exportc
pragma <manual.html#foreign-function-interface-exportc-pragma>`_. The 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 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 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. symbol for the backend in case the symbol rules don't match.
The JavaScript target doesn't have any further interfacing considerations The JavaScript target doesn't have any further interfacing considerations
since it also has garbage collection, but the C targets require you to 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 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 the compiler will assume certain types for the return value and parameters
which will likely make your program crash at runtime. 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 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 code.
Nim invocation example from C 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 .. code-block:: nim
@ -254,7 +256,7 @@ Create a ``fib.nim`` file with the following content:
else: else:
result = fib(a - 1) + fib(a - 2) 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 .. 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 $ 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 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 object files into a final binary, and explicitly generate a header file for C
integration. All the generated files are placed into the ``nimcache`` integration. All the generated files are placed into the `nimcache`
directory. That's why the next command compiles the ``maths.c`` source plus 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 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. 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:: also ask the Nim compiler to generate a statically linked library::
$ nim c --app:staticLib --noMain --header fib.nim $ nim c --app:staticLib --noMain --header fib.nim
$ gcc -o m -Inimcache -Ipath/to/nim/lib libfib.nim.a maths.c $ 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 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 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 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 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:: .. code-block::
@ -311,7 +313,7 @@ Create a ``mhost.html`` file with the following content:
</script> </script>
</body></html> </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): from the previous section):
.. code-block:: nim .. code-block:: nim
@ -322,10 +324,10 @@ from the previous section):
else: else:
result = fib(a - 1) + fib(a - 2) result = fib(a - 1) + fib(a - 2)
Compile the Nim code to JavaScript with ``nim js -o:fib.js fib.nim`` and 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 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 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 earlier, JavaScript doesn't require an initialization call to `NimMain` or
a similar function and you can call the exported Nim proc directly. 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 The `nimcache`:idx: directory is generated during compilation and will hold
either temporary or final files depending on your backend target. The default 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 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. <nimc.html#compiler-usage-commandminusline-switches>`_ to change it.
Memory management 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 JavaScript already provides automatic memory management, you can freely pass
objects between the two languages without problems. In C and derivate languages 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 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 The manual mentions that `Nim strings are implicitly convertible to
cstrings <manual.html#types-cstring-type>`_ which makes interaction usually cstrings <manual.html#types-cstring-type>`_ which makes interaction usually
painless. Most C functions accepting a Nim string converted to a 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 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 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 freed with `GC_ref <system.html#GC_ref,string>`_ and `GC_unref
<system.html#GC_unref,string>`_. <system.html#GC_unref,string>`_.
A similar thing happens with C code invoking Nim code which returns a 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 .. 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) result = "Hey there C code! " & $rand(100)
Since Nim's garbage collector is not aware of the C code, once the 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``. `gimme` proc has finished it can reclaim the memory of the `cstring`.
However, from a practical standpoint, the C code invoking the ``gimme`` 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 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 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 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 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 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 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. these for the Nim side should be enough.
Thread coordination 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 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 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. 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 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 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 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 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 This document aims to be a precise specification about how
move semantics and destructors work in Nim. move semantics and destructors work in Nim.
@ -89,12 +91,12 @@ written as:
Lifetime-tracking hooks 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 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>`_. "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 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. `distinct` type) that are called implicitly by the compiler.
(Note: The word "hook" here does not imply any kind of dynamic binding (Note: The word "hook" here does not imply any kind of dynamic binding
or runtime indirections, the implicit calls are statically bound and 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 they go out of scope or when the routine they were declared in is about
to return. 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 .. code-block:: nim
proc `=destroy`(x: var T) proc `=destroy`(x: var T)
The general pattern in ``=destroy`` looks like: The general pattern in `=destroy` looks like:
.. code-block:: nim .. 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 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 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 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 (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 default value is written as `wasMoved(x)`. When not provided the compiler
is using a combination of `=destroy` and `copyMem` instead. This is efficient 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 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. 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 .. code-block:: nim
proc `=sink`(dest: var T; source: T) proc `=sink`(dest: var T; source: T)
The general pattern in ``=sink`` looks like: The general pattern in `=sink` looks like:
.. code-block:: nim .. code-block:: nim
@ -156,25 +158,25 @@ The general pattern in ``=sink`` looks like:
dest.field = source.field 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. How self-assignments are handled is explained later in this document.
`=copy` hook `=copy` hook
--------------- ---------------
The ordinary assignment in Nim conceptually copies the values. The ``=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`` is called for assignments that couldn't be transformed into `=sink`
operations. 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 .. code-block:: nim
proc `=copy`(dest: var T; source: T) proc `=copy`(dest: var T; source: T)
The general pattern in ``=copy`` looks like: The general pattern in `=copy` looks like:
.. code-block:: nim .. code-block:: nim
@ -186,48 +188,48 @@ The general pattern in ``=copy`` looks like:
dest.field = duplicateResource(source.field) 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: that otherwise would lead to a copy is prevented at compile-time. This looks like:
.. code-block:: nim .. code-block:: nim
proc `=copy`(dest: var T; source: T) {.error.} proc `=copy`(dest: var T; source: T) {.error.}
but a custom error message (e.g., ``{.error: "custom error".}``) will not be emitted 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. by the compiler. Notice that there is no `=` before the `{.error.}` pragma.
Move semantics Move semantics
============== ==============
A "move" can be regarded as an optimized copy operation. If the source of the 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 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 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 Swap
==== ====
The need to check for self-assignments and also the need to destroy previous 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 objects inside `=copy` and `=sink` is a strong indicator to treat
``system.swap`` as a builtin primitive of its own that simply swaps every `system.swap` as a builtin primitive of its own that simply swaps every
field in the involved objects via ``copyMem`` or a comparable mechanism. field in the involved objects via `copyMem` or a comparable mechanism.
In other words, ``swap(a, b)`` is **not** implemented In other words, `swap(a, b)` is **not** implemented
as ``let tmp = move(b); b = move(a); a = move(tmp)``. as `let tmp = move(b); b = move(a); a = move(tmp)`.
This has further consequences: This has further consequences:
* Objects that contain pointers that point to the same object are not supported * 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. 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 Sink parameters
=============== ===============
To move a variable into a collection usually ``sink`` parameters are involved. 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. 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 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 proven to be the last usage of the location, a copy is done instead and this
copy is then passed to the sink parameter. copy is then passed to the sink parameter.
@ -235,9 +237,9 @@ copy is then passed to the sink parameter.
A sink parameter A sink parameter
*may* be consumed once in the proc's body but doesn't have to be consumed at all. *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 The reason for this is that signatures
like ``proc put(t: var Table; k: sink Key, v: sink Value)`` should be possible 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 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, `k` already exists in the table. Sink parameters enable an affine type system,
not a linear type system. not a linear type system.
The employed static analysis is limited and only concerned with local variables; 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] 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 .. code-block:: nim
@ -294,9 +296,9 @@ Rewrite rules
**Note**: There are two different allowed implementation strategies: **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. 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 The current implementation follows strategy (2). This means that resources are
destroyed at the scope exit. 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 Object and array construction is treated as a function call where the
function has ``sink`` parameters. function has `sink` parameters.
Destructor removal 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 out. An implementation is encouraged to exploit this in order to improve
efficiency and code sizes. The current implementation does perform this efficiency and code sizes. The current implementation does perform this
optimization. optimization.
@ -374,22 +376,22 @@ optimization.
Self assignments 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. it's subtle.
The simple case of ``x = x`` cannot be turned The simple case of `x = x` cannot be turned
into ``=sink(x, x); wasMoved(x)`` because that would lose ``x``'s value. into `=sink(x, x); wasMoved(x)` because that would lose `x`'s value.
The solution is that simple self-assignments that consist of The solution is that simple self-assignments that consist of
- Symbols: ``x = x`` - Symbols: `x = x`
- Field access: ``x.f = x.f`` - Field access: `x.f = x.f`
- Array, sequence or string access with indices known at compile-time: ``x[0] = x[0]`` - Array, sequence or string access with indices known at compile-time: `x[0] = x[0]`
are transformed into an empty statement that does nothing. are transformed into an empty statement that does nothing.
The compiler is free to optimize further cases. The compiler is free to optimize further cases.
The complex case looks like a variant of ``x = f(x)``, we consider The complex case looks like a variant of `x = f(x)`, we consider
``x = select(rand() < 0.5, x, y)`` here: `x = select(rand() < 0.5, x, y)` here:
.. code-block:: nim .. code-block:: nim
@ -450,17 +452,17 @@ self-assignments.
Lent type 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 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. 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. 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 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 .. code-block:: nim
@ -494,9 +496,9 @@ for expressions of type ``lent T`` or of type ``var T``.
The .cursor annotation 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 "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: one can break up cycles declaratively:
.. code-block:: nim .. 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. involved in the reference counting, it is a raw pointer without runtime checks.
Automatic reference counting also has the disadvantage that it introduces overhead 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: to avoid this overhead:
.. code-block:: nim .. code-block:: nim
@ -521,11 +523,11 @@ to avoid this overhead:
it = it.next 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 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 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 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 to be safe, but for `ptr` the compiler has to remain silent about possible
problems. problems.
@ -556,13 +558,13 @@ indirections:
Hook lifting Hook lifting
============ ============
The hooks of a tuple type ``(A, B, ...)`` are generated by lifting the 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 hooks of the involved types `A`, `B`, ... to the tuple type. In
other words, a copy ``x = y`` is implemented other words, a copy `x = y` is implemented
as ``x[0] = y[0]; x[1] = y[1]; ...``, likewise for ``=sink`` and ``=destroy``. 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 Other value-based compound types like `object` and `array` are handled
correspondingly. For ``object`` however, the compiler-generated hooks correspondingly. For `object` however, the compiler-generated hooks
can be overridden. This can also be important to use an alternative traversal 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 of the involved data structure that is more efficient or in order to avoid
deep recursions. deep recursions.
@ -588,18 +590,18 @@ The ability to override a hook leads to a phase ordering problem:
discard 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 it is used. The compiler generates implicit
hooks for all types in *strategic places* so that an explicitly provided hooks for all types in *strategic places* so that an explicitly provided
hook that comes too "late" can be detected reliably. These *strategic places* hook that comes too "late" can be detected reliably. These *strategic places*
have been derived from the rewrite rules and are as follows: have been derived from the rewrite rules and are as follows:
- In the construct ``let/var x = ...`` (var/let binding) - In the construct `let/var x = ...` (var/let binding)
hooks are generated for ``typeof(x)``. hooks are generated for `typeof(x)`.
- In ``x = ...`` (assignment) 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(...))``. - In `f(...)` (function call) hooks are generated for `typeof(f(...))`.
- For every sink parameter ``x: sink T`` the hooks are generated - For every sink parameter `x: sink T` the hooks are generated
for ``typeof(x)``. for `typeof(x)`.
nodestroy pragma 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 literal is shared between different variables which are pointing to it.
The copy operation is deferred until the first write. The copy operation is deferred until the first write.
```nim .. code-block:: nim
var x = "abc" # no copy var x = "abc" # no copy
var y = x # no copy var y = x # no copy
```
The string literal "abc" is stored in static memory and not allocated on the heap. 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. The variable `x` points to the literal and the variable `y` points to the literal too.
There is no copy during assigning operations. There is no copy during assigning operations.
```nim .. code-block:: nim
var x = "abc" # no copy var x = "abc" # no copy
var y = x # no copy var y = x # no copy
y[0] = 'h' # copy y[0] = 'h' # copy
```
The program above shows when the copy operations happen. The program above shows when the copy operations happen.
When mutating the variable `y`, the Nim compiler creates a fresh copy of `x`, When mutating the variable `y`, the Nim compiler creates a fresh copy of `x`,
@ -670,29 +670,27 @@ and the variable `y` becomes a mutable string.
Let's look at a silly example demonstrating this behaviour: Let's look at a silly example demonstrating this behaviour:
```nim .. code-block:: nim
var x = "abc" var x = "abc"
var y = x 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`. The program fails because we need to prepare a fresh copy for the variable `y`.
`prepareMutation` should be called before the address operation. `prepareMutation` should be called before the address operation.
```nim .. code-block:: nim
var x = "abc" var x = "abc"
var y = x var y = x
prepareMutation(y) prepareMutation(y)
moveMem(addr y[0], addr x[0], 3) moveMem(addr y[0], addr x[0], 3)
assert y == "abc" assert y == "abc"
```
Now `prepareMutation` solves the problem. Now `prepareMutation` solves the problem.
It manually creates a fresh copy and makes the variable `y` mutable. It manually creates a fresh copy and makes the variable `y` mutable.
```nim .. code-block:: nim
var x = "abc" var x = "abc"
var y = x var y = x
@ -701,6 +699,5 @@ moveMem(addr y[0], addr x[0], 3)
moveMem(addr y[0], addr x[0], 3) 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" assert y == "abc"
```
No matter how many times `moveMem` is called, the program compiles and runs. 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 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 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 from input .nim files and projects, as well as HTML and LaTeX from input RST
(reStructuredText) files. The output documentation will include the module (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. exported symbols (*), including procedures, types, and variables.
Quick start Quick start
@ -125,12 +127,12 @@ Document Types
HTML 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 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, base filename, or multiple .nim files, outputting multiple .html files and,
optionally, an index file. optionally, an index file.
The ``doc`` command:: The `doc` command::
nim doc sample nim doc sample
Partial Output:: Partial Output::
@ -146,12 +148,12 @@ compiler.
JSON 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 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. contains the same information.
The ``jsondoc`` command:: The `jsondoc` command::
nim jsondoc sample nim jsondoc sample
Output:: Output::
@ -171,10 +173,10 @@ Output::
] ]
} }
Similarly to the old ``doc`` command, the old ``jsondoc`` command has been Similarly to the old `doc` command, the old `jsondoc` command has been
renamed to ``jsondoc0``. renamed to `jsondoc0`.
The ``jsondoc0`` command:: The `jsondoc0` command::
nim jsondoc0 sample nim jsondoc0 sample
Output:: Output::
@ -190,8 +192,8 @@ Output::
} }
] ]
Note that the ``jsondoc`` command outputs it's JSON without pretty-printing it, Note that the `jsondoc` command outputs it's JSON without pretty-printing it,
while ``jsondoc0`` outputs pretty-printed JSON. while `jsondoc0` outputs pretty-printed JSON.
Related Options Related Options
=============== ===============
@ -203,7 +205,7 @@ Project switch
nim doc --project filename.nim nim doc --project filename.nim
This will recursively generate documentation of all nim modules imported 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. belongs to.
@ -214,13 +216,13 @@ Index switch
nim doc --index:on filename.nim nim doc --index:on filename.nim
This will generate an index of all the exported symbols in the input 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 index file is line-oriented (newlines have to be escaped). Each line
represents a tab-separated record of several columns, the first two mandatory, represents a tab-separated record of several columns, the first two mandatory,
the rest optional. See the `Index (idx) file format`_ section for details. 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 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>`_ files in the specified directory to generate a `theindex.html <theindex.html>`_
file. file.
@ -230,28 +232,28 @@ See source switch
:: ::
nim doc --git.url:<url> filename.nim 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 documented item in your source code pointing to the implementation of that
item on a GitHub repository. item on a GitHub repository.
You can click the link to see the implementation of the item. 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`, 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. 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. 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. 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 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 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. specific commit in the output.
@ -259,9 +261,9 @@ Other Input Formats
=================== ===================
The *Nim compiler* also has support for RST (reStructuredText) files with 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 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. supports highlighting of C++ and some other c-like languages.
Usage:: Usage::
@ -270,17 +272,17 @@ Usage::
Output:: Output::
You're reading it! 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. a .tex file instead of .html.
HTML anchor generation 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 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 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 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. 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 Callable type Suffix
------------- -------------- ------------- --------------
proc *empty string* proc *empty string*
macro ``.m`` macro `.m`
method ``.e`` method `.e`
iterator ``.i`` iterator `.i`
template ``.t`` template `.t`
converter ``.c`` converter `.c`
------------- -------------- ------------- --------------
The relationship of type to suffix is made by the proc ``complexName`` in the 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 `compiler/docgen.nim` file. Here are some examples of complex names for
symbols in the `system module <system.html>`_. 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>`_ `#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>`_ `#globalRaiseHook <system.html#globalRaiseHook>`_
* ``const NimVersion = "0.0.0"`` **=>** * `const NimVersion = "0.0.0"` **=>**
`#NimVersion <system.html#NimVersion>`_ `#NimVersion <system.html#NimVersion>`_
* ``proc getTotalMem(): int {.rtl, raises: [], tags: [].}`` **=>** * `proc getTotalMem(): int {.rtl, raises: [], tags: [].}` **=>**
`#getTotalMem, <system.html#getTotalMem>`_ `#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]>`_ `#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]>`_ `#pairs.i,seq[T] <iterators.html#pairs.i,seq[T]>`_
* ``template newException[](exceptn: typedesc; message: string; * `template newException[](exceptn: typedesc; message: string;
parentException: ref Exception = nil): untyped`` **=>** parentException: ref Exception = nil): untyped` **=>**
`#newException.t,typedesc,string,ref.Exception `#newException.t,typedesc,string,ref.Exception
<system.html#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 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 switch <#related-options-index-switch>`_ along with commands to generate
documentation from source or text files. You can programmatically generate documentation from source or text files. You can programmatically generate
indices with the `setIndexTerm() indices with the `setIndexTerm()
<rstgen.html#setIndexTerm,RstGenerator,string,string,string,string,string>`_ <rstgen.html#setIndexTerm,RstGenerator,string,string,string,string,string>`_
and `writeIndexFile() <rstgen.html#writeIndexFile,RstGenerator,string>`_ procs. 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 references so they can be later concatenated into a big index file with
`mergeIndexes() <rstgen.html#mergeIndexes,string>`_. This section documents `mergeIndexes() <rstgen.html#mergeIndexes,string>`_. This section documents
the file format in detail. the file format in detail.
@ -362,7 +364,7 @@ columns is:
1. Mandatory term being indexed. Terms can include quoting according to 1. Mandatory term being indexed. Terms can include quoting according to
Nim's rules (e.g. \`^\`). 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 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 present or is the empty string, the hyperlink will be rendered
using the term. Prefix whitespace indicates that this entry is 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. this as a tooltip after hovering a moment over the hyperlink.
The index generation tools try to differentiate between documentation The index generation tools try to differentiate between documentation
generated from ``.nim`` files and documentation generated from ``.txt`` or generated from `.nim` files and documentation generated from `.txt` or
``.rst`` files. The former are always closely related to source code and `.rst` files. The former are always closely related to source code and
consist mainly of API entries. The latter are generic documents meant for consist mainly of API entries. The latter are generic documents meant for
human reading. 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 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 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 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 Additional resources
@ -402,8 +404,8 @@ Additional resources
`RST Quick Reference `RST Quick Reference
<http://docutils.sourceforge.net/docs/user/rst/quickref.html>`_ <http://docutils.sourceforge.net/docs/user/rst/quickref.html>`_
The output for HTML and LaTeX comes from the ``config/nimdoc.cfg`` and 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 `config/nimdoc.tex.cfg` configuration files. You can add and modify these
files to your project to change the look of the docgen output. files to your project to change the look of the docgen output.
You can import the `packages/docutils/rstgen module <rstgen.html>`_ in your 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. * 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 * 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. * 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, 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. 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 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 adding `.. default-role:: code` to an rst file will also make those render as monospace when rendered directly
in tools such as github. 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). since the syntax is simpler and markdown is more common (likewise, `nim rst2html` also supports it in rst files).
.. code-block:: nim .. code-block:: nim
@ -28,8 +28,8 @@ General Guidelines
Module-level documentation Module-level documentation
-------------------------- --------------------------
Documentation of a module is placed at the top of the module itself. Each line of documentation begins with double hashes (``##``). 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``. Sometimes `##[ multiline docs containing code ]##` is preferable, see `lib/pure/times.nim`.
Code samples are encouraged, and should follow the general RST syntax: Code samples are encouraged, and should follow the general RST syntax:
.. code-block:: Nim .. 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 doAssert addThree(3, 125, 6) == -122
result = x +% y +% z 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 Types
----- -----
@ -116,8 +116,8 @@ Make sure to place the documentation beside or within the object.
.. code-block:: Nim .. code-block:: Nim
type type
## Bad: this documentation disappears because it annotates the ``type`` keyword ## Bad: this documentation disappears because it annotates the `type` keyword
## above, not ``NamedQueue``. ## above, not `NamedQueue`.
NamedQueue*[T] = object NamedQueue*[T] = object
name*: string ## This becomes the main documentation for the object, which name*: string ## This becomes the main documentation for the object, which
## is not what we want. ## is not what we want.
@ -127,7 +127,7 @@ Make sure to place the documentation beside or within the object.
Var, Let, and Const 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 .. code-block:: Nim
@ -137,9 +137,9 @@ When declaring module-wide constants and values, documentation is encouraged. Th
[1,2,3], [1,2,3],
[2,3,1], [2,3,1],
[3,1,2], [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 .. code-block:: Nim

View file

@ -1,3 +1,5 @@
.. default-role:: code
=================================== ===================================
DrNim User Guide 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 DrNim currently only checks the sections of your code that are marked
via ``staticBoundChecks: on``: via `staticBoundChecks: on`:
.. code-block:: nim .. code-block:: nim
@ -31,9 +33,9 @@ overflow errors are *not* prevented. Overflows will be checked for in
the future. the future.
Later versions of the **Nim compiler** will **assume** that the checks inside 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 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 Nim compiler remains unaware of the performed proofs but DrNim will prove
your code. your code.
@ -41,7 +43,7 @@ your code.
Installation 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 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] 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. an index out of bounds error.
@ -82,37 +84,37 @@ DrNim adds 4 additional annotations (pragmas) to Nim:
- `assume`:idx: - `assume`:idx:
These pragmas are ignored by the Nim compiler so that they don't have to 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 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. iteration, it's tied to the loop body it's part of.
Requires Requires
-------- --------
A ``requires`` annotation describes what the function expects to be true A `requires` annotation describes what the function expects to be true
before it's called so that it can perform its operation. A ``requires`` before it's called so that it can perform its operation. A `requires`
annotation is also called a `precondition`:idx:. annotation is also called a `precondition`:idx:.
Ensures Ensures
------- -------
An ``ensures`` annotation describes what will be true after the function An `ensures` annotation describes what will be true after the function
call. An ``ensures`` annotation is also called a `postcondition`:idx:. call. An `ensures` annotation is also called a `postcondition`:idx:.
Assume 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 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 than DrNim. You should add a comment to a paper that proves the proposition
you assume. you assume.
@ -143,12 +145,12 @@ Example: insertionSort
Unfortunately, the invariants required to prove that this code is correct take more Unfortunately, the invariants required to prove that this code is correct take more
code than the imperative instructions. However, this effort can be compensated 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 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]) 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 was performed. For example, the same postcondition is true for this proc
which doesn't sort at all: which doesn't sort at all:
@ -166,8 +168,8 @@ which doesn't sort at all:
Syntax of propositions Syntax of propositions
====================== ======================
The basic syntax is ``ensures|requires|invariant: <prop>``. The basic syntax is `ensures|requires|invariant: <prop>`.
A ``prop`` is either a comparison or a compound:: A `prop` is either a comparison or a compound::
prop = nim_bool_expression prop = nim_bool_expression
| prop 'and' prop | prop 'and' prop
@ -186,17 +188,17 @@ A ``prop`` is either a comparison or a compound::
quantifier = <new identifier> 'in' nim_iteration_expression quantifier = <new identifier> 'in' nim_iteration_expression
``nim_iteration_expression`` here is an ordinary expression of Nim code `nim_iteration_expression` here is an ordinary expression of Nim code
that describes an iteration space, for example ``1..4`` or ``1..<a.len``. 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 `nim_bool_expression` here is an ordinary expression of Nim code of
type ``bool`` like ``a == 3`` or ``23 > a.len``. type `bool` like `a == 3` or `23 > a.len`.
The supported subset of Nim code that can be used in these expressions The supported subset of Nim code that can be used in these expressions
is currently underspecified but ``let`` variables, function parameters is currently underspecified but `let` variables, function parameters
and ``result`` (which represents the function's final result) are amenable and `result` (which represents the function's final result) are amenable
for verification. The expressions must not have any side-effects and must for verification. The expressions must not have any side-effects and must
terminate. terminate.
The operators ``forall``, ``exists``, ``->``, ``<->`` have to imported The operators `forall`, `exists`, `->`, `<->` have to imported
from ``std / logic``. from `std / logic`.

View file

@ -1,3 +1,5 @@
.. default-role:: code
=================================================== ===================================================
Embedded Stack Trace Profiler (ESTP) User Guide 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 the Embedded Stack Trace Profiler (ESTP). The profiler
is *embedded* into your executable. To activate the profiler you need to do: 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 line options
* import the ``nimprof`` module * import the `nimprof` module
* run your program as usual. * 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. 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 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 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. 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 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: find memory leaks. To activate the memory profiler you need to do:
* compile your program with the ``--profiler:off --stackTrace:on -d:memProfiler`` * compile your program with the `--profiler:off --stackTrace:on -d:memProfiler`
command line options. Yes it's ``--profiler:off``. command line options. Yes it's `--profiler:off`.
* import the ``nimprof`` module * import the `nimprof` module
* run your program as usual. * 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. 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 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 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 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 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 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 output stream before parsing. A filter can be used to provide templating
systems or preprocessors. 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 = '#') #? stdtmpl(subsChar = '$', metaChar = '#')
#proc generateXML(name, age: string): string = #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 As the example shows, passing arguments to a filter can be done
just like an ordinary procedure call with named or positional arguments. The 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 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 (or higher) while compiling or `nim check`, Nim lists the processed code after
each filter application. each filter application.
@ -32,8 +34,8 @@ Usage
First, put your SCF code in a separate file with filters specified in the first line. 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 **Note:** You can name your SCF file with any file extension you want, but the
conventional extension is ``.nimf`` conventional extension is `.nimf`
(it used to be ``.tmpl`` but that was too generic, for example preventing github to (it used to be `.tmpl` but that was too generic, for example preventing github to
recognize it as Nim source file). recognize it as Nim source file).
If we use `generateXML` code shown above and call the SCF file `xmlGen.nimf` If we use `generateXML` code shown above and call the SCF file `xmlGen.nimf`
@ -47,7 +49,7 @@ In your `main.nim`:
Pipe operator Pipe operator
============= =============
Filters can be combined with the ``|`` pipe operator:: Filters can be combined with the `|` pipe operator::
#? strip(startswith="<") | stdtmpl #? strip(startswith="<") | stdtmpl
#proc generateXML(name, age: string): string = #proc generateXML(name, age: string): string =
@ -68,10 +70,10 @@ The replace filter replaces substrings in each line.
Parameters and their defaults: Parameters and their defaults:
``sub: string = ""`` `sub: string = ""`
the substring that is searched for the substring that is searched for
``by: string = ""`` `by: string = ""`
the string the substring is replaced with the string the substring is replaced with
@ -83,14 +85,14 @@ each line.
Parameters and their defaults: Parameters and their defaults:
``startswith: string = ""`` `startswith: string = ""`
strip only the lines that start with *startswith* (ignoring leading strip only the lines that start with *startswith* (ignoring leading
whitespace). If empty every line is stripped. whitespace). If empty every line is stripped.
``leading: bool = true`` `leading: bool = true`
strip leading whitespace strip leading whitespace
``trailing: bool = true`` `trailing: bool = true`
strip trailing whitespace strip trailing whitespace
@ -99,25 +101,25 @@ StdTmpl filter
The stdtmpl filter provides a simple templating engine for Nim. The The stdtmpl filter provides a simple templating engine for Nim. The
filter uses a line based parser: Lines prefixed with a *meta character* 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 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: Parameters and their defaults:
``metaChar: char = '#'`` `metaChar: char = '#'`
prefix for a line that contains Nim code prefix for a line that contains Nim code
``subsChar: char = '$'`` `subsChar: char = '$'`
prefix for a Nim expression within a template line prefix for a Nim expression within a template line
``conc: string = " & "`` `conc: string = " & "`
the operation for concatenation the operation for concatenation
``emit: string = "result.add"`` `emit: string = "result.add"`
the operation to emit a string literal the operation to emit a string literal
``toString: string = "$"`` `toString: string = "$"`
the operation that is applied to each expression the operation that is applied to each expression
Example:: Example::
@ -174,18 +176,18 @@ The filter transforms this into:
Each line that does not start with the meta character (ignoring leading 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 The substitution character introduces a Nim expression *e* within the
string literal. *e* is converted to a string with the *toString* operation 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:: empty string. *e* must match this PEG pattern::
e <- [a-zA-Z\128-\255][a-zA-Z0-9\128-\255_.]* / '{' x '}' e <- [a-zA-Z\128-\255][a-zA-Z0-9\128-\255_.]* / '{' x '}'
x <- '{' x+ '}' / [^}]* x <- '{' x+ '}' / [^}]*
To produce a single substitution character it has to be doubled: ``$$`` To produce a single substitution character it has to be doubled: `$$`
produces ``$``. produces `$`.
The template engine is quite flexible. It is easy to produce a procedure that The template engine is quite flexible. It is easy to produce a procedure that
writes the template code directly to a file:: writes the template code directly to a file::

View file

@ -1,3 +1,5 @@
.. default-role:: code
======================= =======================
Nim's Memory Management Nim's Memory Management
======================= =======================
@ -27,37 +29,37 @@ and how the memory management strategies other than garbage collectors work.
Multi-paradigm Memory Management Strategies 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 deferred reference counting based garbage collector
with a simple Mark&Sweep backup GC in order to collect cycles. Heaps are thread-local. 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:markAndSweep`. Simple Mark-And-Sweep based garbage collector. Heaps are thread-local.
- ``--gc:boehm``. Boehm based garbage collector, it offers a shared heap. - `--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:go`. Go's garbage collector, useful for interoperability with Go. Offers a shared heap.
- ``--gc:arc``. Plain reference counting with - `--gc:arc`. Plain reference counting with
`move semantic optimizations <destructors.html#move-semantics>`_, offers a shared heap. `move semantic optimizations <destructors.html#move-semantics>`_, offers a shared heap.
It offers deterministic performance for `hard realtime`:idx: systems. Reference cycles It offers deterministic performance for `hard realtime`:idx: systems. Reference cycles
cause memory leaks, beware. 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 Unfortunately, that makes its performance profile hard to reason about so it is less
useful for hard real-time systems. useful for hard real-time systems.
- ``--gc:none``. No memory management strategy nor a garbage collector. Allocated memory is - `--gc:none`. No memory management strategy nor a garbage collector. Allocated memory is
simply never freed. You should use ``--gc:arc`` instead. simply never freed. You should use `--gc:arc` instead.
================== ======== ================= ============== =================== ================== ======== ================= ============== ===================
Memory Management Heap Reference Cycles Stop-The-World Command line switch Memory Management Heap Reference Cycles Stop-The-World Command line switch
================== ======== ================= ============== =================== ================== ======== ================= ============== ===================
RefC Local Cycle Collector No ``--gc:refc`` RefC Local Cycle Collector No `--gc:refc`
Mark & Sweep Local Cycle Collector No ``--gc:markAndSweep`` Mark & Sweep Local Cycle Collector No `--gc:markAndSweep`
ARC Shared Leak No ``--gc:arc`` ARC Shared Leak No `--gc:arc`
ORC Shared Cycle Collector No ``--gc:orc`` ORC Shared Cycle Collector No `--gc:orc`
Boehm Shared Cycle Collector Yes ``--gc:boehm`` Boehm Shared Cycle Collector Yes `--gc:boehm`
Go Shared Cycle Collector Yes ``--gc:go`` Go Shared Cycle Collector Yes `--gc:go`
None Manual Manual Manual ``--gc:none`` None Manual Manual Manual `--gc:none`
================== ======== ================= ============== =================== ================== ======== ================= ============== ===================
JavaScript's garbage collector is used for the `JavaScript and NodeJS 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 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 Soft real-time support
---------------------- ----------------------
To enable real-time support, the symbol `useRealtimeGC`:idx: needs to be 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). file as well).
With this switch the garbage collector supports the following operations: 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_setMaxPause*(maxPauseInUs: int)
proc GC_step*(us: int, strongAdvice = false, stackSize = -1) 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: These two procs are the two modus operandi of the real-time garbage collector:
(1) GC_SetMaxPause Mode (1) GC_SetMaxPause Mode
You can call ``GC_SetMaxPause`` at program startup and then each triggered 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 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 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. time.
(2) GC_step Mode (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. 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, To bind all garbage collector activity to a `GC_step` call,
deactivate the garbage collector with ``GC_disable`` at program startup. deactivate the garbage collector with `GC_disable` at program startup.
If ``strongAdvice`` is set to ``true``, If `strongAdvice` is set to `true`,
then the garbage collector will be forced to perform the collection cycle. then the garbage collector will be forced to perform the collection cycle.
Otherwise, the garbage collector may decide not to do anything, Otherwise, the garbage collector may decide not to do anything,
if there is not much garbage to collect. 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 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 below a certain point on the stack. Make sure the size you specify is greater
than the potential worst-case size. than the potential worst-case size.
@ -130,16 +132,16 @@ Time measurement with garbage collectors
---------------------------------------- ----------------------------------------
The garbage collectors' way of measuring time uses 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. 1) `QueryPerformanceCounter` and `QueryPerformanceFrequency` on Windows.
2) ``mach_absolute_time`` on Mac OS X. 2) `mach_absolute_time` on Mac OS X.
3) ``gettimeofday`` on Posix systems. 3) `gettimeofday` on Posix systems.
As such it supports a resolution of nanoseconds internally; however, the API As such it supports a resolution of nanoseconds internally; however, the API
uses microseconds for convenience. 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. garbage collector output whenever it missed a deadline.
The reporting will be enhanced and supported by the API in later versions of the collector. 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 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 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. 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 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. being freed by the garbage collector.
Other useful procs from `system <system.html>`_ you can use to keep track of memory are: 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. * `getTotalMem()` Returns the amount of total memory managed by the garbage collector.
* ``getOccupiedMem()`` Bytes reserved by the garbage collector and used by objects. * `getOccupiedMem()` Bytes reserved by the garbage collector and used by objects.
* ``getFreeMem()`` Bytes reserved by the garbage collector and not in use. * `getFreeMem()` Bytes reserved by the garbage collector and not in use.
* ``GC_getStatistics()`` Garbage collector statistics as a human-readable string. * `GC_getStatistics()` Garbage collector statistics as a human-readable string.
These numbers are usually only for the running thread, not for the whole heap, 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 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``. 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 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. 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 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 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 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 the total amount of object instances for this type as well as the total
amount of bytes these instances take up. amount of bytes these instances take up.
The numbers count the number of objects in all garbage collector heaps, they refer to 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 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. change in later versions.

View file

@ -1,3 +1,5 @@
.. default-role:: code
=================================== ===================================
Hot code reloading 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. during development resides.
In this example, we use SDL2 to create a window and we reload the logic 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 ``#***``. code when `F9` is pressed. The important lines are marked with `#***`.
To install SDL2 you can use ``nimble install sdl2``. To install SDL2 you can use `nimble install sdl2`.
.. code-block:: nim .. 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 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. updated version of the program.
@ -133,8 +135,8 @@ updated version of the program.
Reloading API Reloading API
============= =============
One can use the special event handlers ``beforeCodeReload`` and One can use the special event handlers `beforeCodeReload` and
``afterCodeReload`` to reset the state of a particular variable or to force `afterCodeReload` to reset the state of a particular variable or to force
the execution of certain statements: the execution of certain statements:
.. code-block:: Nim .. 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 build-system triggered IPC notification mechanism, but a polling solution is
also possible through the provided `hasAnyModuleChanged()`:idx: API. also possible through the provided `hasAnyModuleChanged()`:idx: API.
In order to access ``beforeCodeReload``, ``afterCodeReload``, ``hasModuleChanged`` In order to access `beforeCodeReload`, `afterCodeReload`, `hasModuleChanged`
or ``hasAnyModuleChanged`` one must import the `hotcodereloading`:idx: module. or `hasAnyModuleChanged` one must import the `hotcodereloading`:idx: module.
Native code targets Native code targets
@ -187,11 +189,11 @@ Native code targets
Native projects using the hot code reloading option will be implicitly Native projects using the hot code reloading option will be implicitly
compiled with the `-d:useNimRtl` option and they will depend on both compiled with the `-d:useNimRtl` option and they will depend on both
the ``nimrtl`` library and the ``nimhcr`` library which implements the the `nimrtl` library and the `nimhcr` library which implements the
hot code reloading run-time. Both libraries can be found in the ``lib`` 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 folder of Nim and can be compiled into dynamic libraries to satisfy
runtime demands of the example code above. An example of compiling 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. with choosenim follows.
:: ::
@ -208,16 +210,16 @@ with choosenim follows.
# source directory (.dll for Windows, .so for Unix, .dylib for MacOS) # source directory (.dll for Windows, .so for Unix, .dylib for MacOS)
All modules of the project will be compiled to separate dynamic link 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 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 only copies of these libraries in order to not interfere with any newly
issued build commands. issued build commands.
The main module of the program is considered non-reloadable. Please note 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 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 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 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 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 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, Nim differs from many other compilers in that it is really fast,
and being so fast makes it suited to provide external queries for and being so fast makes it suited to provide external queries for
text editors about the source code being written. Through the text editors about the source code being written. Through the
``idetools`` command of `the compiler <nimc.html>`_, any IDE `idetools` command of `the compiler <nimc.html>`_, any IDE
can query a ``.nim`` source file and obtain useful information like can query a `.nim` source file and obtain useful information like
definition of symbols or suggestions for completion. definition of symbols or suggestions for completion.
This document will guide you through the available options. If you 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 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:: The general idetools invocations are::
nim idetools --track:FILE,LINE,COL <switches> proj.nim 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 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 This is the main *project* filename. Most of the time you will
pass in the same as **FILE**, but for bigger projects this is 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 the file which is used as main entry point for the program, the
one which users compile to generate a final binary. one which users compile to generate a final binary.
``<switches>`` `<switches>`
This would be any of the other idetools available options, like 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 An integer with the column you are going to query. For the
compiler columns start at zero, so the first column will be compiler columns start at zero, so the first column will be
**0** and the last in an 80 column terminal will be **79**. **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 An integer with the line you are going to query. For the compiler
lines start at **1**. lines start at **1**.
``FILE`` `FILE`
The file you want to perform the query on. Usually you will The file you want to perform the query on. Usually you will
pass in the same value as **proj.nim**. pass in the same value as **proj.nim**.
``DIRTY_FILE`` `DIRTY_FILE`
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 tend to have *unsaved buffers* where the user may still be in
the middle of typing a line. In such situations the IDE can the middle of typing a line. In such situations the IDE can
save the current contents to a temporary file and then use the 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 Dirty files are likely to contain errors and they are usually
compiled partially only to the point needed to service the compiled partially only to the point needed to service the
@ -91,7 +93,7 @@ Or::
Definitions 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 of a specific symbol. If available, idetools will answer with the
type, source file, line/column information and other accessory data type, source file, line/column information and other accessory data
if available like a docstring. With this information an IDE can 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 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 completion symbols at some point in the file. IDEs can easily provide
an autocompletion feature where the IDE scans the current file (and an autocompletion feature where the IDE scans the current file (and
related ones, if it knows about the language being edited and follows 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 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 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 character, this one is meant to be used after the user has typed
an opening brace to start typing parameters. an opening brace to start typing parameters.
@ -143,7 +145,7 @@ an opening brace to start typing parameters.
Symbol usages 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 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 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 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: tab characters (``\t``). The values of each column are:
1. Three characters indicating the type of returned answer (e.g. 1. Three characters indicating the type of returned answer (e.g.
def for definition, ``sug`` for suggestion, etc). def for definition, `sug` for suggestion, etc).
2. Type of the symbol. This can be ``skProc``, ``skLet``, and just 2. Type of the symbol. This can be `skProc`, `skLet`, and just
about any of the enums defined in the module ``compiler/ast.nim``. 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 3. Full qualified path of the symbol. If you are querying a symbol
defined in the ``proj.nim`` file, this would have the form defined in the `proj.nim` file, this would have the form
``proj.symbolName``. `proj.symbolName`.
4. Type/signature. For variables and enums this will contain the 4. Type/signature. For variables and enums this will contain the
type of the symbol, for procs, methods and templates this will 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. 5. Full path to the file containing the symbol.
6. Line where the symbol is located in the file. Lines start to 6. Line where the symbol is located in the file. Lines start to
count at **1**. 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 by the parameters and return value, the signature of the method
returned by idetools returns also the pragmas for the method. returned by idetools returns also the pragmas for the method.
Note that at the moment the word ``proc`` is returned for the Note that at the moment the word `proc` is returned for the
signature of the found method instead of the expected ``method``. signature of the found method instead of the expected `method`.
This may change in the future. This may change in the future.
| **Third column**: module + [n scope nesting] + method name. | **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 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 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 to report it as a bug and add a test to the suite to avoid future
regressions. regressions.
@ -533,27 +535,27 @@ run it manually. First you have to compile the tester::
$ cd my/nim/checkout/tests $ cd my/nim/checkout/tests
$ nim c testament/caasdriver.nim $ 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 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 nothing will be printed and the process will exit with zero. If any
test fails, the specific line of the test preceding the failure test fails, the specific line of the test preceding the failure
and the failure itself will be dumped to stdout, along with a final 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 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 starting a process for each command or query, similar to running
manually the Nim compiler from the commandline. The ``CaasRun`` manually the Nim compiler from the commandline. The `CaasRun`
mode starts a server process to answer all queries. The ``SymbolProcRun`` mode starts a server process to answer all queries. The `SymbolProcRun`
mode is used by compiler developers. This means that running all 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. can be quite time consuming.
If you don't want to run all the test case files you can pass any 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 passed substring will be run. The filtering doesn't use any globbing
metacharacters, it's a plain match. For example, to run only 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 ./caasdriver verbose -compile
@ -561,18 +563,18 @@ metacharacters, it's a plain match. For example, to run only
Test case file format 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. * 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 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. 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 modes, you can prefix a line with the mode and the line will be
processed only in that mode. processed only in that mode.

View file

@ -1,3 +1,5 @@
.. default-role:: code
========================================= =========================================
Internals of the Nim Compiler Internals of the Nim Compiler
========================================= =========================================
@ -19,19 +21,19 @@ The Nim project's directory structure is:
============ =================================================== ============ ===================================================
Path Purpose Path Purpose
============ =================================================== ============ ===================================================
``bin`` generated binary files `bin` generated binary files
``build`` generated C code for the installation `build` generated C code for the installation
``compiler`` the Nim compiler itself; note that this `compiler` the Nim compiler itself; note that this
code has been translated from a bootstrapping code has been translated from a bootstrapping
version written in Pascal, so the code is **not** version written in Pascal, so the code is **not**
a poster child of good Nim code a poster child of good Nim code
``config`` configuration files for Nim `config` configuration files for Nim
``dist`` additional packages for the distribution `dist` additional packages for the distribution
``doc`` the documentation; it is a bunch of `doc` the documentation; it is a bunch of
reStructuredText files reStructuredText files
``lib`` the Nim library `lib` the Nim library
``web`` website of Nim; generated by ``nimweb`` `web` website of Nim; generated by `nimweb`
from the ``*.txt`` and ``*.nimf`` files from the `*.txt` and `*.nimf` files
============ =================================================== ============ ===================================================
@ -53,7 +55,7 @@ And for a debug version compatible with GDB::
nim c koch.nim nim c koch.nim
./koch boot --debuginfo --linedir:on ./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. 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>`_ More information about its options can be found in the `koch <koch.html>`_
documentation. documentation.
@ -67,8 +69,8 @@ Coding Guidelines
* Max line length is 80 characters. * Max line length is 80 characters.
* Provide spaces around binary operators if that enhances readability. * Provide spaces around binary operators if that enhances readability.
* Use a space after a colon, but not before it. * Use a space after a colon, but not before it.
* [deprecated] Start types with a capital ``T``, unless they are * [deprecated] Start types with a capital `T`, unless they are
pointers/references which start with ``P``. pointers/references which start with `P`.
See also the `API naming design <apis.html>`_ document. 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. C code, porting the code generator is not necessary.
POSIX-compliant systems on conventional hardware are usually pretty easy to 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. check that the OS, System modules work and recompile Nim.
The only case where things aren't as easy is when the garbage The only case where things aren't as easy is when the garbage
collector needs some assembler tweaking to work. The standard 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 on the hardware stack. It may be necessary that the new platform needs to
replace this generic code by some assembler code. 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. 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. 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 Rebuilding the compiler
======================== ========================
@ -139,7 +141,7 @@ Debugging the compiler
====================== ======================
You can of course use GDB or Visual Studio to debug the 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: 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 renderer import renderTree
from msgs import `??` 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 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 to create stacktraces for compiler debugging. See also
`Rebuilding the compiler`_ if you need more control. `Rebuilding the compiler`_ if you need more control.
Bisecting for regressions Bisecting for regressions
========================= =========================
``koch temp`` returns 125 as the exit code in case the compiler `koch temp` returns 125 as the exit code in case the compiler
compilation fails. This exit code tells ``git bisect`` to skip the compilation fails. This exit code tells `git bisect` to skip the
current commit.:: current commit.::
git bisect start bad-commit good-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 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 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 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 module. However, calls to some procedures like `addInt` are inserted by
the CCG. Therefore the module ``magicsys`` contains a table (``compilerprocs``) the CCG. Therefore the module `magicsys` contains a table (`compilerprocs`)
with all symbols that are marked as ``compilerproc``. ``compilerprocs`` are with all symbols that are marked as `compilerproc`. `compilerprocs` are
needed by the code generator. A ``magic`` proc is not the same as a 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 `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 semantic checking, a `compilerproc` is a proc that is used by the code
generator. 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. that fills the internal seqs which are affected by the pragmas.
In fact, this describes how the AST should be stored in the database, 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: following contents:
.. code-block:: nim .. code-block:: nim
@ -279,21 +281,21 @@ Conceptually this is the AST we store for the module:
static: static:
echo "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. 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. that dependencies are resolved properly.
Shared global compiletime state 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 invocations across different modules. This feature breaks modularity in a
severe way. Plenty of different solutions have been proposed: 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 similar unordered, only-growable collections so that we can track
the module's write effects to these variables and reapply the changes the module's write effects to these variables and reapply the changes
in a different order. 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 Since we adopt the "replay the top level statements" idea, the natural
solution to this problem is to emit pseudo top level statements that solution to this problem is to emit pseudo top level statements that
reflect the mutations done to the global variable. However, this is 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: snippet:
.. code-block:: nim .. code-block:: nim
@ -314,12 +316,12 @@ snippet:
"\t^self externalCallFailed\C!\C\C") "\t^self externalCallFailed\C!\C\C")
stCode.add(st & "\C\t\"Generated by NimSqueak\"\C\t" & apicall) stCode.add(st & "\C\t\"Generated by NimSqueak\"\C\t" & apicall)
We can "replay" ``stCode.add`` only if the values of ``st`` 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 and `apicall` are known. And even then a hash table's `add` with its
hashing mechanism is too hard to replay. hashing mechanism is too hard to replay.
In practice, things are worse still, consider ``someGlobal[i][j].add arg``. 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 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 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 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 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 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. 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 .. code-block:: nim
@ -350,7 +352,7 @@ Instead the native code would work with an API like ``put``, ``get``:
proc cacheGet*(key: string): NimNode proc cacheGet*(key: string): NimNode
The API should embrace the AST diffing notion: See the 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: if 1:
echo "ugly, but should work" echo "ugly, but should work"
If in the above example module ``B`` is re-compiled, but ``A`` is not then 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 `B` needs to be aware of `toBool` even though `toBool` is not referenced
in ``B`` *explicitly*. in `B` *explicitly*.
Both the multi method and the type converter problems are solved by the Both the multi method and the type converter problems are solved by the
AST replay implementation. AST replay implementation.
@ -395,7 +397,7 @@ Generics
We cache generic instantiations and need to ensure this caching works We cache generic instantiations and need to ensure this caching works
well with the incremental compilation feature. Since the cache is 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. special logic.
@ -405,22 +407,22 @@ Backend issues
- Init procs must not be "forgotten" to be called. - Init procs must not be "forgotten" to be called.
- Files must not be "forgotten" to be linked. - Files must not be "forgotten" to be linked.
- Method dispatchers are global. - Method dispatchers are global.
- DLL loading via ``dlsym`` is global. - DLL loading via `dlsym` is global.
- Emulated thread vars are global. - Emulated thread vars are global.
However the biggest problem is that dead code elimination breaks modularity! 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 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, 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``. `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`` Then module `A` (that depends on `B` and `G`) is compiled and `B`
and ``G`` are left unchanged. ``A`` requires ``G.P2``. and `G` are left unchanged. `A` requires `G.P2`.
So now ``G.c`` MUST contain both ``P1`` and ``P2``, but we haven't even 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 loaded `P1` from the symbol file, nor do we want to because we then quickly
would restore large parts of the whole program. 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 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 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 inserted back into the produced C file. This approach seems to deal with
all the outlined problems above. all the outlined problems above.
@ -444,8 +446,8 @@ in mind:
keeps allocating memory! Thus a stack overflow may happen, hiding the keeps allocating memory! Thus a stack overflow may happen, hiding the
real issue. real issue.
* What seem to be C code generation problems is often a bug resulting from * 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 not producing prototypes, so that some types default to `cint`. Testing
without the ``-w`` option helps! without the `-w` option helps!
The Garbage Collector The Garbage Collector
@ -464,9 +466,9 @@ code generation.
Each cell has a header consisting of a RC and a pointer to its type 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 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 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. 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 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, 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 .. code-block:: Nim
type type
@ -559,11 +561,11 @@ Code generation for closures is implemented by `lambda lifting`:idx:.
Design 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 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. `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 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 interoperability is worth the cost of the `if`. Thunk generation would be
possible too, but it's slightly more effort to implement. possible too, but it's slightly more effort to implement.
Tests with GCC on Amd64 showed that it's really beneficial if the 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 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. 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 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: Example code:
@ -695,15 +697,15 @@ Accumulator
Internals 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, 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 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 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 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 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 backend somehow. We deal with this by modifying `s.ast[paramPos]` to contain
the formal hidden parameter, but not ``s.typ``! the formal hidden parameter, but not `s.typ`!
Integer literals: Integer literals:

View file

@ -1,3 +1,5 @@
.. default-role:: code
=============================== ===============================
Nim maintenance script Nim maintenance script
=============================== ===============================
@ -17,7 +19,7 @@ Introduction
The `koch`:idx: program is Nim's maintenance script. It is a replacement 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. 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 Nim compiler, but it can also be used for other tasks. This document
describes the supported commands and their options. describes the supported commands and their options.
@ -39,8 +41,8 @@ options:
Use the linenoise library for interactive mode (not needed on Windows). Use the linenoise library for interactive mode (not needed on Windows).
After compilation is finished you will hopefully end up with the nim 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 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 your `$PATH` or use the install command to place it where it will be
found. found.
csource command csource command
@ -54,33 +56,33 @@ temp command
------------ ------------
The temp command builds the Nim compiler but with a different final name 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 this command to test different options, the same you would issue for the `boot
command <#commands-boot-command>`_. command <#commands-boot-command>`_.
test command test command
------------ ------------
The `test`:idx: command can also be invoked with the alias ``tests``. This 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 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, 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 they will be forwarded to the tester. See its source code for available
options. options.
web command 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 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. https://nim-lang.org.
By default, the documentation will be built in parallel using the number of 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 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 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 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 pdf command
----------- -----------

View file

@ -1,3 +1,5 @@
.. default-role:: code
==================== ====================
Nim Standard Library Nim Standard Library
==================== ====================
@ -9,7 +11,7 @@ Nim Standard Library
Nim's library is divided into *pure libraries*, *impure libraries*, and *wrappers*. 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 while impure libraries do. A wrapper is an impure library that is a very
low-level interface to a C library. low-level interface to a C library.
@ -37,11 +39,11 @@ Automatic imports
* `threads <threads.html>`_ * `threads <threads.html>`_
Basic Nim thread support. **Note:** This is part of the system module. Do not 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>`_ * `channels <channels_builtin.html>`_
Nim message passing support for threads. **Note:** This is part of the 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 Core
@ -86,14 +88,14 @@ Algorithms
This module implements some common generic algorithms like sort or binary search. This module implements some common generic algorithms like sort or binary search.
* `std/enumutils <enumutils.html>`_ * `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>`_ * `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. which were inspired by functional programming languages.
* `std/setutils <setutils.html>`_ * `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 Collections
@ -105,7 +107,7 @@ Collections
* `deques <deques.html>`_ * `deques <deques.html>`_
Implementation of a double-ended queue. Implementation of a double-ended queue.
The underlying implementation uses a ``seq``. The underlying implementation uses a `seq`.
* `heapqueue <heapqueue.html>`_ * `heapqueue <heapqueue.html>`_
Implementation of a heap data structure that can be used as a priority queue. Implementation of a heap data structure that can be used as a priority queue.
@ -140,7 +142,7 @@ String handling
--------------- ---------------
* `cstrutils <cstrutils.html>`_ * `cstrutils <cstrutils.html>`_
Utilities for ``cstring`` handling. Utilities for `cstring` handling.
* `std/editdistance <editdistance.html>`_ * `std/editdistance <editdistance.html>`_
This module contains an algorithm to compute the edit distance between two This module contains an algorithm to compute the edit distance between two
@ -148,7 +150,7 @@ String handling
* `encodings <encodings.html>`_ * `encodings <encodings.html>`_
Converts between different character encodings. On UNIX, this uses 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>`_ * `parseutils <parseutils.html>`_
This module contains helpers for parsing tokens, numbers, identifiers, etc. This module contains helpers for parsing tokens, numbers, identifiers, etc.
@ -166,17 +168,17 @@ String handling
* `strformat <strformat.html>`_ * `strformat <strformat.html>`_
Macro based standard string interpolation/formatting. Inspired by Macro based standard string interpolation/formatting. Inspired by
Python's ``f``-strings. Python's `f`-strings.
* `strmisc <strmisc.html>`_ * `strmisc <strmisc.html>`_
This module contains uncommon string handling operations that do not This module contains uncommon string handling operations that do not
fit with the commonly used operations in strutils. fit with the commonly used operations in strutils.
* `strscans <strscans.html>`_ * `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>`_ * `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 from strings to strings. Supports a case-sensitive, case-insensitive and
style-insensitive modes. style-insensitive modes.
@ -200,10 +202,10 @@ Time handling
------------- -------------
* `std/monotimes <monotimes.html>`_ * `std/monotimes <monotimes.html>`_
The ``monotimes`` module implements monotonic timestamps. The `monotimes` module implements monotonic timestamps.
* `times <times.html>`_ * `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 Generic Operating System Services
@ -225,7 +227,7 @@ Generic Operating System Services
data structures. data structures.
* `memfiles <memfiles.html>`_ * `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. on the different operating systems.
* `os <os.html>`_ * `os <os.html>`_
@ -234,12 +236,12 @@ Generic Operating System Services
commands, etc. commands, etc.
* `osproc <osproc.html>`_ * `osproc <osproc.html>`_
Module for process communication beyond ``os.execShellCmd``. Module for process communication beyond `os.execShellCmd`.
* `streams <streams.html>`_ * `streams <streams.html>`_
This module provides a stream interface and two implementations thereof: This module provides a stream interface and two implementations thereof:
the ``FileStream`` and the ``StringStream`` which implement the stream the `FileStream` and the `StringStream` which implement the stream
interface for Nim file objects (``File``) and strings. Other modules interface for Nim file objects (`File`) and strings. Other modules
may provide other implementations for this standard stream interface. may provide other implementations for this standard stream interface.
* `terminal <terminal.html>`_ * `terminal <terminal.html>`_
@ -288,22 +290,22 @@ Internet Protocols and Support
* `asyncfile <asyncfile.html>`_ * `asyncfile <asyncfile.html>`_
This module implements asynchronous file reading and writing using This module implements asynchronous file reading and writing using
``asyncdispatch``. `asyncdispatch`.
* `asyncftpclient <asyncftpclient.html>`_ * `asyncftpclient <asyncftpclient.html>`_
This module implements an asynchronous FTP client using the ``asyncnet`` This module implements an asynchronous FTP client using the `asyncnet`
module. module.
* `asynchttpserver <asynchttpserver.html>`_ * `asynchttpserver <asynchttpserver.html>`_
This module implements an asynchronous HTTP server using the ``asyncnet`` This module implements an asynchronous HTTP server using the `asyncnet`
module. module.
* `asyncnet <asyncnet.html>`_ * `asyncnet <asyncnet.html>`_
This module implements asynchronous sockets based on the ``asyncdispatch`` This module implements asynchronous sockets based on the `asyncdispatch`
module. module.
* `asyncstreams <asyncstreams.html>`_ * `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>`_ * `cgi <cgi.html>`_
This module implements helpers for CGI applications. This module implements helpers for CGI applications.
@ -323,7 +325,7 @@ Internet Protocols and Support
* `net <net.html>`_ * `net <net.html>`_
This module implements a high-level sockets API. It replaces the This module implements a high-level sockets API. It replaces the
``sockets`` module. `sockets` module.
* `selectors <selectors.html>`_ * `selectors <selectors.html>`_
This module implements a selector API with backends specific to each OS. 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. scheme for lexers and parsers. This is used by the diverse parsing modules.
* `parsecfg <parsecfg.html>`_ * `parsecfg <parsecfg.html>`_
The ``parsecfg`` module implements a high-performance configuration file The `parsecfg` module implements a high-performance configuration file
parser. The configuration file's syntax is similar to the Windows ``.ini`` 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 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 literals, raw string literals, and triple quote string literals are supported
as in the Nim programming language. as in the Nim programming language.
* `parsecsv <parsecsv.html>`_ * `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>`_ * `parseopt <parseopt.html>`_
The ``parseopt`` module implements a command line option parser. The `parseopt` module implements a command line option parser.
* `parsesql <parsesql.html>`_ * `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>`_ * `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 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 to be somewhat error-correcting, so that even some "wild HTML" found on the
web can be parsed with it. web can be parsed with it.
@ -458,7 +460,7 @@ Miscellaneous
This module implements a simple logger. This module implements a simple logger.
* `segfaults <segfaults.html>`_ * `segfaults <segfaults.html>`_
Turns access violations or segfaults into a ``NilAccessDefect`` exception. Turns access violations or segfaults into a `NilAccessDefect` exception.
* `sugar <sugar.html>`_ * `sugar <sugar.html>`_
This module implements nice syntactic sugar based on Nim's macro system. 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. Declaration of the Document Object Model for the JS backend.
* `jsconsole <jsconsole.html>`_ * `jsconsole <jsconsole.html>`_
Wrapper for the ``console`` object. Wrapper for the `console` object.
* `jscore <jscore.html>`_ * `jscore <jscore.html>`_
The wrapper of core JavaScript functions. For most purposes, you should be using 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>`_ * `jsffi <jsffi.html>`_
Types and macros for easier interaction with JavaScript. 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 .. default-role:: code
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) 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: then it has to be derived from the routine's first parameter:
.. code-block:: nim .. code-block:: nim
@ -11,10 +13,10 @@ then it has to be derived from the routine's first parameter:
var x: int var x: int
# we know 'forward' provides a view into the location derived from # we know 'forward' provides a view into the location derived from
# its first argument 'x'. # 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 # which is not p's first parameter and lives
# on the stack. # 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 lifetime of the first parameter and that is enough knowledge to verify
memory safety at the call site. 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 Strict not nil checking
========================= =========================
@ -14,9 +15,9 @@ or
In the second case it would check builtin and imported modules as well. 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: We check several kinds of types for nilability:
@ -28,14 +29,14 @@ We check several kinds of types for nilability:
nil nil
------- -------
The default kind of nilability types is the nilable kind: they can have the value ``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. If you have a non-nilable type `T`, you can use `T nil` to get a nilable type for it.
not nil 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 .. code-block:: nim
type 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 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`` 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 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. Note: test that/TODO for code/manual.
nilability state 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 `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``. `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. `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 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.
type nilability type nilability
---------------- ----------------
Types are either nilable or non-nilable. 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`` When you pass a param or a default value, we use the type : for nilable types we return `MaybeNil`
and for non-nilable ``Safe``. 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 params rules
------------ ------------
@ -102,9 +103,9 @@ Param's nilability is detected based on type nilability. We use the type of the
assignment rules 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 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 .. code-block:: nim
callByVar(a) callByVar(a)
Here ``callByVar`` can re-assign ``a``, so this might change ``a``'s nilability, so we change it to ``MaybeNil``. 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). This is also a possible aliasing `move out` (moving out of a current alias set).
.. code-block:: nim .. code-block:: nim
call(a) 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 rules
--------------- ---------------
Branches are the reason we do nil checking like this: with flow checking. 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. 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. 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: else:
MaybeNil 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``. `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``. We also reverse the nilability in the opposite branch: e.g. `else`.
compound expressions: field, index expressions compound expressions: field, index expressions
----------------------------------------------- -----------------------------------------------
We want to track also field(dot) and index(bracket) 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), 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``. 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. 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. 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 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 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. 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]``. 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 element tracking
----------------- -----------------
@ -185,8 +186,8 @@ Also related to tracking initialization of expressions/fields.
unstructured control flow rules unstructured control flow rules
------------------------------- -------------------------------
Unstructured control flow keywords as ``return``, ``break``, ``continue``, ``raise`` mean that we jump from a branch out. 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. 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 .. code-block:: nim
for a in c: 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. 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. 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. This means it stops being aliased with its previous aliases.
.. code-block:: nim .. code-block:: nim
var left = b var left = b
left = right # moving left to right 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. 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 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. 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 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 - 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 these are somewhat special words requiring all uppercase. Instead treat them
as what they are: Real words. So it's ``parseUrl`` rather than as what they are: Real words. So it's `parseUrl` rather than
``parseURL``, ``checkHttpHeader`` instead of ``checkHTTPHeader`` etc. `parseURL`, `checkHttpHeader` instead of `checkHTTPHeader` etc.
- Operations like ``mitems`` or ``mpairs`` (or the now deprecated ``mget``) - Operations like `mitems` or `mpairs` (or the now deprecated `mget`)
that allow a *mutating view* into some data structure should start with an ``m``. 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 - When both in-place mutation and 'returns transformed copy' are available the latter
is a past participle of the former: is a past participle of the former:
@ -136,8 +138,8 @@ Naming Conventions
- sort and sorted - sort and sorted
- rotate and rotated - rotate and rotated
- When the 'returns transformed copy' version already exists like ``strutils.replace`` - When the 'returns transformed copy' version already exists like `strutils.replace`
an in-place version should get an ``-In`` suffix (``replaceIn`` for this example). an in-place version should get an `-In` suffix (`replaceIn` for this example).
- Use `subjectVerb`, not `verbSubject`, e.g.: `fileExists`, not `existsFile`. - 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 English word To use Notes
------------------- ------------ -------------------------------------- ------------------- ------------ --------------------------------------
initialize initFoo initializes a value type ``Foo`` initialize initFoo initializes a value type `Foo`
new newFoo initializes a reference type ``Foo`` new newFoo initializes a reference type `Foo`
via ``new`` via `new`
this or self self for method like procs, e.g.: this or self self for method like procs, e.g.:
`proc fun(self: Foo, a: int)` `proc fun(self: Foo, a: int)`
rationale: `self` is more unique in English rationale: `self` is more unique in English
than `this`, and `foo` would not be DRY. than `this`, and `foo` would not be DRY.
find find should return the position where find find should return the position where
something was found; for a bool result something was found; for a bool result
use ``contains`` use `contains`
contains contains often short for ``find() >= 0`` contains contains often short for `find() >= 0`
append add use ``add`` instead of ``append`` append add use `add` instead of `append`
compare cmp should return an int with the compare cmp should return an int with the
``< 0`` ``== 0`` or ``> 0`` semantics; `< 0` `== 0` or `> 0` semantics;
for a bool result use ``sameXYZ`` for a bool result use `sameXYZ`
put put, ``[]=`` consider overloading ``[]=`` for put put put, `[]=` consider overloading `[]=` for put
get get, ``[]`` consider overloading ``[]`` for get; get get, `[]` consider overloading `[]` for get;
consider to not use ``get`` as a consider to not use `get` as a
prefix: ``len`` instead of ``getLen`` prefix: `len` instead of `getLen`
length len also used for *number of elements* length len also used for *number of elements*
size size, len size should refer to a byte size size size, len size should refer to a byte size
capacity cap capacity cap
@ -236,8 +238,8 @@ Coding Conventions
- Use a proc when possible, only using the more powerful facilities of macros, - Use a proc when possible, only using the more powerful facilities of macros,
templates, iterators, and converters when necessary. templates, iterators, and converters when necessary.
- Use the ``let`` statement (not the ``var`` statement) when declaring variables 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 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 variables remain immutable, and gives those who read the code a better idea
of the code's purpose. of the code's purpose.

View file

@ -1,3 +1,5 @@
.. default-role:: code
=================================== ===================================
Nim Compiler User Guide Nim Compiler User Guide
=================================== ===================================
@ -45,8 +47,8 @@ Advanced command-line switches are:
List of warnings List of warnings
---------------- ----------------
Each warning can be activated individually with ``--warning[NAME]:on|off`` or Each warning can be activated individually with `--warning[NAME]:on|off` or
in a ``push`` pragma. in a `push` pragma.
========================== ============================================ ========================== ============================================
Name Description Name Description
@ -60,7 +62,7 @@ ConfigDeprecated The project makes use of a deprecated config
file. file.
SmallLshouldNotBeUsed The letter 'l' should not be used as an SmallLshouldNotBeUsed The letter 'l' should not be used as an
identifier. identifier.
EachIdentIsTuple The code contains a confusing ``var`` EachIdentIsTuple The code contains a confusing `var`
declaration. declaration.
User Some user-defined warning. User Some user-defined warning.
========================== ============================================ ========================== ============================================
@ -69,8 +71,8 @@ User Some user-defined warning.
List of hints List of hints
------------- -------------
Each hint can be activated individually with ``--hint[NAME]:on|off`` or in a Each hint can be activated individually with `--hint[NAME]:on|off` or in a
``push`` pragma. `push` pragma.
========================== ============================================ ========================== ============================================
Name Description Name Description
@ -129,52 +131,52 @@ Level Description
Compile-time symbols 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 symbols for conditional compilation. The defined switches can be checked in
source code with the `when statement source code with the `when statement
<manual.html#statements-and-expressions-when-statement>`_ and <manual.html#statements-and-expressions-when-statement>`_ and
`defined proc <system.html#defined,untyped>`_. The typical use of this switch is `defined proc <system.html#defined,untyped>`_. The typical use of this switch is
to enable builds in release mode (``-d:release``) where optimizations are to enable builds in release mode (`-d:release`) where optimizations are
enabled for better performance. Another common use is the ``-d:ssl`` switch to enabled for better performance. Another common use is the `-d:ssl` switch to
activate SSL sockets. 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 which may be used in conjunction with the `compile-time define
pragmas<manual.html#implementation-specific-pragmas-compileminustime-define-pragmas>`_ pragmas<manual.html#implementation-specific-pragmas-compileminustime-define-pragmas>`_
to override symbols during build time. to override symbols during build time.
Compile-time symbols are completely **case insensitive** and underscores are 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. implementation and should not be used elsewhere.
Configuration files 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. 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): 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. 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. 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. 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. 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. 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. Command-line settings have priority over configuration file settings.
The default build of a project is a `debug build`:idx:. To compile a 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 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 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 determine where to find imported modules or include files. If multiple files are
found an ambiguity error is produced. 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 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:: directory structure looks like this::
$lib/x.nim $lib/x.nim
@ -198,27 +200,27 @@ directory structure looks like this::
foo/main.nim foo/main.nim
other.nim other.nim
And ``main`` imports ``x``, ``foo/x`` is imported. If ``other`` imports ``x`` 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 then both `$lib/x.nim` and `$lib/bar/x.nim` match but `$lib/x.nim` is used
as it is the first match. as it is the first match.
Generated C code directory Generated C code directory
-------------------------- --------------------------
The generated files that Nim produces all go into a subdirectory called 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 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. This makes it easy to delete all generated files.
The ``--nimcache`` The `--nimcache`
`compiler switch <#compiler-usage-commandminusline-switches>`_ can be used to `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 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 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 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, 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``. 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 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 `CXX` environment variable, use `nim cpp --cc:env myfile.nim`. `--cc:env` is available
since Nim version 1.4. 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 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. Linux i386 machine and run the script.
Another way is to make Nim invoke a cross compiler toolchain:: 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 nim c --cpu:arm --os:linux myproject.nim
For cross compilation, the compiler invokes a C compiler named For cross compilation, the compiler invokes a C compiler named
like ``$cpu.$os.$cc`` (for example arm.linux.gcc) and the configuration like `$cpu.$os.$cc` (for example arm.linux.gcc) and the configuration
system is used to provide meaningful defaults. For example for ``ARM`` your system is used to provide meaningful defaults. For example for `ARM` your
configuration file should contain something like:: configuration file should contain something like::
arm.linux.gcc.path = "/usr/bin" 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 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:: 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 directly on android as if it was Linux. These programs are console-only
programs that can't be distributed in the Play Store. 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 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 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>`_ `native-activity <https://developer.android.com/ndk/samples/sample_na>`_
to have the Java stub be auto-generated for you. 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 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. Add the generated C files to CMake build script in your Android
project. Then do the final compile with Android Studio which uses Gradle project. Then do the final compile with Android Studio which uses Gradle
to call CMake to compile the project. to call CMake to compile the project.
Because Nim is part of a library it can't have its own c style ``main()`` 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 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 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 initialize Nim's garbage collector and to run the top level statements
of your program. 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++ use LLVM and can be compiled into object files linked together with C, C++
or Objective C code produced by Nim. 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 your XCode project. Then you can use XCode to compile, link, package and
sign everything. sign everything.
Because Nim is part of a library it can't have its own c style ``main()`` so you 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 would need to define `main` that calls `autoreleasepool` and
``UIApplicationMain`` to do it, or use a library like SDL2 or GLFM. After `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 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 initialize Nim's garbage collector and to run the top-level statements
of your program. of your program.
@ -356,8 +358,8 @@ Cross-compilation for Nintendo Switch
===================================== =====================================
Simply add --os:nintendoswitch Simply add --os:nintendoswitch
to your usual ``nim c`` or ``nim cpp`` command and set the ``passC`` to your usual `nim c` or `nim cpp` command and set the `passC`
and ``passL`` command line switches to something like: and `passL` command line switches to something like:
.. code-block:: console .. code-block:: console
nim c ... --passC="-I$DEVKITPRO/libnx/include" ... nim c ... --passC="-I$DEVKITPRO/libnx/include" ...
@ -378,8 +380,8 @@ For example, with the above-mentioned config::
nim c --os:nintendoswitch switchhomebrew.nim nim c --os:nintendoswitch switchhomebrew.nim
This will generate a file called ``switchhomebrew.elf`` which can then be turned into 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 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>`_. `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. 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 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 instance of the GC per process/address space. This instance is contained in
``nimrtl.dll``. This means that every generated Nim DLL depends `nimrtl.dll`. This means that every generated Nim DLL depends
on ``nimrtl.dll``. To generate the "nimrtl.dll" file, use the command:: on `nimrtl.dll`. To generate the "nimrtl.dll" file, use the command::
nim c -d:release lib/nimrtl.nim 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 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! never been tested and is unlikely to work!
Additional compilation switches 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 affecting how some features are implemented. This section tries to give a
complete list. complete list.
====================== ========================================================= ====================== =========================================================
Define Effect Define Effect
====================== ========================================================= ====================== =========================================================
``release`` Turns on the optimizer. `release` Turns on the optimizer.
More aggressive optimizations are possible, e.g.: More aggressive optimizations are possible, e.g.:
``--passC:-ffast-math`` (but see issue #10305) `--passC:-ffast-math` (but see issue #10305)
``danger`` Turns off all runtime checks and turns on the optimizer. `danger` Turns off all runtime checks and turns on the optimizer.
``useFork`` Makes ``osproc`` use ``fork`` instead of ``posix_spawn``. `useFork` Makes `osproc` use `fork` instead of `posix_spawn`.
``useNimRtl`` Compile and link against ``nimrtl.dll``. `useNimRtl` Compile and link against `nimrtl.dll`.
``useMalloc`` Makes Nim use C's `malloc`:idx: instead of Nim's `useMalloc` Makes Nim use C's `malloc`:idx: instead of Nim's
own memory manager, albeit prefixing each allocation with own memory manager, albeit prefixing each allocation with
its size to support clearing memory on reallocation. its size to support clearing memory on reallocation.
This only works with ``gc:none``, ``gc:arc`` and This only works with `gc:none`, `gc:arc` and
``--gc:orc``. `--gc:orc`.
``useRealtimeGC`` Enables support of Nim's GC for *soft* realtime `useRealtimeGC` Enables support of Nim's GC for *soft* realtime
systems. See the documentation of the `gc <gc.html>`_ systems. See the documentation of the `gc <gc.html>`_
for further information. for further information.
``logGC`` Enable GC logging to stdout. `logGC` Enable GC logging to stdout.
``nodejs`` The JS target is actually ``node.js``. `nodejs` The JS target is actually `node.js`.
``ssl`` Enables OpenSSL support for the sockets module. `ssl` Enables OpenSSL support for the sockets module.
``memProfiler`` Enables memory profiling for the native GC. `memProfiler` Enables memory profiling for the native GC.
``uClibc`` Use uClibc instead of libc. (Relevant for Unix-like OSes) `uClibc` Use uClibc instead of libc. (Relevant for Unix-like OSes)
``checkAbi`` When using types from C headers, add checks that compare `checkAbi` When using types from C headers, add checks that compare
what's in the Nim file with what's in the C header. what's in the Nim file with what's in the C header.
This may become enabled by default in the future. This may become enabled by default in the future.
``tempDir`` This symbol takes a string as its value, like `tempDir` This symbol takes a string as its value, like
``--define:tempDir:/some/temp/path`` to override the `--define:tempDir:/some/temp/path` to override the
temporary directory returned by ``os.getTempDir()``. temporary directory returned by `os.getTempDir()`.
The value **should** end with a directory separator The value **should** end with a directory separator
character. (Relevant for the Android platform) character. (Relevant for the Android platform)
``useShPath`` This symbol takes a string as its value, like `useShPath` This symbol takes a string as its value, like
``--define:useShPath:/opt/sh/bin/sh`` to override the `--define:useShPath:/opt/sh/bin/sh` to override the
path for the ``sh`` binary, in cases where it is not path for the `sh` binary, in cases where it is not
located in the default location ``/bin/sh``. located in the default location `/bin/sh`.
``noSignalHandler`` Disable the crash handler from ``system.nim``. `noSignalHandler` Disable the crash handler from `system.nim`.
``globalSymbols`` Load all ``{.dynlib.}`` libraries with the ``RTLD_GLOBAL`` `globalSymbols` Load all `{.dynlib.}` libraries with the `RTLD_GLOBAL`
flag on Posix systems to resolve symbols in subsequently flag on Posix systems to resolve symbols in subsequently
loaded libraries. loaded libraries.
====================== ========================================================= ====================== =========================================================
@ -471,20 +473,20 @@ generator and are subject to change.
LineDir option LineDir option
-------------- --------------
The ``lineDir`` option can be turned on or off. If turned on the The `lineDir` option can be turned on or off. If turned on the
generated C code contains ``#line`` directives. This may be helpful for generated C code contains `#line` directives. This may be helpful for
debugging with GDB. debugging with GDB.
StackTrace option 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. ensure that proper stack traces are given if the program crashes or some uncaught exception is raised.
LineTrace option 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 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 number information are given if the program crashes or an uncaught exception
is raised. is raised.
@ -493,10 +495,10 @@ is raised.
DynlibOverride DynlibOverride
============== ==============
By default Nim's ``dynlib`` pragma causes the compiler to generate By default Nim's `dynlib` pragma causes the compiler to generate
``GetProcAddress`` (or their Unix counterparts) `GetProcAddress` (or their Unix counterparts)
calls to bind to a DLL. With the ``dynlibOverride`` command line switch this 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 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 against. For instance, to link statically against Lua this command might work
on Linux:: on Linux::
@ -506,8 +508,8 @@ on Linux::
Backend language options Backend language options
======================== ========================
The typical compiler usage involves using the ``compile`` or ``c`` command to 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 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 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 are other commands to compile to C++, Objective-C, or JavaScript. More details
can be read in the `Nim Backend Integration document <backends.html>`_. 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 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>`_. the output. For more details `see the docgen documentation <docgen.html>`_.
Nim idetools integration Nim idetools integration
@ -533,15 +535,15 @@ for further information.
The Nim compiler supports an interactive mode. This is also known as 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 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 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: line is an incomplete statement to be continued these rules are used:
1. The line ends with ``[-+*/\\<>!\?\|%&$@~,;:=#^]\s*$`` (operator symbol followed by optional whitespace). 1. The line ends with ``[-+*/\\<>!\?\|%&$@~,;:=#^]\s*$`` (operator symbol followed by optional whitespace).
2. The line starts with a space (indentation). 2. The line starts with a space (indentation).
3. The line is within a triple quoted string literal. However, the detection 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 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 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. embedded microprocessors with only a few kilobytes of memory.
A good start is to use the ``any`` operating target together with the A good start is to use the `any` operating target together with the
``malloc`` memory allocator and the ``arc`` garbage collector. For example: `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 of the default garbage collector. This enables Nim to use heap memory which
is required for strings and seqs, for example. 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 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. on almost any platform.
- The ``-d:useMalloc`` option configures Nim to use only the standard C memory - The `-d:useMalloc` option configures Nim to use only the standard C memory
manage primitives ``malloc()``, ``free()``, ``realloc()``. manage primitives `malloc()`, `free()`, `realloc()`.
If your platform does not provide these functions it should be trivial to If your platform does not provide these functions it should be trivial to
provide an implementation for them and link these to your program. 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 to optimize the build for size. For example, the following flags can be used
when targeting a gcc compiler: 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 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 size (with the help of the C compiler), the `flto` flags enable link-time
optimization in the compiler and linker. optimization in the compiler and linker.
Check the `Cross-compilation` section for instructions on how to compile the 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 mechanisms. However, the standard library offers some rudimentary support
for signal handling, in particular, segmentation faults are turned into for signal handling, in particular, segmentation faults are turned into
fatal errors that produce a stack trace. This can be disabled with the fatal errors that produce a stack trace. This can be disabled with the
``-d:noSignalHandler`` switch. `-d:noSignalHandler` switch.
Optimizing for Nim Optimizing for Nim
@ -642,7 +644,7 @@ However, it is not efficient to do:
.. code-block:: Nim .. code-block:: Nim
var s = varA # assignment has to copy the whole string into a new buffer! 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 .. code-block:: Nim
let s = varA # may only copy a pointer if it safe to do so 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 shallow(s) # mark 's' as a shallow string
var x = s # now might not copy the 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:. anymore, similar to Ruby's `freeze`:idx:.

View file

@ -1,3 +1,5 @@
.. default-role:: code
===================== =====================
Nimfix User Guide Nimfix User Guide
===================== =====================
@ -14,12 +16,12 @@ It performs 3 different actions:
1. It makes your code case consistent. 1. It makes your code case consistent.
2. It renames every symbol that has a deprecation rule. So if a module has a 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 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 Note that `nimfix` defaults to **overwrite** your code unless you
use ``--overwriteFiles:off``! But hey, if you do not use a version control 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. 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 nimgrep User's manual
========================= =========================
@ -22,7 +24,7 @@ Compile nimgrep with the command::
nim c -d:release tools/nimgrep.nim 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 Command line switches

View file

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

View file

@ -1,30 +1,32 @@
.. default-role:: code
================================ ================================
NimScript 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 by Nim's builtin virtual machine (VM). This VM is used for Nim's compiletime
function evaluation features. 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 the following directories (in this order; later files overwrite
previous settings): previous settings):
1) If environment variable ``XDG_CONFIG_HOME`` is defined, 1) If environment variable `XDG_CONFIG_HOME` is defined,
``$XDG_CONFIG_HOME/nim/config.nims`` or `$XDG_CONFIG_HOME/nim/config.nims` or
``~/.config/nim/config.nims`` (POSIX) or `~/.config/nim/config.nims` (POSIX) or
``%APPDATA%/nim/config.nims`` (Windows). This file can be skipped `%APPDATA%/nim/config.nims` (Windows). This file can be skipped
with the ``--skipUserCfg`` command line option. with the `--skipUserCfg` command line option.
2) ``$parentDir/config.nims`` where ``$parentDir`` stands for any 2) `$parentDir/config.nims` where `$parentDir` stands for any
parent directory of the project file's path. These files can be parent directory of the project file's path. These files can be
skipped with the ``--skipParentCfg`` command line option. skipped with the `--skipParentCfg` command line option.
3) ``$projectDir/config.nims`` where ``$projectDir`` stands for the 3) `$projectDir/config.nims` where `$projectDir` stands for the
project's path. This file can be skipped with the ``--skipProjCfg`` project's path. This file can be skipped with the `--skipProjCfg`
command line option. command line option.
4) A project can also have a project specific configuration file named 4) A project can also have a project specific configuration file named
``$project.nims`` that resides in the same directory as `$project.nims` that resides in the same directory as
``$project.nim``. This file can be skipped with the same `$project.nim`. This file can be skipped with the same
``--skipProjCfg`` command line option. `--skipProjCfg` command line option.
For available procs and implementation details see `nimscript <nimscript.html>`_. 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): (virtual machine):
* Nim's FFI (foreign function interface) is not available in NimScript. This * 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. 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. 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. also be problematic in some cases.
* More than one level of `ref` is generally not supported (for example, the type * 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. * 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 Standard library modules
@ -109,11 +111,11 @@ See also:
NimScript as a configuration file NimScript as a configuration file
================================= =================================
A command-line switch ``--FOO`` is written as ``switch("FOO")`` in A command-line switch `--FOO` is written as `switch("FOO")` in
NimScript. Similarly, command-line ``--FOO:VAL`` translates to NimScript. Similarly, command-line `--FOO:VAL` translates to
``switch("FOO", "VAL")``. `switch("FOO", "VAL")`.
Here are few examples of using the ``switch`` proc: Here are few examples of using the `switch` proc:
.. code-block:: nim .. code-block:: nim
# command-line: --opt:size # command-line: --opt:size
@ -123,7 +125,7 @@ Here are few examples of using the ``switch`` proc:
# command-line: --forceBuild # command-line: --forceBuild
switch("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 like command-line switches written as-is in the NimScript file. So the
above example can be rewritten as: above example can be rewritten as:
@ -133,17 +135,17 @@ above example can be rewritten as:
--forceBuild --forceBuild
**Note**: In general, the *define* switches can also be set in **Note**: In general, the *define* switches can also be set in
NimScripts using ``switch`` or ``--``, as shown in above NimScripts using `switch` or `--`, as shown in above
examples. Only the ``release`` define (``-d:release``) cannot be set examples. Only the `release` define (`-d:release`) cannot be set
in NimScripts. in NimScripts.
NimScript as a build tool 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 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 .. code-block:: nim
task build, "builds an example": task build, "builds an example":
@ -155,11 +157,11 @@ In fact, as a convention the following tasks should be available:
========= =================================================== ========= ===================================================
Task Description Task Description
========= =================================================== ========= ===================================================
``help`` List all the available NimScript tasks along with their docstrings. `help` List all the available NimScript tasks along with their docstrings.
``build`` Build the project with the required `build` Build the project with the required
backend (``c``, ``cpp`` or ``js``). backend (`c`, `cpp` or `js`).
``tests`` Runs the tests belonging to the project. `tests` Runs the tests belonging to the project.
``bench`` Runs benchmarks 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 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: installation of Nimble could be accomplished with this simple script:
.. code-block:: nim .. 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 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 On Unix, you can also use the shebang `#!/usr/bin/env nim`, as long as your filename
ends with ``.nims``: ends with `.nims`:
.. code-block:: nim .. code-block:: nim
@ -206,7 +208,7 @@ ends with ``.nims``:
echo "hello world" 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 Benefits
@ -268,7 +270,7 @@ Powerful Metaprogramming
NimScript can use Nim's templates, macros, types, concepts, effect tracking system, and more, 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. 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. making it ideal for functional scripting metaprogramming.
This is an example of a third party module that uses macros and templates to 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 echo CompileDate
``likely()``, ``unlikely()``, ``static:`` and ``{.compiletime.}`` `likely()`, `unlikely()`, `static:` and `{.compiletime.}`
will produce no code at all when run on NimScript, will produce no code at all when run on NimScript,
but still no error nor warning is produced and the code just works. 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 Nim IDE Integration Guide
================================ ================================
@ -11,8 +13,8 @@
Nim differs from many other compilers in that it is really fast, Nim differs from many other compilers in that it is really fast,
and being so fast makes it suited to provide external queries for and being so fast makes it suited to provide external queries for
text editors about the source code being written. Through the text editors about the source code being written. Through the
``nimsuggest`` tool, any IDE `nimsuggest` tool, any IDE
can query a ``.nim`` source file and obtain useful information like can query a `.nim` source file and obtain useful information like
definition of symbols or suggestions for completion. definition of symbols or suggestions for completion.
This document will guide you through the available options. If you 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 Nimsuggest invocation
===================== =====================
Run it via ``nimsuggest --stdin --debug myproject.nim``. Nimsuggest is a Run it via `nimsuggest --stdin --debug myproject.nim`. Nimsuggest is a
server that takes queries that are related to ``myproject``. There is some 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 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 of `myproject` at Nimsuggest too, but usually the query refer to modules/files
that are part of ``myproject``. 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 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 via sockets is more reasonable so that is the default. It listens to port 6000
by default. 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>`_ `config files <https://nim-lang.org/docs/nimc.html#compiler-usage-configuration-files>`_
can be used to specify additional dependencies like 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 Specifying the location of the query
------------------------------------ ------------------------------------
Nimsuggest then waits for queries to process. A query consists of a 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: 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. This is the name of the module or include file the query refers to.
``dirtyfile.nim`` `dirtyfile.nim`
This is optional. 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 tend to have *unsaved buffers* where the user may still be in
the middle of typing a line. In such situations the IDE can the middle of typing a line. In such situations the IDE can
save the current contents to a temporary file and then use the save the current contents to a temporary file and then use the
``dirtyfile.nim`` option to tell Nimsuggest that ``foobar.nim`` should `dirtyfile.nim` option to tell Nimsuggest that `foobar.nim` should
be taken from ``temporary/foobar.nim``. be taken from `temporary/foobar.nim`.
``line`` `line`
An integer with the line you are going to query. For the compiler An integer with the line you are going to query. For the compiler
lines start at **1**. lines start at **1**.
``col`` `col`
An integer with the column you are going to query. For the An integer with the column you are going to query. For the
compiler columns start at **0**. compiler columns start at **0**.
@ -84,7 +86,7 @@ a location. A query location consists of:
Definitions 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 of a specific symbol. If available, Nimsuggest will answer with the
type, source file, line/column information and other accessory data type, source file, line/column information and other accessory data
if available like a docstring. With this information an IDE can 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 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. completion symbols at some point in the file.
The typical usage scenario for this option is to call it after the 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 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 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 character, this one is meant to be used after the user has typed
an opening brace to start typing parameters. an opening brace to start typing parameters.
@ -127,7 +129,7 @@ an opening brace to start typing parameters.
Symbol usages 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 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 where the symbol is used and offer the user to rename it in all
places at the same time. 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: tab characters (``\t``). The values of each column are:
1. Three characters indicating the type of returned answer (e.g. 1. Three characters indicating the type of returned answer (e.g.
``def`` for definition, ``sug`` for suggestion, etc). `def` for definition, `sug` for suggestion, etc).
2. Type of the symbol. This can be ``skProc``, ``skLet``, and just 2. Type of the symbol. This can be `skProc`, `skLet`, and just
about any of the enums defined in the module ``compiler/ast.nim``. 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 3. Fully qualified path of the symbol. If you are querying a symbol
defined in the ``proj.nim`` file, this would have the form defined in the `proj.nim` file, this would have the form
``proj.symbolName``. `proj.symbolName`.
4. Type/signature. For variables and enums this will contain the 4. Type/signature. For variables and enums this will contain the
type of the symbol, for procs, methods and templates this will 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. 5. Full path to the file containing the symbol.
6. Line where the symbol is located in the file. Lines start to 6. Line where the symbol is located in the file. Lines start to
count at **1**. 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, 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, offers process isolation for your tests, it can generate statistics about test cases,
supports multiple targets (C, C++, ObjectiveC, JavaScript, etc), 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 Test files location
=================== ===================
By default Testament looks for test files on ``"./tests/*.nim"``. By default Testament looks for test files on `"./tests/*.nim"`.
You can overwrite this pattern glob using ``pattern <glob>``. You can overwrite this pattern glob using `pattern <glob>`.
The default working directory path can be changed using The default working directory path can be changed using
``--directory:"folder/subfolder/"``. `--directory:"folder/subfolder/"`.
Testament uses the ``nim`` compiler on ``PATH``. Testament uses the `nim` compiler on `PATH`.
You can change that using ``--nim:"folder/subfolder/nim"``. You can change that using `--nim:"folder/subfolder/nim"`.
Running JavaScript tests with ``--targets:"js"`` requires a working NodeJS on Running JavaScript tests with `--targets:"js"` requires a working NodeJS on
``PATH``. `PATH`.
Options Options
======= =======
* ``--print`` Also print results to the console * `--print` Also print results to the console
* ``--simulate`` See what tests would be run but don't run them (for debugging) * `--simulate` See what tests would be run but don't run them (for debugging)
* ``--failing`` Only show failing/ignored tests * `--failing` Only show failing/ignored tests
* ``--targets:"c cpp js objc"`` Run tests for specified targets (default: all) * `--targets:"c cpp js objc"` Run tests for specified targets (default: all)
* ``--nim:path`` Use a particular nim executable (default: ``$PATH/nim``) * `--nim:path` Use a particular nim executable (default: `$PATH/nim`)
* ``--directory:dir`` Change to directory dir before reading the tests or doing anything else. * `--directory:dir` Change to directory dir before reading the tests or doing anything else.
* ``--colors:on|off`` Turn messages coloring on|off. * `--colors:on|off` Turn messages coloring on|off.
* ``--backendLogging:on|off`` Disable or enable backend logging. By default turned on. * `--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 * `--skipFrom:file` Read tests to skip from `file` - one test per line, # comments ignored
Running a single test Running a single test
@ -68,7 +70,7 @@ To search for tests deeper in a directory, use
HTML Reports 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: you have to run at least 1 test *before* generating a report:
.. code:: .. code::
@ -172,7 +174,7 @@ Example "template" **to edit** and write a Testament unittest:
assert 42 == 42, "Assert error message" 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. * 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>`_ * `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>`_ * `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 Tools available with Nim
======================== ========================
@ -9,11 +11,11 @@ The standard distribution ships with the following tools:
document explaining how it works. document explaining how it works.
- | `Documentation generator <docgen.html>`_ - | `Documentation generator <docgen.html>`_
| The builtin document generator ``nim doc`` generates HTML documentation | The builtin document generator `nim doc` generates HTML documentation
from ``.nim`` source files. from `.nim` source files.
- | `Nimsuggest for IDE support <nimsuggest.html>`_ - | `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 and obtain useful information like the definition of symbols or suggestions for
completion. completion.
@ -27,11 +29,11 @@ The standard distribution ships with the following tools:
| Nim search and replace utility. | Nim search and replace utility.
- | nimpretty - | nimpretty
| ``nimpretty`` is a Nim source code beautifier, | `nimpretty` is a Nim source code beautifier,
to format code according to the official style guide. to format code according to the official style guide.
- | `testament <https://nim-lang.github.io/Nim/testament.html>`_ - | `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, 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), it can generate statistics about test cases, supports multiple targets (C, JS, etc),
`simulated Dry-Runs <https://en.wikipedia.org/wiki/Dry_run_(testing)>`_, `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) Nim Tutorial (Part II)
====================== ======================
@ -24,7 +26,7 @@ Pragmas
Pragmas are Nim's method to give the compiler additional information/ Pragmas are Nim's method to give the compiler additional information/
commands without introducing a massive number of new keywords. Pragmas are 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 does not cover pragmas. See the `manual <manual.html#pragmas>`_ or `user guide
<nimc.html#additional-features>`_ for a description of the available <nimc.html#additional-features>`_ for a description of the available
pragmas. pragmas.
@ -45,11 +47,11 @@ Inheritance
Inheritance in Nim is entirely optional. To enable inheritance with Inheritance in Nim is entirely optional. To enable inheritance with
runtime type information the object needs to inherit from runtime type information the object needs to inherit from
``RootObj``. This can be done directly, or indirectly by `RootObj`. This can be done directly, or indirectly by
inheriting from an object that inherits from ``RootObj``. Usually inheriting from an object that inherits from `RootObj`. Usually
types with inheritance are also marked as ``ref`` types even though 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 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 .. code-block:: nim
:test: "nim c $1" :test: "nim c $1"
@ -69,16 +71,16 @@ type, the ``of`` operator can be used.
student = Student(name: "Anton", age: 5, id: 2) student = Student(name: "Anton", age: 5, id: 2)
echo student[] echo student[]
Inheritance is done with the ``object of`` syntax. Multiple inheritance is Inheritance is done with the `object of` syntax. Multiple inheritance is
currently not supported. If an object type has no suitable ancestor, ``RootObj`` 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 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 no ancestor are implicitly `final`. You can use the `inheritable` pragma
to introduce new object roots apart from ``system.RootObj``. (This is used to introduce new object roots apart from `system.RootObj`. (This is used
in the GTK wrapper for instance.) in the GTK wrapper for instance.)
Ref objects should be used whenever inheritance is used. It isn't strictly 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 = necessary, but with non-ref objects assignments such as `let person: Person =
Student(id: 123)`` will truncate subclass fields. Student(id: 123)` will truncate subclass fields.
**Note**: Composition (*has-a* relation) is often preferable to inheritance **Note**: Composition (*has-a* relation) is often preferable to inheritance
(*is-a* relation) for simple code reuse. Since objects are value types in (*is-a* relation) for simple code reuse. Since objects are value types in
@ -111,7 +113,7 @@ Example:
Type conversions Type conversions
---------------- ----------------
Nim distinguishes between `type casts`:idx: and `type conversions`:idx:. 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. interpret a bit pattern to be of another type.
Type conversions are a much more polite way to convert a type into another: 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 type conversion is not possible, the compiler complains or an exception is
raised. 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): (like an ordinary call):
.. code-block:: nim .. code-block:: nim
proc getID(x: Person): int = proc getID(x: Person): int =
Student(x).id Student(x).id
The ``InvalidObjectConversionDefect`` exception is raised if ``x`` is not a The `InvalidObjectConversionDefect` exception is raised if `x` is not a
``Student``. `Student`.
Object variants Object variants
@ -150,7 +152,7 @@ An example:
nkSub, # a subtraction nkSub, # a subtraction
nkIf # an if statement nkIf # an if statement
Node = ref object 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 nkInt: intVal: int
of nkFloat: floatVal: float of nkFloat: floatVal: float
of nkString: strVal: string of nkString: strVal: string
@ -173,9 +175,9 @@ Method call syntax
------------------ ------------------
There is a syntactic sugar for calling routines: 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: 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 This method call syntax is not restricted to objects, it can be used
for any type: for any type:
@ -229,10 +231,10 @@ is needed:
new s new s
s.host = 34 # same as `host=`(s, 34) 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:\ : `array properties`:idx:\ :
.. code-block:: nim .. code-block:: nim
@ -258,14 +260,14 @@ The ``[]`` array access operator can be overloaded to provide
else: assert(false) else: assert(false)
The example is silly, since a vector is better modelled by a tuple which The example is silly, since a vector is better modelled by a tuple which
already provides ``v[]`` access. already provides `v[]` access.
Dynamic dispatch Dynamic dispatch
---------------- ----------------
Procedures always use static dispatch. For dynamic dispatch replace the Procedures always use static dispatch. For dynamic dispatch replace the
``proc`` keyword by ``method``: `proc` keyword by `method`:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1" :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))) echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4)))
Note that in the example the constructors ``newLit`` and ``newPlus`` are procs 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 because it makes more sense for them to use static binding, but `eval` is a
method because it requires dynamic binding. method because it requires dynamic binding.
**Note:** Starting from Nim 0.20, to use multi-methods one must explicitly pass **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 In a multi-method all parameters that have an object type are used for the
dispatching: dispatching:
@ -324,7 +326,7 @@ dispatching:
As the example demonstrates, invocation of a multi-method cannot be ambiguous: 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 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 **Performance note**: Nim does not produce a virtual method table, but
generates dispatch trees. This avoids the expensive indirect branch for method 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 In Nim exceptions are objects. By convention, exception types are
suffixed with 'Error'. The `system <system.html>`_ module defines an suffixed with 'Error'. The `system <system.html>`_ module defines an
exception hierarchy that you might want to stick to. Exceptions derive from 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. 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. 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 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, A convention is that exceptions should be raised in *exceptional* cases,
they should not be used as an alternative method of control flow. they should not be used as an alternative method of control flow.
Raise statement Raise statement
--------------- ---------------
Raising an exception is done with the ``raise`` statement: Raising an exception is done with the `raise` statement:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1" :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" e.msg = "the request to the OS failed"
raise e 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, 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 .. code-block:: nim
raise newException(OSError, "the request to the OS failed") 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 Try statement
------------- -------------
The ``try`` statement handles exceptions: The `try` statement handles exceptions:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1" :test: "nim c $1"
@ -399,23 +401,23 @@ The ``try`` statement handles exceptions:
finally: finally:
close(f) close(f)
The statements after the ``try`` are executed unless an exception is The statements after the `try` are executed unless an exception is
raised. Then the appropriate ``except`` part is executed. raised. Then the appropriate `except` part is executed.
The empty ``except`` part is executed if there is an exception that is 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`` not explicitly listed. It is similar to an `else` part in `if`
statements. 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. 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 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). is not executed (if an exception occurs).
If you need to *access* the actual exception object or message inside an 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#getCurrentException>`_ and `getCurrentExceptionMsg()
<system.html#getCurrentExceptionMsg>`_ procs from the `system <system.html>`_ <system.html#getCurrentExceptionMsg>`_ procs from the `system <system.html>`_
module. Example: module. Example:
@ -433,10 +435,10 @@ module. Example:
Annotating procs with raised exceptions 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 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 `{.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 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 (or one of the procs it calls) starts raising a new exception the compiler will
prevent that proc from compiling. Usage example: 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 with the file and line where the uncaught exception is being raised, which may
help you locate the offending code which has changed. help you locate the offending code which has changed.
If you want to add the ``{.raises.}`` pragma to existing code, the compiler can 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 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 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 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 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 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>`_. `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 Generics are Nim's means to parametrize procs, iterators or types
with `type parameters`:idx:. Generic parameters are written within square 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: containers:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1" :test: "nim c $1"
type type
BinaryTree*[T] = ref object # BinaryTree is a generic type with 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 le, ri: BinaryTree[T] # left and right subtrees; may be nil
data: T # the data stored in a node data: T # the data stored in a node
@ -491,8 +493,8 @@ containers:
else: else:
var it = root var it = root
while it != nil: while it != nil:
# compare the data items; uses the generic ``cmp`` proc # compare the data items; uses the generic `cmp` proc
# that works for any type that has a ``==`` and ``<`` operator # that works for any type that has a `==` and `<` operator
var c = cmp(it.data, n.data) var c = cmp(it.data, n.data)
if c < 0: if c < 0:
if it.le == nil: if it.le == nil:
@ -522,19 +524,19 @@ containers:
n = n.le # and follow the left pointer n = n.le # and follow the left pointer
var var
root: BinaryTree[string] # instantiate a BinaryTree with ``string`` root: BinaryTree[string] # instantiate a BinaryTree with `string`
add(root, newNode("hello")) # instantiates ``newNode`` and ``add`` add(root, newNode("hello")) # instantiates `newNode` and `add`
add(root, "world") # instantiates the second ``add`` proc add(root, "world") # instantiates the second `add` proc
for str in preorder(root): for str in preorder(root):
stdout.writeLine(str) stdout.writeLine(str)
The example shows a generic binary tree. Depending on context, the brackets are 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, used either to introduce type parameters or to instantiate a generic proc,
iterator or type. As the example shows, generics work with overloading: the 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 best match of `add` is used. The built-in `add` procedure for sequences
is not hidden and is used in the ``preorder`` iterator. 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 .. code-block:: nim
:test: "nim c $1" :test: "nim c $1"
@ -567,14 +569,14 @@ Example:
assert(5 != 6) # the compiler rewrites that to: assert(not (5 == 6)) assert(5 != 6) # the compiler rewrites that to: assert(not (5 == 6))
The ``!=``, ``>``, ``>=``, ``in``, ``notin``, ``isnot`` operators are in fact The `!=`, `>`, `>=`, `in`, `notin`, `isnot` operators are in fact
templates: this has the benefit that if you overload the ``==`` operator, templates: this has the benefit that if you overload the `==` operator,
the ``!=`` operator is available automatically and does the right thing. (Except the `!=` operator is available automatically and does the right thing. (Except
for IEEE floating point numbers - NaN breaks basic boolean logic.) for IEEE floating point numbers - NaN breaks basic boolean logic.)
``a > b`` is transformed into ``b < a``. `a > b` is transformed into `b < a`.
``a in b`` is transformed into ``contains(b, a)``. `a in b` is transformed into `contains(b, a)`.
``notin`` and ``isnot`` have the obvious meanings. `notin` and `isnot` have the obvious meanings.
Templates are especially useful for lazy evaluation purposes. Consider a Templates are especially useful for lazy evaluation purposes. Consider a
simple proc for logging: simple proc for logging:
@ -591,11 +593,11 @@ simple proc for logging:
x = 4 x = 4
log("x has the value: " & $x) log("x has the value: " & $x)
This code has a shortcoming: if ``debug`` is set to false someday, the quite This code has a shortcoming: if `debug` is set to false someday, the quite
expensive ``$`` and ``&`` operations are still performed! (The argument expensive `$` and `&` operations are still performed! (The argument
evaluation for procedures is *eager*). 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 .. code-block:: nim
:test: "nim c $1" :test: "nim c $1"
@ -609,15 +611,15 @@ Turning the ``log`` proc into a template solves this problem:
x = 4 x = 4
log("x has the value: " & $x) log("x has the value: " & $x)
The parameters' types can be ordinary types or the meta types ``untyped``, 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 `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 as an argument, and `untyped` means symbol lookups and type resolution is not
performed before the expression is passed to the template. performed before the expression is passed to the template.
If the template has no explicit return type, 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 .. code-block:: nim
:test: "nim c $1" :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 1")
txt.writeLine("line 2") txt.writeLine("line 2")
In the example the two ``writeLine`` statements are bound to the ``body`` In the example the two `writeLine` statements are bound to the `body`
parameter. The ``withFile`` template contains boilerplate code and helps to parameter. The `withFile` template contains boilerplate code and helps to
avoid a common bug: to forget to close the file. Note how the 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. once.
Example: Lifting Procs Example: Lifting Procs
@ -653,7 +655,7 @@ Example: Lifting Procs
template liftScalarProc(fname) = template liftScalarProc(fname) =
## Lift a proc taking one scalar parameter and returning a ## 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 ## to provide templated procs that can handle a single
## parameter of seq[T] or nested seq[seq[]] or the same type ## 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 Nim code can be compiled to JavaScript. However in order to write
JavaScript-compatible code you should remember the following: 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 It is recommended to avoid those if you're not sure how they are translated
to JavaScript. 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 between signed/unsigned ints, in which case it behaves as static cast in
C language. C language.
- ``cstring`` in JavaScript means JavaScript string. It is a good practice to - `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 use `cstring` only when it is semantically appropriate. E.g. don't use
``cstring`` as a binary data buffer. `cstring` as a binary data buffer.
Part 3 Part 3

View file

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

View file

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