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:
parent
15586c7a7a
commit
83ae70cb54
30 changed files with 1402 additions and 1350 deletions
30
doc/apis.rst
30
doc/apis.rst
|
|
@ -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
|
||||||
|
|
|
||||||
114
doc/backends.rst
114
doc/backends.rst
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
100
doc/docgen.rst
100
doc/docgen.rst
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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`.
|
||||||
|
|
|
||||||
24
doc/estp.rst
24
doc/estp.rst
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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::
|
||||||
|
|
|
||||||
92
doc/gc.rst
92
doc/gc.rst
|
|
@ -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.
|
||||||
|
|
|
||||||
28
doc/hcr.rst
28
doc/hcr.rst
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
138
doc/intern.rst
138
doc/intern.rst
|
|
@ -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:
|
||||||
|
|
|
||||||
24
doc/koch.rst
24
doc/koch.rst
|
|
@ -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
|
||||||
-----------
|
-----------
|
||||||
|
|
|
||||||
68
doc/lib.rst
68
doc/lib.rst
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
42
doc/nep1.rst
42
doc/nep1.rst
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
222
doc/nimc.rst
222
doc/nimc.rst
|
|
@ -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:.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"`
|
||||||
==================== =======================================================
|
==================== =======================================================
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
78
doc/nims.rst
78
doc/nims.rst
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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**.
|
||||||
|
|
|
||||||
|
|
@ -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>`_
|
||||||
|
|
|
||||||
|
|
@ -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)>`_,
|
||||||
|
|
|
||||||
410
doc/tut1.rst
410
doc/tut1.rst
File diff suppressed because it is too large
Load diff
160
doc/tut2.rst
160
doc/tut2.rst
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
.. default-role:: code
|
||||||
|
|
||||||
=======================
|
=======================
|
||||||
Nim Tutorial (Part III)
|
Nim Tutorial (Part III)
|
||||||
=======================
|
=======================
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue