mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-07 20:34:21 +00:00
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:
30
doc/apis.rst
30
doc/apis.rst
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
=================
|
||||
API naming design
|
||||
=================
|
||||
@@ -18,22 +20,22 @@ been renamed to fit this scheme. The ultimate goal is that the programmer can
|
||||
------------------- ------------ --------------------------------------
|
||||
English word To use Notes
|
||||
------------------- ------------ --------------------------------------
|
||||
initialize initT ``init`` is used to create a
|
||||
value type ``T``
|
||||
new newP ``new`` is used to create a
|
||||
reference type ``P``
|
||||
initialize initT `init` is used to create a
|
||||
value type `T`
|
||||
new newP `new` is used to create a
|
||||
reference type `P`
|
||||
find find should return the position where
|
||||
something was found; for a bool result
|
||||
use ``contains``
|
||||
contains contains often short for ``find() >= 0``
|
||||
append add use ``add`` instead of ``append``
|
||||
use `contains`
|
||||
contains contains often short for `find() >= 0`
|
||||
append add use `add` instead of `append`
|
||||
compare cmp should return an int with the
|
||||
``< 0`` ``== 0`` or ``> 0`` semantics;
|
||||
for a bool result use ``sameXYZ``
|
||||
put put, ``[]=`` consider overloading ``[]=`` for put
|
||||
get get, ``[]`` consider overloading ``[]`` for get;
|
||||
consider to not use ``get`` as a
|
||||
prefix: ``len`` instead of ``getLen``
|
||||
`< 0` `== 0` or `> 0` semantics;
|
||||
for a bool result use `sameXYZ`
|
||||
put put, `[]=` consider overloading `[]=` for put
|
||||
get get, `[]` consider overloading `[]` for get;
|
||||
consider to not use `get` as a
|
||||
prefix: `len` instead of `getLen`
|
||||
length len also used for *number of elements*
|
||||
size size, len size should refer to a byte size
|
||||
capacity cap
|
||||
@@ -44,7 +46,7 @@ delete delete, del del is supposed to be faster than
|
||||
delete, because it does not keep
|
||||
the order; delete keeps the order
|
||||
remove delete, del inconsistent right now
|
||||
remove-and-return pop ``Table``/``TableRef`` alias to ``take``
|
||||
remove-and-return pop `Table`/`TableRef` alias to `take`
|
||||
include incl
|
||||
exclude excl
|
||||
command cmd
|
||||
|
||||
114
doc/backends.rst
114
doc/backends.rst
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
================================
|
||||
Nim Backend Integration
|
||||
================================
|
||||
@@ -13,8 +15,8 @@ Introduction
|
||||
============
|
||||
|
||||
The `Nim Compiler User Guide <nimc.html>`_ documents the typical
|
||||
compiler invocation, using the ``compile`` or ``c`` command to transform a
|
||||
``.nim`` file into one or more ``.c`` files which are then compiled with the
|
||||
compiler invocation, using the `compile` or `c` command to transform a
|
||||
`.nim` file into one or more `.c` files which are then compiled with the
|
||||
platform's C compiler into a static binary. However, there are other commands
|
||||
to compile to C++, Objective-C, or JavaScript. This document tries to
|
||||
concentrate in a single place all the backend and interfacing options.
|
||||
@@ -23,7 +25,7 @@ The Nim compiler supports mainly two backend families: the C, C++ and
|
||||
Objective-C targets and the JavaScript target. `The C like targets
|
||||
<#backends-the-c-like-targets>`_ creates source files that can be compiled
|
||||
into a library or a final executable. `The JavaScript target
|
||||
<#backends-the-javascript-target>`_ can generate a ``.js`` file which you
|
||||
<#backends-the-javascript-target>`_ can generate a `.js` file which you
|
||||
reference from an HTML file or create a `standalone Node.js program
|
||||
<http://nodejs.org>`_.
|
||||
|
||||
@@ -45,7 +47,7 @@ The commands to compile to either C, C++ or Objective-C are:
|
||||
//compileToOC, objc compile project to Objective C code
|
||||
|
||||
The most significant difference between these commands is that if you look
|
||||
into the ``nimcache`` directory you will find ``.c``, ``.cpp`` or ``.m``
|
||||
into the `nimcache` directory you will find `.c`, `.cpp` or `.m`
|
||||
files, other than that all of them will produce a native binary for your
|
||||
project. This allows you to take the generated code and place it directly
|
||||
into a project using any of these languages. Here are some typical command-
|
||||
@@ -64,17 +66,17 @@ or compiler/linker commands.
|
||||
The JavaScript target
|
||||
---------------------
|
||||
|
||||
Nim can also generate `JavaScript`:idx: code through the ``js`` command.
|
||||
Nim can also generate `JavaScript`:idx: code through the `js` command.
|
||||
|
||||
Nim targets JavaScript 1.5 which is supported by any widely used browser.
|
||||
Since JavaScript does not have a portable means to include another module,
|
||||
Nim just generates a long ``.js`` file.
|
||||
Nim just generates a long `.js` file.
|
||||
|
||||
Features or modules that the JavaScript platform does not support are not
|
||||
available. This includes:
|
||||
|
||||
* manual memory management (``alloc``, etc.)
|
||||
* casting and other unsafe operations (``cast`` operator, ``zeroMem``, etc.)
|
||||
* manual memory management (`alloc`, etc.)
|
||||
* casting and other unsafe operations (`cast` operator, `zeroMem`, etc.)
|
||||
* file management
|
||||
* OS-specific operations
|
||||
* threading, coroutines
|
||||
@@ -86,14 +88,14 @@ To compensate, the standard library has modules `catered to the JS backend
|
||||
and more support will come in the future (for instance, Node.js bindings
|
||||
to get OS info).
|
||||
|
||||
To compile a Nim module into a ``.js`` file use the ``js`` command; the
|
||||
default is a ``.js`` file that is supposed to be referenced in an ``.html``
|
||||
To compile a Nim module into a `.js` file use the `js` command; the
|
||||
default is a `.js` file that is supposed to be referenced in an `.html`
|
||||
file. However, you can also run the code with `nodejs`:idx:
|
||||
(`<http://nodejs.org>`_)::
|
||||
|
||||
nim js -d:nodejs -r examples/hallo.nim
|
||||
|
||||
If you experience errors saying that ``globalThis`` is not defined, be
|
||||
If you experience errors saying that `globalThis` is not defined, be
|
||||
sure to run a recent version of Node.js (at least 12.0).
|
||||
|
||||
|
||||
@@ -113,7 +115,7 @@ Nim code calling the backend
|
||||
Nim code can interface with the backend through the `Foreign function
|
||||
interface <manual.html#foreign-function-interface>`_ mainly through the
|
||||
`importc pragma <manual.html#foreign-function-interface-importc-pragma>`_.
|
||||
The ``importc`` pragma is the *generic* way of making backend symbols available
|
||||
The `importc` pragma is the *generic* way of making backend symbols available
|
||||
in Nim and is available in all the target backends (JavaScript too). The C++
|
||||
or Objective-C backends have their respective `ImportCpp
|
||||
<manual.html#implementation-specific-pragmas-importcpp-pragma>`_ and
|
||||
@@ -123,7 +125,7 @@ pragmas to call methods from classes.
|
||||
Whenever you use any of these pragmas you need to integrate native code into
|
||||
your final binary. In the case of JavaScript this is no problem at all, the
|
||||
same HTML file which hosts the generated JavaScript will likely provide other
|
||||
JavaScript functions which you are importing with ``importc``.
|
||||
JavaScript functions which you are importing with `importc`.
|
||||
|
||||
However, for the C like targets you need to link external code either
|
||||
statically or dynamically. The preferred way of integrating native code is to
|
||||
@@ -148,7 +150,7 @@ interface.
|
||||
C invocation example
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Create a ``logic.c`` file with the following content:
|
||||
Create a `logic.c` file with the following content:
|
||||
|
||||
.. code-block:: c
|
||||
int addTwoIntegers(int a, int b)
|
||||
@@ -156,7 +158,7 @@ Create a ``logic.c`` file with the following content:
|
||||
return a + b;
|
||||
}
|
||||
|
||||
Create a ``calculator.nim`` file with the following content:
|
||||
Create a `calculator.nim` file with the following content:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
@@ -166,26 +168,26 @@ Create a ``calculator.nim`` file with the following content:
|
||||
when isMainModule:
|
||||
echo addTwoIntegers(3, 7)
|
||||
|
||||
With these two files in place, you can run ``nim c -r calculator.nim`` and
|
||||
the Nim compiler will compile the ``logic.c`` file in addition to
|
||||
``calculator.nim`` and link both into an executable, which outputs ``10`` when
|
||||
With these two files in place, you can run `nim c -r calculator.nim` and
|
||||
the Nim compiler will compile the `logic.c` file in addition to
|
||||
`calculator.nim` and link both into an executable, which outputs `10` when
|
||||
run. Another way to link the C file statically and get the same effect would
|
||||
be to remove the line with the ``compile`` pragma and run the following typical
|
||||
be to remove the line with the `compile` pragma and run the following typical
|
||||
Unix commands::
|
||||
|
||||
$ gcc -c logic.c
|
||||
$ ar rvs mylib.a logic.o
|
||||
$ nim c --passL:mylib.a -r calculator.nim
|
||||
|
||||
Just like in this example we pass the path to the ``mylib.a`` library (and we
|
||||
could as well pass ``logic.o``) we could be passing switches to link any other
|
||||
Just like in this example we pass the path to the `mylib.a` library (and we
|
||||
could as well pass `logic.o`) we could be passing switches to link any other
|
||||
static C library.
|
||||
|
||||
|
||||
JavaScript invocation example
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Create a ``host.html`` file with the following content:
|
||||
Create a `host.html` file with the following content:
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -199,7 +201,7 @@ Create a ``host.html`` file with the following content:
|
||||
<script type="text/javascript" src="calculator.js"></script>
|
||||
</body></html>
|
||||
|
||||
Create a ``calculator.nim`` file with the following content (or reuse the one
|
||||
Create a `calculator.nim` file with the following content (or reuse the one
|
||||
from the previous section):
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -209,9 +211,9 @@ from the previous section):
|
||||
when isMainModule:
|
||||
echo addTwoIntegers(3, 7)
|
||||
|
||||
Compile the Nim code to JavaScript with ``nim js -o:calculator.js
|
||||
calculator.nim`` and open ``host.html`` in a browser. If the browser supports
|
||||
javascript, you should see the value ``10`` in the browser's console. Use the
|
||||
Compile the Nim code to JavaScript with `nim js -o:calculator.js
|
||||
calculator.nim` and open `host.html` in a browser. If the browser supports
|
||||
javascript, you should see the value `10` in the browser's console. Use the
|
||||
`dom module <dom.html>`_ for specific DOM querying and modification procs
|
||||
or take a look at `karax <https://github.com/pragmagic/karax>`_ for how to
|
||||
develop browser-based applications.
|
||||
@@ -222,29 +224,29 @@ Backend code calling Nim
|
||||
|
||||
Backend code can interface with Nim code exposed through the `exportc
|
||||
pragma <manual.html#foreign-function-interface-exportc-pragma>`_. The
|
||||
``exportc`` pragma is the *generic* way of making Nim symbols available to
|
||||
`exportc` pragma is the *generic* way of making Nim symbols available to
|
||||
the backends. By default, the Nim compiler will mangle all the Nim symbols to
|
||||
avoid any name collision, so the most significant thing the ``exportc`` pragma
|
||||
avoid any name collision, so the most significant thing the `exportc` pragma
|
||||
does is maintain the Nim symbol name, or if specified, use an alternative
|
||||
symbol for the backend in case the symbol rules don't match.
|
||||
|
||||
The JavaScript target doesn't have any further interfacing considerations
|
||||
since it also has garbage collection, but the C targets require you to
|
||||
initialize Nim's internals, which is done calling a ``NimMain`` function.
|
||||
initialize Nim's internals, which is done calling a `NimMain` function.
|
||||
Also, C code requires you to specify a forward declaration for functions or
|
||||
the compiler will assume certain types for the return value and parameters
|
||||
which will likely make your program crash at runtime.
|
||||
|
||||
The Nim compiler can generate a C interface header through the ``--header``
|
||||
The Nim compiler can generate a C interface header through the `--header`
|
||||
command-line switch. The generated header will contain all the exported
|
||||
symbols and the ``NimMain`` proc which you need to call before any other
|
||||
symbols and the `NimMain` proc which you need to call before any other
|
||||
Nim code.
|
||||
|
||||
|
||||
Nim invocation example from C
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Create a ``fib.nim`` file with the following content:
|
||||
Create a `fib.nim` file with the following content:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
@@ -254,7 +256,7 @@ Create a ``fib.nim`` file with the following content:
|
||||
else:
|
||||
result = fib(a - 1) + fib(a - 2)
|
||||
|
||||
Create a ``maths.c`` file with the following content:
|
||||
Create a `maths.c` file with the following content:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@@ -277,30 +279,30 @@ program::
|
||||
$ gcc -o m -I$HOME/.cache/nim/fib_d -Ipath/to/nim/lib $HOME/.cache/nim/fib_d/*.c maths.c
|
||||
|
||||
The first command runs the Nim compiler with three special options to avoid
|
||||
generating a ``main()`` function in the generated files, avoid linking the
|
||||
generating a `main()` function in the generated files, avoid linking the
|
||||
object files into a final binary, and explicitly generate a header file for C
|
||||
integration. All the generated files are placed into the ``nimcache``
|
||||
directory. That's why the next command compiles the ``maths.c`` source plus
|
||||
all the ``.c`` files from ``nimcache``. In addition to this path, you also
|
||||
have to tell the C compiler where to find Nim's ``nimbase.h`` header file.
|
||||
integration. All the generated files are placed into the `nimcache`
|
||||
directory. That's why the next command compiles the `maths.c` source plus
|
||||
all the `.c` files from `nimcache`. In addition to this path, you also
|
||||
have to tell the C compiler where to find Nim's `nimbase.h` header file.
|
||||
|
||||
Instead of depending on the generation of the individual ``.c`` files you can
|
||||
Instead of depending on the generation of the individual `.c` files you can
|
||||
also ask the Nim compiler to generate a statically linked library::
|
||||
|
||||
$ nim c --app:staticLib --noMain --header fib.nim
|
||||
$ gcc -o m -Inimcache -Ipath/to/nim/lib libfib.nim.a maths.c
|
||||
|
||||
The Nim compiler will handle linking the source files generated in the
|
||||
``nimcache`` directory into the ``libfib.nim.a`` static library, which you can
|
||||
`nimcache` directory into the `libfib.nim.a` static library, which you can
|
||||
then link into your C program. Note that these commands are generic and will
|
||||
vary for each system. For instance, on Linux systems you will likely need to
|
||||
use ``-ldl`` too to link in required dlopen functionality.
|
||||
use `-ldl` too to link in required dlopen functionality.
|
||||
|
||||
|
||||
Nim invocation example from JavaScript
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Create a ``mhost.html`` file with the following content:
|
||||
Create a `mhost.html` file with the following content:
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -311,7 +313,7 @@ Create a ``mhost.html`` file with the following content:
|
||||
</script>
|
||||
</body></html>
|
||||
|
||||
Create a ``fib.nim`` file with the following content (or reuse the one
|
||||
Create a `fib.nim` file with the following content (or reuse the one
|
||||
from the previous section):
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -322,10 +324,10 @@ from the previous section):
|
||||
else:
|
||||
result = fib(a - 1) + fib(a - 2)
|
||||
|
||||
Compile the Nim code to JavaScript with ``nim js -o:fib.js fib.nim`` and
|
||||
open ``mhost.html`` in a browser. If the browser supports javascript, you
|
||||
should see an alert box displaying the text ``Fib for 9 is 34``. As mentioned
|
||||
earlier, JavaScript doesn't require an initialization call to ``NimMain`` or
|
||||
Compile the Nim code to JavaScript with `nim js -o:fib.js fib.nim` and
|
||||
open `mhost.html` in a browser. If the browser supports javascript, you
|
||||
should see an alert box displaying the text `Fib for 9 is 34`. As mentioned
|
||||
earlier, JavaScript doesn't require an initialization call to `NimMain` or
|
||||
a similar function and you can call the exported Nim proc directly.
|
||||
|
||||
|
||||
@@ -335,14 +337,14 @@ Nimcache naming logic
|
||||
The `nimcache`:idx: directory is generated during compilation and will hold
|
||||
either temporary or final files depending on your backend target. The default
|
||||
name for the directory depends on the used backend and on your OS but you can
|
||||
use the ``--nimcache`` `compiler switch
|
||||
use the `--nimcache` `compiler switch
|
||||
<nimc.html#compiler-usage-commandminusline-switches>`_ to change it.
|
||||
|
||||
|
||||
Memory management
|
||||
=================
|
||||
|
||||
In the previous sections, the ``NimMain()`` function reared its head. Since
|
||||
In the previous sections, the `NimMain()` function reared its head. Since
|
||||
JavaScript already provides automatic memory management, you can freely pass
|
||||
objects between the two languages without problems. In C and derivate languages
|
||||
you need to be careful about what you do and how you share memory. The
|
||||
@@ -357,15 +359,15 @@ Strings and C strings
|
||||
The manual mentions that `Nim strings are implicitly convertible to
|
||||
cstrings <manual.html#types-cstring-type>`_ which makes interaction usually
|
||||
painless. Most C functions accepting a Nim string converted to a
|
||||
``cstring`` will likely not need to keep this string around and by the time
|
||||
`cstring` will likely not need to keep this string around and by the time
|
||||
they return the string won't be needed anymore. However, for the rare cases
|
||||
where a Nim string has to be preserved and made available to the C backend
|
||||
as a ``cstring``, you will need to manually prevent the string data from being
|
||||
as a `cstring`, you will need to manually prevent the string data from being
|
||||
freed with `GC_ref <system.html#GC_ref,string>`_ and `GC_unref
|
||||
<system.html#GC_unref,string>`_.
|
||||
|
||||
A similar thing happens with C code invoking Nim code which returns a
|
||||
``cstring``. Consider the following proc:
|
||||
`cstring`. Consider the following proc:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
@@ -373,8 +375,8 @@ A similar thing happens with C code invoking Nim code which returns a
|
||||
result = "Hey there C code! " & $rand(100)
|
||||
|
||||
Since Nim's garbage collector is not aware of the C code, once the
|
||||
``gimme`` proc has finished it can reclaim the memory of the ``cstring``.
|
||||
However, from a practical standpoint, the C code invoking the ``gimme``
|
||||
`gimme` proc has finished it can reclaim the memory of the `cstring`.
|
||||
However, from a practical standpoint, the C code invoking the `gimme`
|
||||
function directly will be able to use it since Nim's garbage collector has
|
||||
not had a chance to run *yet*. This gives you enough time to make a copy for
|
||||
the C side of the program, as calling any further Nim procs *might* trigger
|
||||
@@ -397,14 +399,14 @@ Again, if you are wrapping a library which *mallocs* and *frees* data
|
||||
structures, you need to expose the appropriate *free* function to Nim so
|
||||
you can clean it up. And of course, once cleaned you should avoid accessing it
|
||||
from Nim (or C for that matter). Typically C data structures have their own
|
||||
``malloc_structure`` and ``free_structure`` specific functions, so wrapping
|
||||
`malloc_structure` and `free_structure` specific functions, so wrapping
|
||||
these for the Nim side should be enough.
|
||||
|
||||
|
||||
Thread coordination
|
||||
-------------------
|
||||
|
||||
When the ``NimMain()`` function is called Nim initializes the garbage
|
||||
When the `NimMain()` function is called Nim initializes the garbage
|
||||
collector to the current thread, which is usually the main thread of your
|
||||
application. If your C code later spawns a different thread and calls Nim
|
||||
code, the garbage collector will fail to work properly and you will crash.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
==================================
|
||||
Nim Destructors and Move Semantics
|
||||
==================================
|
||||
@@ -16,7 +18,7 @@ not use classical GC algorithms anymore but is based on destructors and
|
||||
move semantics. The new runtime's advantages are that Nim programs become
|
||||
oblivious to the involved heap sizes and programs are easier to write to make
|
||||
effective use of multi-core machines. As a nice bonus, files and sockets and
|
||||
the like will not require manual ``close`` calls anymore.
|
||||
the like will not require manual `close` calls anymore.
|
||||
|
||||
This document aims to be a precise specification about how
|
||||
move semantics and destructors work in Nim.
|
||||
@@ -89,12 +91,12 @@ written as:
|
||||
Lifetime-tracking hooks
|
||||
=======================
|
||||
|
||||
The memory management for Nim's standard ``string`` and ``seq`` types as
|
||||
The memory management for Nim's standard `string` and `seq` types as
|
||||
well as other standard collections is performed via so-called
|
||||
"Lifetime-tracking hooks", which are particular `type bound operators <manual.html#procedures-type-bound-operators>`_.
|
||||
|
||||
There are 3 different hooks for each (generic or concrete) object type ``T`` (``T`` can also be a
|
||||
``distinct`` type) that are called implicitly by the compiler.
|
||||
There are 3 different hooks for each (generic or concrete) object type `T` (`T` can also be a
|
||||
`distinct` type) that are called implicitly by the compiler.
|
||||
|
||||
(Note: The word "hook" here does not imply any kind of dynamic binding
|
||||
or runtime indirections, the implicit calls are statically bound and
|
||||
@@ -109,14 +111,14 @@ other associated resources. Variables are destroyed via this hook when
|
||||
they go out of scope or when the routine they were declared in is about
|
||||
to return.
|
||||
|
||||
The prototype of this hook for a type ``T`` needs to be:
|
||||
The prototype of this hook for a type `T` needs to be:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
proc `=destroy`(x: var T)
|
||||
|
||||
|
||||
The general pattern in ``=destroy`` looks like:
|
||||
The general pattern in `=destroy` looks like:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
@@ -133,20 +135,20 @@ The general pattern in ``=destroy`` looks like:
|
||||
A `=sink` hook moves an object around, the resources are stolen from the source
|
||||
and passed to the destination. It is ensured that the source's destructor does
|
||||
not free the resources afterward by setting the object to its default value
|
||||
(the value the object's state started in). Setting an object ``x`` back to its
|
||||
default value is written as ``wasMoved(x)``. When not provided the compiler
|
||||
(the value the object's state started in). Setting an object `x` back to its
|
||||
default value is written as `wasMoved(x)`. When not provided the compiler
|
||||
is using a combination of `=destroy` and `copyMem` instead. This is efficient
|
||||
hence users rarely need to implement their own `=sink` operator, it is enough to
|
||||
provide `=destroy` and `=copy`, compiler will take care of the rest.
|
||||
|
||||
The prototype of this hook for a type ``T`` needs to be:
|
||||
The prototype of this hook for a type `T` needs to be:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
proc `=sink`(dest: var T; source: T)
|
||||
|
||||
|
||||
The general pattern in ``=sink`` looks like:
|
||||
The general pattern in `=sink` looks like:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
@@ -156,25 +158,25 @@ The general pattern in ``=sink`` looks like:
|
||||
dest.field = source.field
|
||||
|
||||
|
||||
**Note**: ``=sink`` does not need to check for self-assignments.
|
||||
**Note**: `=sink` does not need to check for self-assignments.
|
||||
How self-assignments are handled is explained later in this document.
|
||||
|
||||
|
||||
`=copy` hook
|
||||
---------------
|
||||
|
||||
The ordinary assignment in Nim conceptually copies the values. The ``=copy`` hook
|
||||
is called for assignments that couldn't be transformed into ``=sink``
|
||||
The ordinary assignment in Nim conceptually copies the values. The `=copy` hook
|
||||
is called for assignments that couldn't be transformed into `=sink`
|
||||
operations.
|
||||
|
||||
The prototype of this hook for a type ``T`` needs to be:
|
||||
The prototype of this hook for a type `T` needs to be:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
proc `=copy`(dest: var T; source: T)
|
||||
|
||||
|
||||
The general pattern in ``=copy`` looks like:
|
||||
The general pattern in `=copy` looks like:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
@@ -186,48 +188,48 @@ The general pattern in ``=copy`` looks like:
|
||||
dest.field = duplicateResource(source.field)
|
||||
|
||||
|
||||
The ``=copy`` proc can be marked with the ``{.error.}`` pragma. Then any assignment
|
||||
The `=copy` proc can be marked with the `{.error.}` pragma. Then any assignment
|
||||
that otherwise would lead to a copy is prevented at compile-time. This looks like:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
proc `=copy`(dest: var T; source: T) {.error.}
|
||||
|
||||
but a custom error message (e.g., ``{.error: "custom error".}``) will not be emitted
|
||||
by the compiler. Notice that there is no ``=`` before the ``{.error.}`` pragma.
|
||||
but a custom error message (e.g., `{.error: "custom error".}`) will not be emitted
|
||||
by the compiler. Notice that there is no `=` before the `{.error.}` pragma.
|
||||
|
||||
Move semantics
|
||||
==============
|
||||
|
||||
A "move" can be regarded as an optimized copy operation. If the source of the
|
||||
copy operation is not used afterward, the copy can be replaced by a move. This
|
||||
document uses the notation ``lastReadOf(x)`` to describe that ``x`` is not
|
||||
document uses the notation `lastReadOf(x)` to describe that `x` is not
|
||||
used afterwards. This property is computed by a static control flow analysis
|
||||
but can also be enforced by using ``system.move`` explicitly.
|
||||
but can also be enforced by using `system.move` explicitly.
|
||||
|
||||
|
||||
Swap
|
||||
====
|
||||
|
||||
The need to check for self-assignments and also the need to destroy previous
|
||||
objects inside ``=copy`` and ``=sink`` is a strong indicator to treat
|
||||
``system.swap`` as a builtin primitive of its own that simply swaps every
|
||||
field in the involved objects via ``copyMem`` or a comparable mechanism.
|
||||
In other words, ``swap(a, b)`` is **not** implemented
|
||||
as ``let tmp = move(b); b = move(a); a = move(tmp)``.
|
||||
objects inside `=copy` and `=sink` is a strong indicator to treat
|
||||
`system.swap` as a builtin primitive of its own that simply swaps every
|
||||
field in the involved objects via `copyMem` or a comparable mechanism.
|
||||
In other words, `swap(a, b)` is **not** implemented
|
||||
as `let tmp = move(b); b = move(a); a = move(tmp)`.
|
||||
|
||||
This has further consequences:
|
||||
|
||||
* Objects that contain pointers that point to the same object are not supported
|
||||
by Nim's model. Otherwise swapped objects would end up in an inconsistent state.
|
||||
* Seqs can use ``realloc`` in the implementation.
|
||||
* Seqs can use `realloc` in the implementation.
|
||||
|
||||
|
||||
Sink parameters
|
||||
===============
|
||||
|
||||
To move a variable into a collection usually ``sink`` parameters are involved.
|
||||
A location that is passed to a ``sink`` parameter should not be used afterward.
|
||||
To move a variable into a collection usually `sink` parameters are involved.
|
||||
A location that is passed to a `sink` parameter should not be used afterward.
|
||||
This is ensured by a static analysis over a control flow graph. If it cannot be
|
||||
proven to be the last usage of the location, a copy is done instead and this
|
||||
copy is then passed to the sink parameter.
|
||||
@@ -235,9 +237,9 @@ copy is then passed to the sink parameter.
|
||||
A sink parameter
|
||||
*may* be consumed once in the proc's body but doesn't have to be consumed at all.
|
||||
The reason for this is that signatures
|
||||
like ``proc put(t: var Table; k: sink Key, v: sink Value)`` should be possible
|
||||
without any further overloads and ``put`` might not take ownership of ``k`` if
|
||||
``k`` already exists in the table. Sink parameters enable an affine type system,
|
||||
like `proc put(t: var Table; k: sink Key, v: sink Value)` should be possible
|
||||
without any further overloads and `put` might not take ownership of `k` if
|
||||
`k` already exists in the table. Sink parameters enable an affine type system,
|
||||
not a linear type system.
|
||||
|
||||
The employed static analysis is limited and only concerned with local variables;
|
||||
@@ -254,7 +256,7 @@ however, object and tuple fields are treated as separate entities:
|
||||
echo tup[1]
|
||||
|
||||
|
||||
Sometimes it is required to explicitly ``move`` a value into its final position:
|
||||
Sometimes it is required to explicitly `move` a value into its final position:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
@@ -294,9 +296,9 @@ Rewrite rules
|
||||
|
||||
**Note**: There are two different allowed implementation strategies:
|
||||
|
||||
1. The produced ``finally`` section can be a single section that is wrapped
|
||||
1. The produced `finally` section can be a single section that is wrapped
|
||||
around the complete routine body.
|
||||
2. The produced ``finally`` section is wrapped around the enclosing scope.
|
||||
2. The produced `finally` section is wrapped around the enclosing scope.
|
||||
|
||||
The current implementation follows strategy (2). This means that resources are
|
||||
destroyed at the scope exit.
|
||||
@@ -359,13 +361,13 @@ Object and array construction
|
||||
=============================
|
||||
|
||||
Object and array construction is treated as a function call where the
|
||||
function has ``sink`` parameters.
|
||||
function has `sink` parameters.
|
||||
|
||||
|
||||
Destructor removal
|
||||
==================
|
||||
|
||||
``wasMoved(x);`` followed by a `=destroy(x)` operation cancel each other
|
||||
`wasMoved(x);` followed by a `=destroy(x)` operation cancel each other
|
||||
out. An implementation is encouraged to exploit this in order to improve
|
||||
efficiency and code sizes. The current implementation does perform this
|
||||
optimization.
|
||||
@@ -374,22 +376,22 @@ optimization.
|
||||
Self assignments
|
||||
================
|
||||
|
||||
``=sink`` in combination with ``wasMoved`` can handle self-assignments but
|
||||
`=sink` in combination with `wasMoved` can handle self-assignments but
|
||||
it's subtle.
|
||||
|
||||
The simple case of ``x = x`` cannot be turned
|
||||
into ``=sink(x, x); wasMoved(x)`` because that would lose ``x``'s value.
|
||||
The simple case of `x = x` cannot be turned
|
||||
into `=sink(x, x); wasMoved(x)` because that would lose `x`'s value.
|
||||
The solution is that simple self-assignments that consist of
|
||||
|
||||
- Symbols: ``x = x``
|
||||
- Field access: ``x.f = x.f``
|
||||
- Array, sequence or string access with indices known at compile-time: ``x[0] = x[0]``
|
||||
- Symbols: `x = x`
|
||||
- Field access: `x.f = x.f`
|
||||
- Array, sequence or string access with indices known at compile-time: `x[0] = x[0]`
|
||||
|
||||
are transformed into an empty statement that does nothing.
|
||||
The compiler is free to optimize further cases.
|
||||
|
||||
The complex case looks like a variant of ``x = f(x)``, we consider
|
||||
``x = select(rand() < 0.5, x, y)`` here:
|
||||
The complex case looks like a variant of `x = f(x)`, we consider
|
||||
`x = select(rand() < 0.5, x, y)` here:
|
||||
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -450,17 +452,17 @@ self-assignments.
|
||||
Lent type
|
||||
=========
|
||||
|
||||
``proc p(x: sink T)`` means that the proc ``p`` takes ownership of ``x``.
|
||||
`proc p(x: sink T)` means that the proc `p` takes ownership of `x`.
|
||||
To eliminate even more creation/copy <-> destruction pairs, a proc's return
|
||||
type can be annotated as ``lent T``. This is useful for "getter" accessors
|
||||
type can be annotated as `lent T`. This is useful for "getter" accessors
|
||||
that seek to allow an immutable view into a container.
|
||||
|
||||
The ``sink`` and ``lent`` annotations allow us to remove most (if not all)
|
||||
The `sink` and `lent` annotations allow us to remove most (if not all)
|
||||
superfluous copies and destructions.
|
||||
|
||||
``lent T`` is like ``var T`` a hidden pointer. It is proven by the compiler
|
||||
`lent T` is like `var T` a hidden pointer. It is proven by the compiler
|
||||
that the pointer does not outlive its origin. No destructor call is injected
|
||||
for expressions of type ``lent T`` or of type ``var T``.
|
||||
for expressions of type `lent T` or of type `var T`.
|
||||
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -494,9 +496,9 @@ for expressions of type ``lent T`` or of type ``var T``.
|
||||
The .cursor annotation
|
||||
======================
|
||||
|
||||
Under the ``--gc:arc|orc`` modes Nim's `ref` type is implemented via the same runtime
|
||||
Under the `--gc:arc|orc` modes Nim's `ref` type is implemented via the same runtime
|
||||
"hooks" and thus via reference counting. This means that cyclic structures cannot be freed
|
||||
immediately (``--gc:orc`` ships with a cycle collector). With the ``.cursor`` annotation
|
||||
immediately (`--gc:orc` ships with a cycle collector). With the `.cursor` annotation
|
||||
one can break up cycles declaratively:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -510,7 +512,7 @@ But please notice that this is not C++'s weak_ptr, it means the right field is n
|
||||
involved in the reference counting, it is a raw pointer without runtime checks.
|
||||
|
||||
Automatic reference counting also has the disadvantage that it introduces overhead
|
||||
when iterating over linked structures. The ``.cursor`` annotation can also be used
|
||||
when iterating over linked structures. The `.cursor` annotation can also be used
|
||||
to avoid this overhead:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -521,11 +523,11 @@ to avoid this overhead:
|
||||
it = it.next
|
||||
|
||||
|
||||
In fact, ``.cursor`` more generally prevents object construction/destruction pairs
|
||||
In fact, `.cursor` more generally prevents object construction/destruction pairs
|
||||
and so can also be useful in other contexts. The alternative solution would be to
|
||||
use raw pointers (``ptr``) instead which is more cumbersome and also more dangerous
|
||||
for Nim's evolution: Later on, the compiler can try to prove ``.cursor`` annotations
|
||||
to be safe, but for ``ptr`` the compiler has to remain silent about possible
|
||||
use raw pointers (`ptr`) instead which is more cumbersome and also more dangerous
|
||||
for Nim's evolution: Later on, the compiler can try to prove `.cursor` annotations
|
||||
to be safe, but for `ptr` the compiler has to remain silent about possible
|
||||
problems.
|
||||
|
||||
|
||||
@@ -556,13 +558,13 @@ indirections:
|
||||
Hook lifting
|
||||
============
|
||||
|
||||
The hooks of a tuple type ``(A, B, ...)`` are generated by lifting the
|
||||
hooks of the involved types ``A``, ``B``, ... to the tuple type. In
|
||||
other words, a copy ``x = y`` is implemented
|
||||
as ``x[0] = y[0]; x[1] = y[1]; ...``, likewise for ``=sink`` and ``=destroy``.
|
||||
The hooks of a tuple type `(A, B, ...)` are generated by lifting the
|
||||
hooks of the involved types `A`, `B`, ... to the tuple type. In
|
||||
other words, a copy `x = y` is implemented
|
||||
as `x[0] = y[0]; x[1] = y[1]; ...`, likewise for `=sink` and `=destroy`.
|
||||
|
||||
Other value-based compound types like ``object`` and ``array`` are handled
|
||||
correspondingly. For ``object`` however, the compiler-generated hooks
|
||||
Other value-based compound types like `object` and `array` are handled
|
||||
correspondingly. For `object` however, the compiler-generated hooks
|
||||
can be overridden. This can also be important to use an alternative traversal
|
||||
of the involved data structure that is more efficient or in order to avoid
|
||||
deep recursions.
|
||||
@@ -588,18 +590,18 @@ The ability to override a hook leads to a phase ordering problem:
|
||||
discard
|
||||
|
||||
|
||||
The solution is to define ``proc `=destroy`[T](f: var Foo[T])`` before
|
||||
The solution is to define `proc `=destroy`[T](f: var Foo[T])` before
|
||||
it is used. The compiler generates implicit
|
||||
hooks for all types in *strategic places* so that an explicitly provided
|
||||
hook that comes too "late" can be detected reliably. These *strategic places*
|
||||
have been derived from the rewrite rules and are as follows:
|
||||
|
||||
- In the construct ``let/var x = ...`` (var/let binding)
|
||||
hooks are generated for ``typeof(x)``.
|
||||
- In ``x = ...`` (assignment) hooks are generated for ``typeof(x)``.
|
||||
- In ``f(...)`` (function call) hooks are generated for ``typeof(f(...))``.
|
||||
- For every sink parameter ``x: sink T`` the hooks are generated
|
||||
for ``typeof(x)``.
|
||||
- In the construct `let/var x = ...` (var/let binding)
|
||||
hooks are generated for `typeof(x)`.
|
||||
- In `x = ...` (assignment) hooks are generated for `typeof(x)`.
|
||||
- In `f(...)` (function call) hooks are generated for `typeof(f(...))`.
|
||||
- For every sink parameter `x: sink T` the hooks are generated
|
||||
for `typeof(x)`.
|
||||
|
||||
|
||||
nodestroy pragma
|
||||
@@ -645,20 +647,18 @@ Instead the variable simply points to the literal.
|
||||
The literal is shared between different variables which are pointing to it.
|
||||
The copy operation is deferred until the first write.
|
||||
|
||||
```nim
|
||||
var x = "abc" # no copy
|
||||
var y = x # no copy
|
||||
```
|
||||
.. code-block:: nim
|
||||
var x = "abc" # no copy
|
||||
var y = x # no copy
|
||||
|
||||
The string literal "abc" is stored in static memory and not allocated on the heap.
|
||||
The variable `x` points to the literal and the variable `y` points to the literal too.
|
||||
There is no copy during assigning operations.
|
||||
|
||||
```nim
|
||||
var x = "abc" # no copy
|
||||
var y = x # no copy
|
||||
y[0] = 'h' # copy
|
||||
```
|
||||
.. code-block:: nim
|
||||
var x = "abc" # no copy
|
||||
var y = x # no copy
|
||||
y[0] = 'h' # copy
|
||||
|
||||
The program above shows when the copy operations happen.
|
||||
When mutating the variable `y`, the Nim compiler creates a fresh copy of `x`,
|
||||
@@ -670,37 +670,34 @@ and the variable `y` becomes a mutable string.
|
||||
|
||||
Let's look at a silly example demonstrating this behaviour:
|
||||
|
||||
```nim
|
||||
var x = "abc"
|
||||
var y = x
|
||||
.. code-block:: nim
|
||||
var x = "abc"
|
||||
var y = x
|
||||
|
||||
moveMem(addr y[0], addr x[0], 3)
|
||||
```
|
||||
moveMem(addr y[0], addr x[0], 3)
|
||||
|
||||
The program fails because we need to prepare a fresh copy for the variable `y`.
|
||||
`prepareMutation` should be called before the address operation.
|
||||
|
||||
```nim
|
||||
var x = "abc"
|
||||
var y = x
|
||||
.. code-block:: nim
|
||||
var x = "abc"
|
||||
var y = x
|
||||
|
||||
prepareMutation(y)
|
||||
moveMem(addr y[0], addr x[0], 3)
|
||||
assert y == "abc"
|
||||
```
|
||||
prepareMutation(y)
|
||||
moveMem(addr y[0], addr x[0], 3)
|
||||
assert y == "abc"
|
||||
|
||||
Now `prepareMutation` solves the problem.
|
||||
It manually creates a fresh copy and makes the variable `y` mutable.
|
||||
|
||||
```nim
|
||||
var x = "abc"
|
||||
var y = x
|
||||
.. code-block:: nim
|
||||
var x = "abc"
|
||||
var y = x
|
||||
|
||||
prepareMutation(y)
|
||||
moveMem(addr y[0], addr x[0], 3)
|
||||
moveMem(addr y[0], addr x[0], 3)
|
||||
moveMem(addr y[0], addr x[0], 3)
|
||||
assert y == "abc"
|
||||
```
|
||||
prepareMutation(y)
|
||||
moveMem(addr y[0], addr x[0], 3)
|
||||
moveMem(addr y[0], addr x[0], 3)
|
||||
moveMem(addr y[0], addr x[0], 3)
|
||||
assert y == "abc"
|
||||
|
||||
No matter how many times `moveMem` is called, the program compiles and runs.
|
||||
|
||||
100
doc/docgen.rst
100
doc/docgen.rst
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
===================================
|
||||
Nim DocGen Tools Guide
|
||||
===================================
|
||||
@@ -15,7 +17,7 @@ This document describes the `documentation generation tools`:idx: built into
|
||||
the `Nim compiler <nimc.html>`_, which can generate HTML and JSON output
|
||||
from input .nim files and projects, as well as HTML and LaTeX from input RST
|
||||
(reStructuredText) files. The output documentation will include the module
|
||||
dependencies (``import``), any top-level documentation comments (##), and
|
||||
dependencies (`import`), any top-level documentation comments (##), and
|
||||
exported symbols (*), including procedures, types, and variables.
|
||||
|
||||
Quick start
|
||||
@@ -125,12 +127,12 @@ Document Types
|
||||
HTML
|
||||
----
|
||||
|
||||
The generation of HTML documents is done via the ``doc`` command. This command
|
||||
The generation of HTML documents is done via the `doc` command. This command
|
||||
takes either a single .nim file, outputting a single .html file with the same
|
||||
base filename, or multiple .nim files, outputting multiple .html files and,
|
||||
optionally, an index file.
|
||||
|
||||
The ``doc`` command::
|
||||
The `doc` command::
|
||||
nim doc sample
|
||||
|
||||
Partial Output::
|
||||
@@ -146,12 +148,12 @@ compiler.
|
||||
JSON
|
||||
----
|
||||
|
||||
The generation of JSON documents is done via the ``jsondoc`` command. This command
|
||||
The generation of JSON documents is done via the `jsondoc` command. This command
|
||||
takes in a .nim file and outputs a .json file with the same base filename. Note
|
||||
that this tool is built off of the ``doc`` command (previously ``doc2``), and
|
||||
that this tool is built off of the `doc` command (previously `doc2`), and
|
||||
contains the same information.
|
||||
|
||||
The ``jsondoc`` command::
|
||||
The `jsondoc` command::
|
||||
nim jsondoc sample
|
||||
|
||||
Output::
|
||||
@@ -171,10 +173,10 @@ Output::
|
||||
]
|
||||
}
|
||||
|
||||
Similarly to the old ``doc`` command, the old ``jsondoc`` command has been
|
||||
renamed to ``jsondoc0``.
|
||||
Similarly to the old `doc` command, the old `jsondoc` command has been
|
||||
renamed to `jsondoc0`.
|
||||
|
||||
The ``jsondoc0`` command::
|
||||
The `jsondoc0` command::
|
||||
nim jsondoc0 sample
|
||||
|
||||
Output::
|
||||
@@ -190,8 +192,8 @@ Output::
|
||||
}
|
||||
]
|
||||
|
||||
Note that the ``jsondoc`` command outputs it's JSON without pretty-printing it,
|
||||
while ``jsondoc0`` outputs pretty-printed JSON.
|
||||
Note that the `jsondoc` command outputs it's JSON without pretty-printing it,
|
||||
while `jsondoc0` outputs pretty-printed JSON.
|
||||
|
||||
Related Options
|
||||
===============
|
||||
@@ -203,7 +205,7 @@ Project switch
|
||||
nim doc --project filename.nim
|
||||
|
||||
This will recursively generate documentation of all nim modules imported
|
||||
into the input module that belong to the Nimble package that ``filename.nim``
|
||||
into the input module that belong to the Nimble package that `filename.nim`
|
||||
belongs to.
|
||||
|
||||
|
||||
@@ -214,13 +216,13 @@ Index switch
|
||||
nim doc --index:on filename.nim
|
||||
|
||||
This will generate an index of all the exported symbols in the input Nim
|
||||
module, and put it into a neighboring file with the extension of ``.idx``. The
|
||||
module, and put it into a neighboring file with the extension of `.idx`. The
|
||||
index file is line-oriented (newlines have to be escaped). Each line
|
||||
represents a tab-separated record of several columns, the first two mandatory,
|
||||
the rest optional. See the `Index (idx) file format`_ section for details.
|
||||
|
||||
Once index files have been generated for one or more modules, the Nim
|
||||
compiler command ``buildIndex directory`` can be run to go over all the index
|
||||
compiler command `buildIndex directory` can be run to go over all the index
|
||||
files in the specified directory to generate a `theindex.html <theindex.html>`_
|
||||
file.
|
||||
|
||||
@@ -230,28 +232,28 @@ See source switch
|
||||
::
|
||||
nim doc --git.url:<url> filename.nim
|
||||
|
||||
With the ``git.url`` switch the *See source* hyperlink will appear below each
|
||||
With the `git.url` switch the *See source* hyperlink will appear below each
|
||||
documented item in your source code pointing to the implementation of that
|
||||
item on a GitHub repository.
|
||||
You can click the link to see the implementation of the item.
|
||||
|
||||
The ``git.commit`` switch overrides the hardcoded `devel` branch in config/nimdoc.cfg.
|
||||
The `git.commit` switch overrides the hardcoded `devel` branch in config/nimdoc.cfg.
|
||||
This is useful to link to a different branch e.g. `--git.commit:master`,
|
||||
or to a tag e.g. `--git.commit:1.2.3` or a commit.
|
||||
|
||||
Source URLs are generated as `href="${url}/tree/${commit}/${path}#L${line}"` by default and this compatible with GitHub but not with GitLab.
|
||||
|
||||
Similarly, ``git.devel`` switch overrides the hardcoded `devel` branch for the `Edit` link which is also useful if you have a different working branch than `devel` e.g. `--git.devel:master`.
|
||||
Similarly, `git.devel` switch overrides the hardcoded `devel` branch for the `Edit` link which is also useful if you have a different working branch than `devel` e.g. `--git.devel:master`.
|
||||
|
||||
Edit URLs are generated as `href="${url}/tree/${devel}/${path}#L${line}"` by default.
|
||||
|
||||
You can edit ``config/nimdoc.cfg`` and modify the ``doc.item.seesrc`` value with a hyperlink to your own code repository.
|
||||
You can edit `config/nimdoc.cfg` and modify the `doc.item.seesrc` value with a hyperlink to your own code repository.
|
||||
|
||||
In the case of Nim's own documentation, the ``commit`` value is just a commit
|
||||
In the case of Nim's own documentation, the `commit` value is just a commit
|
||||
hash to append to a formatted URL to https://github.com/nim-lang/Nim. The
|
||||
``tools/nimweb.nim`` helper queries the current git commit hash during the doc
|
||||
`tools/nimweb.nim` helper queries the current git commit hash during the doc
|
||||
generation, but since you might be working on an unpublished repository, it
|
||||
also allows specifying a ``githash`` value in ``web/website.ini`` to force a
|
||||
also allows specifying a `githash` value in `web/website.ini` to force a
|
||||
specific commit in the output.
|
||||
|
||||
|
||||
@@ -259,9 +261,9 @@ Other Input Formats
|
||||
===================
|
||||
|
||||
The *Nim compiler* also has support for RST (reStructuredText) files with
|
||||
the ``rst2html`` and ``rst2tex`` commands. Documents like this one are
|
||||
the `rst2html` and `rst2tex` commands. Documents like this one are
|
||||
initially written in a dialect of RST which adds support for nim source code
|
||||
highlighting with the ``.. code-block:: nim`` prefix. ``code-block`` also
|
||||
highlighting with the `.. code-block:: nim` prefix. `code-block` also
|
||||
supports highlighting of C++ and some other c-like languages.
|
||||
|
||||
Usage::
|
||||
@@ -270,17 +272,17 @@ Usage::
|
||||
Output::
|
||||
You're reading it!
|
||||
|
||||
The ``rst2tex`` command is invoked identically to ``rst2html``, but outputs
|
||||
The `rst2tex` command is invoked identically to `rst2html`, but outputs
|
||||
a .tex file instead of .html.
|
||||
|
||||
|
||||
HTML anchor generation
|
||||
======================
|
||||
|
||||
When you run the ``rst2html`` command, all sections in the RST document will
|
||||
When you run the `rst2html` command, all sections in the RST document will
|
||||
get an anchor you can hyperlink to. Usually, you can guess the anchor lower
|
||||
casing the section title and replacing spaces with dashes, and in any case, you
|
||||
can get it from the table of contents. But when you run the ``doc``
|
||||
can get it from the table of contents. But when you run the `doc`
|
||||
command to generate API documentation, some symbol get one or two anchors at
|
||||
the same time: a numerical identifier, or a plain name plus a complex name.
|
||||
|
||||
@@ -312,31 +314,31 @@ suffix may be added depending on the type of the callable:
|
||||
Callable type Suffix
|
||||
------------- --------------
|
||||
proc *empty string*
|
||||
macro ``.m``
|
||||
method ``.e``
|
||||
iterator ``.i``
|
||||
template ``.t``
|
||||
converter ``.c``
|
||||
macro `.m`
|
||||
method `.e`
|
||||
iterator `.i`
|
||||
template `.t`
|
||||
converter `.c`
|
||||
------------- --------------
|
||||
|
||||
The relationship of type to suffix is made by the proc ``complexName`` in the
|
||||
``compiler/docgen.nim`` file. Here are some examples of complex names for
|
||||
The relationship of type to suffix is made by the proc `complexName` in the
|
||||
`compiler/docgen.nim` file. Here are some examples of complex names for
|
||||
symbols in the `system module <system.html>`_.
|
||||
|
||||
* ``type SomeSignedInt = int | int8 | int16 | int32 | int64`` **=>**
|
||||
* `type SomeSignedInt = int | int8 | int16 | int32 | int64` **=>**
|
||||
`#SomeSignedInt <system.html#SomeSignedInt>`_
|
||||
* ``var globalRaiseHook: proc (e: ref E_Base): bool {.nimcall.}`` **=>**
|
||||
* `var globalRaiseHook: proc (e: ref E_Base): bool {.nimcall.}` **=>**
|
||||
`#globalRaiseHook <system.html#globalRaiseHook>`_
|
||||
* ``const NimVersion = "0.0.0"`` **=>**
|
||||
* `const NimVersion = "0.0.0"` **=>**
|
||||
`#NimVersion <system.html#NimVersion>`_
|
||||
* ``proc getTotalMem(): int {.rtl, raises: [], tags: [].}`` **=>**
|
||||
* `proc getTotalMem(): int {.rtl, raises: [], tags: [].}` **=>**
|
||||
`#getTotalMem, <system.html#getTotalMem>`_
|
||||
* ``proc len[T](x: seq[T]): int {.magic: "LengthSeq", noSideEffect.}`` **=>**
|
||||
* `proc len[T](x: seq[T]): int {.magic: "LengthSeq", noSideEffect.}` **=>**
|
||||
`#len,seq[T] <system.html#len,seq[T]>`_
|
||||
* ``iterator pairs[T](a: seq[T]): tuple[key: int, val: T] {.inline.}`` **=>**
|
||||
* `iterator pairs[T](a: seq[T]): tuple[key: int, val: T] {.inline.}` **=>**
|
||||
`#pairs.i,seq[T] <iterators.html#pairs.i,seq[T]>`_
|
||||
* ``template newException[](exceptn: typedesc; message: string;
|
||||
parentException: ref Exception = nil): untyped`` **=>**
|
||||
* `template newException[](exceptn: typedesc; message: string;
|
||||
parentException: ref Exception = nil): untyped` **=>**
|
||||
`#newException.t,typedesc,string,ref.Exception
|
||||
<system.html#newException.t,typedesc,string,ref.Exception>`_
|
||||
|
||||
@@ -344,13 +346,13 @@ symbols in the `system module <system.html>`_.
|
||||
Index (idx) file format
|
||||
=======================
|
||||
|
||||
Files with the ``.idx`` extension are generated when you use the `Index
|
||||
Files with the `.idx` extension are generated when you use the `Index
|
||||
switch <#related-options-index-switch>`_ along with commands to generate
|
||||
documentation from source or text files. You can programmatically generate
|
||||
indices with the `setIndexTerm()
|
||||
<rstgen.html#setIndexTerm,RstGenerator,string,string,string,string,string>`_
|
||||
and `writeIndexFile() <rstgen.html#writeIndexFile,RstGenerator,string>`_ procs.
|
||||
The purpose of ``idx`` files is to hold the interesting symbols and their HTML
|
||||
The purpose of `idx` files is to hold the interesting symbols and their HTML
|
||||
references so they can be later concatenated into a big index file with
|
||||
`mergeIndexes() <rstgen.html#mergeIndexes,string>`_. This section documents
|
||||
the file format in detail.
|
||||
@@ -362,7 +364,7 @@ columns is:
|
||||
|
||||
1. Mandatory term being indexed. Terms can include quoting according to
|
||||
Nim's rules (e.g. \`^\`).
|
||||
2. Base filename plus anchor hyperlink (e.g. ``algorithm.html#*,int,SortOrder``).
|
||||
2. Base filename plus anchor hyperlink (e.g. `algorithm.html#*,int,SortOrder`).
|
||||
3. Optional human-readable string to display as a hyperlink. If the value is not
|
||||
present or is the empty string, the hyperlink will be rendered
|
||||
using the term. Prefix whitespace indicates that this entry is
|
||||
@@ -371,8 +373,8 @@ columns is:
|
||||
this as a tooltip after hovering a moment over the hyperlink.
|
||||
|
||||
The index generation tools try to differentiate between documentation
|
||||
generated from ``.nim`` files and documentation generated from ``.txt`` or
|
||||
``.rst`` files. The former are always closely related to source code and
|
||||
generated from `.nim` files and documentation generated from `.txt` or
|
||||
`.rst` files. The former are always closely related to source code and
|
||||
consist mainly of API entries. The latter are generic documents meant for
|
||||
human reading.
|
||||
|
||||
@@ -391,7 +393,7 @@ the index file with their third column having as much prefix spaces as their
|
||||
level is in the TOC (at least 1 character). The prefix whitespace helps to
|
||||
filter TOC entries from API or text symbols. This is important because the
|
||||
amount of spaces is used to replicate the hierarchy for document TOCs in the
|
||||
final index, and TOC entries found in ``.nim`` files are discarded.
|
||||
final index, and TOC entries found in `.nim` files are discarded.
|
||||
|
||||
|
||||
Additional resources
|
||||
@@ -402,8 +404,8 @@ Additional resources
|
||||
`RST Quick Reference
|
||||
<http://docutils.sourceforge.net/docs/user/rst/quickref.html>`_
|
||||
|
||||
The output for HTML and LaTeX comes from the ``config/nimdoc.cfg`` and
|
||||
``config/nimdoc.tex.cfg`` configuration files. You can add and modify these
|
||||
The output for HTML and LaTeX comes from the `config/nimdoc.cfg` and
|
||||
`config/nimdoc.tex.cfg` configuration files. You can add and modify these
|
||||
files to your project to change the look of the docgen output.
|
||||
|
||||
You can import the `packages/docutils/rstgen module <rstgen.html>`_ in your
|
||||
|
||||
@@ -6,7 +6,7 @@ General Guidelines
|
||||
|
||||
* See also `nep1<https://nim-lang.github.io/Nim/nep1.html>`_ which should probably be merged here.
|
||||
* Authors should document anything that is exported; documentation for private
|
||||
procs can be useful too (visible via ``nim doc --docInternal foo.nim``).
|
||||
procs can be useful too (visible via `nim doc --docInternal foo.nim`).
|
||||
* Within documentation, a period (`.`) should follow each sentence (or sentence fragment) in a comment block.
|
||||
The documentation may be limited to one sentence fragment, but if multiple sentences are within the documentation,
|
||||
each sentence after the first should be complete and in present tense.
|
||||
@@ -15,7 +15,7 @@ General Guidelines
|
||||
and `nim doc` supports it. Likewise with rst files: `nim rst2html` will render those as monospace, and
|
||||
adding `.. default-role:: code` to an rst file will also make those render as monospace when rendered directly
|
||||
in tools such as github.
|
||||
* In nim sources, for links, prefer `[link text](link.html)` to ``` `link text<link.html>`_ ```
|
||||
* In nim sources, for links, prefer `[link text](link.html)` to `` `link text<link.html>`_ ``
|
||||
since the syntax is simpler and markdown is more common (likewise, `nim rst2html` also supports it in rst files).
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -28,8 +28,8 @@ General Guidelines
|
||||
Module-level documentation
|
||||
--------------------------
|
||||
|
||||
Documentation of a module is placed at the top of the module itself. Each line of documentation begins with double hashes (``##``).
|
||||
Sometimes ``##[ multiline docs containing code ]##`` is preferable, see ``lib/pure/times.nim``.
|
||||
Documentation of a module is placed at the top of the module itself. Each line of documentation begins with double hashes (`##`).
|
||||
Sometimes `##[ multiline docs containing code ]##` is preferable, see `lib/pure/times.nim`.
|
||||
Code samples are encouraged, and should follow the general RST syntax:
|
||||
|
||||
.. code-block:: Nim
|
||||
@@ -80,7 +80,7 @@ Whenever an example of usage would be helpful to the user, you should include on
|
||||
doAssert addThree(3, 125, 6) == -122
|
||||
result = x +% y +% z
|
||||
|
||||
The command ``nim doc`` will then correctly syntax highlight the Nim code within the documentation.
|
||||
The command `nim doc` will then correctly syntax highlight the Nim code within the documentation.
|
||||
|
||||
Types
|
||||
-----
|
||||
@@ -116,8 +116,8 @@ Make sure to place the documentation beside or within the object.
|
||||
.. code-block:: Nim
|
||||
|
||||
type
|
||||
## Bad: this documentation disappears because it annotates the ``type`` keyword
|
||||
## above, not ``NamedQueue``.
|
||||
## Bad: this documentation disappears because it annotates the `type` keyword
|
||||
## above, not `NamedQueue`.
|
||||
NamedQueue*[T] = object
|
||||
name*: string ## This becomes the main documentation for the object, which
|
||||
## is not what we want.
|
||||
@@ -127,7 +127,7 @@ Make sure to place the documentation beside or within the object.
|
||||
Var, Let, and Const
|
||||
-------------------
|
||||
|
||||
When declaring module-wide constants and values, documentation is encouraged. The placement of doc comments is similar to the ``type`` sections.
|
||||
When declaring module-wide constants and values, documentation is encouraged. The placement of doc comments is similar to the `type` sections.
|
||||
|
||||
.. code-block:: Nim
|
||||
|
||||
@@ -137,9 +137,9 @@ When declaring module-wide constants and values, documentation is encouraged. Th
|
||||
[1,2,3],
|
||||
[2,3,1],
|
||||
[3,1,2],
|
||||
] ## Doc comment for ``SpreadArray``.
|
||||
] ## Doc comment for `SpreadArray`.
|
||||
|
||||
Placement of comments in other areas is usually allowed, but will not become part of the documentation output and should therefore be prefaced by a single hash (``#``).
|
||||
Placement of comments in other areas is usually allowed, but will not become part of the documentation output and should therefore be prefaced by a single hash (`#`).
|
||||
|
||||
.. code-block:: Nim
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
===================================
|
||||
DrNim User Guide
|
||||
===================================
|
||||
@@ -18,7 +20,7 @@ DrNim's command-line options are the same as the Nim compiler's.
|
||||
|
||||
|
||||
DrNim currently only checks the sections of your code that are marked
|
||||
via ``staticBoundChecks: on``:
|
||||
via `staticBoundChecks: on`:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
@@ -31,9 +33,9 @@ overflow errors are *not* prevented. Overflows will be checked for in
|
||||
the future.
|
||||
|
||||
Later versions of the **Nim compiler** will **assume** that the checks inside
|
||||
the ``staticBoundChecks: on`` environment have been proven correct and so
|
||||
the `staticBoundChecks: on` environment have been proven correct and so
|
||||
it will **omit** the runtime checks. If you do not want this behavior, use
|
||||
instead ``{.push staticBoundChecks: defined(nimDrNim).}``. This way the
|
||||
instead `{.push staticBoundChecks: defined(nimDrNim).}`. This way the
|
||||
Nim compiler remains unaware of the performed proofs but DrNim will prove
|
||||
your code.
|
||||
|
||||
@@ -41,7 +43,7 @@ your code.
|
||||
Installation
|
||||
============
|
||||
|
||||
Run ``koch drnim``, the executable will afterwards be in ``$nim/bin/drnim``.
|
||||
Run `koch drnim`, the executable will afterwards be in `$nim/bin/drnim`.
|
||||
|
||||
|
||||
Motivating Example
|
||||
@@ -67,7 +69,7 @@ detects it and produces the following error message::
|
||||
|
||||
cannot prove: i <= len(a) + -1; counter example: i -> 0 a.len -> 0 [IndexCheck]
|
||||
|
||||
In other words for ``i == 0`` and ``a.len == 0`` (for example!) there would be
|
||||
In other words for `i == 0` and `a.len == 0` (for example!) there would be
|
||||
an index out of bounds error.
|
||||
|
||||
|
||||
@@ -82,37 +84,37 @@ DrNim adds 4 additional annotations (pragmas) to Nim:
|
||||
- `assume`:idx:
|
||||
|
||||
These pragmas are ignored by the Nim compiler so that they don't have to
|
||||
be disabled via ``when defined(nimDrNim)``.
|
||||
be disabled via `when defined(nimDrNim)`.
|
||||
|
||||
|
||||
Invariant
|
||||
---------
|
||||
|
||||
An ``invariant`` is a proposition that must be true after every loop
|
||||
An `invariant` is a proposition that must be true after every loop
|
||||
iteration, it's tied to the loop body it's part of.
|
||||
|
||||
|
||||
Requires
|
||||
--------
|
||||
|
||||
A ``requires`` annotation describes what the function expects to be true
|
||||
before it's called so that it can perform its operation. A ``requires``
|
||||
A `requires` annotation describes what the function expects to be true
|
||||
before it's called so that it can perform its operation. A `requires`
|
||||
annotation is also called a `precondition`:idx:.
|
||||
|
||||
|
||||
Ensures
|
||||
-------
|
||||
|
||||
An ``ensures`` annotation describes what will be true after the function
|
||||
call. An ``ensures`` annotation is also called a `postcondition`:idx:.
|
||||
An `ensures` annotation describes what will be true after the function
|
||||
call. An `ensures` annotation is also called a `postcondition`:idx:.
|
||||
|
||||
|
||||
Assume
|
||||
------
|
||||
|
||||
An ``assume`` annotation describes what DrNim should **assume** to be true
|
||||
An `assume` annotation describes what DrNim should **assume** to be true
|
||||
in this section of the program. It is an unsafe escape mechanism comparable
|
||||
to Nim's ``cast`` statement. Use it only when you really know better
|
||||
to Nim's `cast` statement. Use it only when you really know better
|
||||
than DrNim. You should add a comment to a paper that proves the proposition
|
||||
you assume.
|
||||
|
||||
@@ -143,12 +145,12 @@ Example: insertionSort
|
||||
Unfortunately, the invariants required to prove that this code is correct take more
|
||||
code than the imperative instructions. However, this effort can be compensated
|
||||
by the fact that the result needs very little testing. Be aware though that
|
||||
DrNim only proves that after ``insertionSort`` this condition holds::
|
||||
DrNim only proves that after `insertionSort` this condition holds::
|
||||
|
||||
forall(i in 1..<a.len, a[i-1] <= a[i])
|
||||
|
||||
|
||||
This is required, but not sufficient to describe that a ``sort`` operation
|
||||
This is required, but not sufficient to describe that a `sort` operation
|
||||
was performed. For example, the same postcondition is true for this proc
|
||||
which doesn't sort at all:
|
||||
|
||||
@@ -166,8 +168,8 @@ which doesn't sort at all:
|
||||
Syntax of propositions
|
||||
======================
|
||||
|
||||
The basic syntax is ``ensures|requires|invariant: <prop>``.
|
||||
A ``prop`` is either a comparison or a compound::
|
||||
The basic syntax is `ensures|requires|invariant: <prop>`.
|
||||
A `prop` is either a comparison or a compound::
|
||||
|
||||
prop = nim_bool_expression
|
||||
| prop 'and' prop
|
||||
@@ -186,17 +188,17 @@ A ``prop`` is either a comparison or a compound::
|
||||
quantifier = <new identifier> 'in' nim_iteration_expression
|
||||
|
||||
|
||||
``nim_iteration_expression`` here is an ordinary expression of Nim code
|
||||
that describes an iteration space, for example ``1..4`` or ``1..<a.len``.
|
||||
`nim_iteration_expression` here is an ordinary expression of Nim code
|
||||
that describes an iteration space, for example `1..4` or `1..<a.len`.
|
||||
|
||||
``nim_bool_expression`` here is an ordinary expression of Nim code of
|
||||
type ``bool`` like ``a == 3`` or ``23 > a.len``.
|
||||
`nim_bool_expression` here is an ordinary expression of Nim code of
|
||||
type `bool` like `a == 3` or `23 > a.len`.
|
||||
|
||||
The supported subset of Nim code that can be used in these expressions
|
||||
is currently underspecified but ``let`` variables, function parameters
|
||||
and ``result`` (which represents the function's final result) are amenable
|
||||
is currently underspecified but `let` variables, function parameters
|
||||
and `result` (which represents the function's final result) are amenable
|
||||
for verification. The expressions must not have any side-effects and must
|
||||
terminate.
|
||||
|
||||
The operators ``forall``, ``exists``, ``->``, ``<->`` have to imported
|
||||
from ``std / logic``.
|
||||
The operators `forall`, `exists`, `->`, `<->` have to imported
|
||||
from `std / logic`.
|
||||
|
||||
24
doc/estp.rst
24
doc/estp.rst
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
===================================================
|
||||
Embedded Stack Trace Profiler (ESTP) User Guide
|
||||
===================================================
|
||||
@@ -10,21 +12,21 @@ Nim comes with a platform independent profiler -
|
||||
the Embedded Stack Trace Profiler (ESTP). The profiler
|
||||
is *embedded* into your executable. To activate the profiler you need to do:
|
||||
|
||||
* compile your program with the ``--profiler:on --stackTrace:on`` command
|
||||
* compile your program with the `--profiler:on --stackTrace:on` command
|
||||
line options
|
||||
* import the ``nimprof`` module
|
||||
* import the `nimprof` module
|
||||
* run your program as usual.
|
||||
|
||||
You can in fact look at ``nimprof``'s source code to see how to implement
|
||||
You can in fact look at `nimprof`'s source code to see how to implement
|
||||
your own profiler.
|
||||
|
||||
The setting ``--profiler:on`` defines the conditional symbol ``profiler``.
|
||||
The setting `--profiler:on` defines the conditional symbol `profiler`.
|
||||
|
||||
After your program has finished the profiler will create a
|
||||
file ``profile_results.txt`` containing the profiling results.
|
||||
file `profile_results.txt` containing the profiling results.
|
||||
|
||||
Since the profiler works by examining stack traces, it's essential that
|
||||
the option ``--stackTrace:on`` is active! Unfortunately this means that a
|
||||
the option `--stackTrace:on` is active! Unfortunately this means that a
|
||||
profiling build is much slower than a release build.
|
||||
|
||||
|
||||
@@ -35,12 +37,12 @@ You can also use ESTP as a memory profiler to see which stack traces allocate
|
||||
the most memory and thus create the most GC pressure. It may also help to
|
||||
find memory leaks. To activate the memory profiler you need to do:
|
||||
|
||||
* compile your program with the ``--profiler:off --stackTrace:on -d:memProfiler``
|
||||
command line options. Yes it's ``--profiler:off``.
|
||||
* import the ``nimprof`` module
|
||||
* compile your program with the `--profiler:off --stackTrace:on -d:memProfiler`
|
||||
command line options. Yes it's `--profiler:off`.
|
||||
* import the `nimprof` module
|
||||
* run your program as usual.
|
||||
|
||||
Define the symbol ``ignoreAllocationSize`` so that only the number of
|
||||
Define the symbol `ignoreAllocationSize` so that only the number of
|
||||
allocations is counted and the sizes of the memory allocations do not matter.
|
||||
|
||||
|
||||
@@ -51,7 +53,7 @@ The results file lists stack traces ordered by significance.
|
||||
|
||||
The following example file has been generated by profiling the Nim compiler
|
||||
itself: It shows that in total 5.4% of the runtime has been spent
|
||||
in ``crcFromRope`` or its children.
|
||||
in `crcFromRope` or its children.
|
||||
|
||||
In general the stack traces show you immediately where the problem is because
|
||||
the trace acts like an explanation; in traditional profilers you can only find
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
===================
|
||||
Source Code Filters
|
||||
===================
|
||||
@@ -8,7 +10,7 @@ A `Source Code Filter (SCF)` transforms the input character stream to an in-mem
|
||||
output stream before parsing. A filter can be used to provide templating
|
||||
systems or preprocessors.
|
||||
|
||||
To use a filter for a source file the ``#?`` notation is used::
|
||||
To use a filter for a source file the `#?` notation is used::
|
||||
|
||||
#? stdtmpl(subsChar = '$', metaChar = '#')
|
||||
#proc generateXML(name, age: string): string =
|
||||
@@ -21,9 +23,9 @@ To use a filter for a source file the ``#?`` notation is used::
|
||||
As the example shows, passing arguments to a filter can be done
|
||||
just like an ordinary procedure call with named or positional arguments. The
|
||||
available parameters depend on the invoked filter. Before version 0.12.0 of
|
||||
the language ``#!`` was used instead of ``#?``.
|
||||
the language `#!` was used instead of `#?`.
|
||||
|
||||
**Hint:** With ``--hint[codeBegin]:on`` or ``--verbosity:2``
|
||||
**Hint:** With `--hint[codeBegin]:on` or `--verbosity:2`
|
||||
(or higher) while compiling or `nim check`, Nim lists the processed code after
|
||||
each filter application.
|
||||
|
||||
@@ -32,8 +34,8 @@ Usage
|
||||
|
||||
First, put your SCF code in a separate file with filters specified in the first line.
|
||||
**Note:** You can name your SCF file with any file extension you want, but the
|
||||
conventional extension is ``.nimf``
|
||||
(it used to be ``.tmpl`` but that was too generic, for example preventing github to
|
||||
conventional extension is `.nimf`
|
||||
(it used to be `.tmpl` but that was too generic, for example preventing github to
|
||||
recognize it as Nim source file).
|
||||
|
||||
If we use `generateXML` code shown above and call the SCF file `xmlGen.nimf`
|
||||
@@ -47,7 +49,7 @@ In your `main.nim`:
|
||||
Pipe operator
|
||||
=============
|
||||
|
||||
Filters can be combined with the ``|`` pipe operator::
|
||||
Filters can be combined with the `|` pipe operator::
|
||||
|
||||
#? strip(startswith="<") | stdtmpl
|
||||
#proc generateXML(name, age: string): string =
|
||||
@@ -68,10 +70,10 @@ The replace filter replaces substrings in each line.
|
||||
|
||||
Parameters and their defaults:
|
||||
|
||||
``sub: string = ""``
|
||||
`sub: string = ""`
|
||||
the substring that is searched for
|
||||
|
||||
``by: string = ""``
|
||||
`by: string = ""`
|
||||
the string the substring is replaced with
|
||||
|
||||
|
||||
@@ -83,14 +85,14 @@ each line.
|
||||
|
||||
Parameters and their defaults:
|
||||
|
||||
``startswith: string = ""``
|
||||
`startswith: string = ""`
|
||||
strip only the lines that start with *startswith* (ignoring leading
|
||||
whitespace). If empty every line is stripped.
|
||||
|
||||
``leading: bool = true``
|
||||
`leading: bool = true`
|
||||
strip leading whitespace
|
||||
|
||||
``trailing: bool = true``
|
||||
`trailing: bool = true`
|
||||
strip trailing whitespace
|
||||
|
||||
|
||||
@@ -99,25 +101,25 @@ StdTmpl filter
|
||||
|
||||
The stdtmpl filter provides a simple templating engine for Nim. The
|
||||
filter uses a line based parser: Lines prefixed with a *meta character*
|
||||
(default: ``#``) contain Nim code, other lines are verbatim. Because
|
||||
(default: `#`) contain Nim code, other lines are verbatim. Because
|
||||
indentation-based parsing is not suited for a templating engine, control flow
|
||||
statements need ``end X`` delimiters.
|
||||
statements need `end X` delimiters.
|
||||
|
||||
Parameters and their defaults:
|
||||
|
||||
``metaChar: char = '#'``
|
||||
`metaChar: char = '#'`
|
||||
prefix for a line that contains Nim code
|
||||
|
||||
``subsChar: char = '$'``
|
||||
`subsChar: char = '$'`
|
||||
prefix for a Nim expression within a template line
|
||||
|
||||
``conc: string = " & "``
|
||||
`conc: string = " & "`
|
||||
the operation for concatenation
|
||||
|
||||
``emit: string = "result.add"``
|
||||
`emit: string = "result.add"`
|
||||
the operation to emit a string literal
|
||||
|
||||
``toString: string = "$"``
|
||||
`toString: string = "$"`
|
||||
the operation that is applied to each expression
|
||||
|
||||
Example::
|
||||
@@ -174,18 +176,18 @@ The filter transforms this into:
|
||||
|
||||
|
||||
Each line that does not start with the meta character (ignoring leading
|
||||
whitespace) is converted to a string literal that is added to ``result``.
|
||||
whitespace) is converted to a string literal that is added to `result`.
|
||||
|
||||
The substitution character introduces a Nim expression *e* within the
|
||||
string literal. *e* is converted to a string with the *toString* operation
|
||||
which defaults to ``$``. For strong type checking, set ``toString`` to the
|
||||
which defaults to `$`. For strong type checking, set `toString` to the
|
||||
empty string. *e* must match this PEG pattern::
|
||||
|
||||
e <- [a-zA-Z\128-\255][a-zA-Z0-9\128-\255_.]* / '{' x '}'
|
||||
x <- '{' x+ '}' / [^}]*
|
||||
|
||||
To produce a single substitution character it has to be doubled: ``$$``
|
||||
produces ``$``.
|
||||
To produce a single substitution character it has to be doubled: `$$`
|
||||
produces `$`.
|
||||
|
||||
The template engine is quite flexible. It is easy to produce a procedure that
|
||||
writes the template code directly to a file::
|
||||
|
||||
92
doc/gc.rst
92
doc/gc.rst
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
=======================
|
||||
Nim's Memory Management
|
||||
=======================
|
||||
@@ -27,37 +29,37 @@ and how the memory management strategies other than garbage collectors work.
|
||||
Multi-paradigm Memory Management Strategies
|
||||
===========================================
|
||||
|
||||
To choose the memory management strategy use the ``--gc:`` switch.
|
||||
To choose the memory management strategy use the `--gc:` switch.
|
||||
|
||||
- ``--gc:refc``. This is the default GC. It's a
|
||||
- `--gc:refc`. This is the default GC. It's a
|
||||
deferred reference counting based garbage collector
|
||||
with a simple Mark&Sweep backup GC in order to collect cycles. Heaps are thread-local.
|
||||
- ``--gc:markAndSweep``. Simple Mark-And-Sweep based garbage collector. Heaps are thread-local.
|
||||
- ``--gc:boehm``. Boehm based garbage collector, it offers a shared heap.
|
||||
- ``--gc:go``. Go's garbage collector, useful for interoperability with Go. Offers a shared heap.
|
||||
- ``--gc:arc``. Plain reference counting with
|
||||
- `--gc:markAndSweep`. Simple Mark-And-Sweep based garbage collector. Heaps are thread-local.
|
||||
- `--gc:boehm`. Boehm based garbage collector, it offers a shared heap.
|
||||
- `--gc:go`. Go's garbage collector, useful for interoperability with Go. Offers a shared heap.
|
||||
- `--gc:arc`. Plain reference counting with
|
||||
`move semantic optimizations <destructors.html#move-semantics>`_, offers a shared heap.
|
||||
It offers deterministic performance for `hard realtime`:idx: systems. Reference cycles
|
||||
cause memory leaks, beware.
|
||||
|
||||
- ``--gc:orc``. Same as ``--gc:arc`` but adds a cycle collector based on "trial deletion".
|
||||
- `--gc:orc`. Same as `--gc:arc` but adds a cycle collector based on "trial deletion".
|
||||
Unfortunately, that makes its performance profile hard to reason about so it is less
|
||||
useful for hard real-time systems.
|
||||
|
||||
- ``--gc:none``. No memory management strategy nor a garbage collector. Allocated memory is
|
||||
simply never freed. You should use ``--gc:arc`` instead.
|
||||
- `--gc:none`. No memory management strategy nor a garbage collector. Allocated memory is
|
||||
simply never freed. You should use `--gc:arc` instead.
|
||||
|
||||
|
||||
================== ======== ================= ============== ===================
|
||||
Memory Management Heap Reference Cycles Stop-The-World Command line switch
|
||||
================== ======== ================= ============== ===================
|
||||
RefC Local Cycle Collector No ``--gc:refc``
|
||||
Mark & Sweep Local Cycle Collector No ``--gc:markAndSweep``
|
||||
ARC Shared Leak No ``--gc:arc``
|
||||
ORC Shared Cycle Collector No ``--gc:orc``
|
||||
Boehm Shared Cycle Collector Yes ``--gc:boehm``
|
||||
Go Shared Cycle Collector Yes ``--gc:go``
|
||||
None Manual Manual Manual ``--gc:none``
|
||||
RefC Local Cycle Collector No `--gc:refc`
|
||||
Mark & Sweep Local Cycle Collector No `--gc:markAndSweep`
|
||||
ARC Shared Leak No `--gc:arc`
|
||||
ORC Shared Cycle Collector No `--gc:orc`
|
||||
Boehm Shared Cycle Collector Yes `--gc:boehm`
|
||||
Go Shared Cycle Collector Yes `--gc:go`
|
||||
None Manual Manual Manual `--gc:none`
|
||||
================== ======== ================= ============== ===================
|
||||
|
||||
JavaScript's garbage collector is used for the `JavaScript and NodeJS
|
||||
@@ -73,14 +75,14 @@ Cycle collector
|
||||
---------------
|
||||
|
||||
The cycle collector can be en-/disabled independently from the other parts of
|
||||
the garbage collector with ``GC_enableMarkAndSweep`` and ``GC_disableMarkAndSweep``.
|
||||
the garbage collector with `GC_enableMarkAndSweep` and `GC_disableMarkAndSweep`.
|
||||
|
||||
|
||||
Soft real-time support
|
||||
----------------------
|
||||
|
||||
To enable real-time support, the symbol `useRealtimeGC`:idx: needs to be
|
||||
defined via ``--define:useRealtimeGC`` (you can put this into your config
|
||||
defined via `--define:useRealtimeGC` (you can put this into your config
|
||||
file as well).
|
||||
With this switch the garbage collector supports the following operations:
|
||||
|
||||
@@ -88,29 +90,29 @@ With this switch the garbage collector supports the following operations:
|
||||
proc GC_setMaxPause*(maxPauseInUs: int)
|
||||
proc GC_step*(us: int, strongAdvice = false, stackSize = -1)
|
||||
|
||||
The unit of the parameters ``maxPauseInUs`` and ``us`` is microseconds.
|
||||
The unit of the parameters `maxPauseInUs` and `us` is microseconds.
|
||||
|
||||
These two procs are the two modus operandi of the real-time garbage collector:
|
||||
|
||||
(1) GC_SetMaxPause Mode
|
||||
|
||||
You can call ``GC_SetMaxPause`` at program startup and then each triggered
|
||||
garbage collector run tries to not take longer than ``maxPause`` time. However, it is
|
||||
You can call `GC_SetMaxPause` at program startup and then each triggered
|
||||
garbage collector run tries to not take longer than `maxPause` time. However, it is
|
||||
possible (and common) that the work is nevertheless not evenly distributed
|
||||
as each call to ``new`` can trigger the garbage collector and thus take ``maxPause``
|
||||
as each call to `new` can trigger the garbage collector and thus take `maxPause`
|
||||
time.
|
||||
|
||||
(2) GC_step Mode
|
||||
|
||||
This allows the garbage collector to perform some work for up to ``us`` time.
|
||||
This allows the garbage collector to perform some work for up to `us` time.
|
||||
This is useful to call in the main loop to ensure the garbage collector can do its work.
|
||||
To bind all garbage collector activity to a ``GC_step`` call,
|
||||
deactivate the garbage collector with ``GC_disable`` at program startup.
|
||||
If ``strongAdvice`` is set to ``true``,
|
||||
To bind all garbage collector activity to a `GC_step` call,
|
||||
deactivate the garbage collector with `GC_disable` at program startup.
|
||||
If `strongAdvice` is set to `true`,
|
||||
then the garbage collector will be forced to perform the collection cycle.
|
||||
Otherwise, the garbage collector may decide not to do anything,
|
||||
if there is not much garbage to collect.
|
||||
You may also specify the current stack size via ``stackSize`` parameter.
|
||||
You may also specify the current stack size via `stackSize` parameter.
|
||||
It can improve performance when you know that there are no unique Nim references
|
||||
below a certain point on the stack. Make sure the size you specify is greater
|
||||
than the potential worst-case size.
|
||||
@@ -130,16 +132,16 @@ Time measurement with garbage collectors
|
||||
----------------------------------------
|
||||
|
||||
The garbage collectors' way of measuring time uses
|
||||
(see ``lib/system/timers.nim`` for the implementation):
|
||||
(see `lib/system/timers.nim` for the implementation):
|
||||
|
||||
1) ``QueryPerformanceCounter`` and ``QueryPerformanceFrequency`` on Windows.
|
||||
2) ``mach_absolute_time`` on Mac OS X.
|
||||
3) ``gettimeofday`` on Posix systems.
|
||||
1) `QueryPerformanceCounter` and `QueryPerformanceFrequency` on Windows.
|
||||
2) `mach_absolute_time` on Mac OS X.
|
||||
3) `gettimeofday` on Posix systems.
|
||||
|
||||
As such it supports a resolution of nanoseconds internally; however, the API
|
||||
uses microseconds for convenience.
|
||||
|
||||
Define the symbol ``reportMissedDeadlines`` to make the
|
||||
Define the symbol `reportMissedDeadlines` to make the
|
||||
garbage collector output whenever it missed a deadline.
|
||||
The reporting will be enhanced and supported by the API in later versions of the collector.
|
||||
|
||||
@@ -148,9 +150,9 @@ Tweaking the garbage collector
|
||||
------------------------------
|
||||
|
||||
The collector checks whether there is still time left for its work after
|
||||
every ``workPackage``'th iteration. This is currently set to 100 which means
|
||||
every `workPackage`'th iteration. This is currently set to 100 which means
|
||||
that up to 100 objects are traversed and freed before it checks again. Thus
|
||||
``workPackage`` affects the timing granularity and may need to be tweaked in
|
||||
`workPackage` affects the timing granularity and may need to be tweaked in
|
||||
highly specialized environments or for older hardware.
|
||||
|
||||
|
||||
@@ -158,22 +160,22 @@ Keeping track of memory
|
||||
=======================
|
||||
|
||||
If you need to pass around memory allocated by Nim to C, you can use the
|
||||
procs ``GC_ref`` and ``GC_unref`` to mark objects as referenced to avoid them
|
||||
procs `GC_ref` and `GC_unref` to mark objects as referenced to avoid them
|
||||
being freed by the garbage collector.
|
||||
Other useful procs from `system <system.html>`_ you can use to keep track of memory are:
|
||||
|
||||
* ``getTotalMem()`` Returns the amount of total memory managed by the garbage collector.
|
||||
* ``getOccupiedMem()`` Bytes reserved by the garbage collector and used by objects.
|
||||
* ``getFreeMem()`` Bytes reserved by the garbage collector and not in use.
|
||||
* ``GC_getStatistics()`` Garbage collector statistics as a human-readable string.
|
||||
* `getTotalMem()` Returns the amount of total memory managed by the garbage collector.
|
||||
* `getOccupiedMem()` Bytes reserved by the garbage collector and used by objects.
|
||||
* `getFreeMem()` Bytes reserved by the garbage collector and not in use.
|
||||
* `GC_getStatistics()` Garbage collector statistics as a human-readable string.
|
||||
|
||||
These numbers are usually only for the running thread, not for the whole heap,
|
||||
with the exception of ``--gc:boehm`` and ``--gc:go``.
|
||||
with the exception of `--gc:boehm` and `--gc:go`.
|
||||
|
||||
In addition to ``GC_ref`` and ``GC_unref`` you can avoid the garbage collector by manually
|
||||
allocating memory with procs like ``alloc``, ``alloc0``, ``allocShared``, ``allocShared0`` or ``allocCStringArray``.
|
||||
In addition to `GC_ref` and `GC_unref` you can avoid the garbage collector by manually
|
||||
allocating memory with procs like `alloc`, `alloc0`, `allocShared`, `allocShared0` or `allocCStringArray`.
|
||||
The garbage collector won't try to free them, you need to call their respective *dealloc* pairs
|
||||
(``dealloc``, ``deallocShared``, ``deallocCStringArray``, etc)
|
||||
(`dealloc`, `deallocShared`, `deallocCStringArray`, etc)
|
||||
when you are done with them or they will leak.
|
||||
|
||||
|
||||
@@ -182,12 +184,12 @@ Heap dump
|
||||
|
||||
The heap dump feature is still in its infancy, but it already proved
|
||||
useful for us, so it might be useful for you. To get a heap dump, compile
|
||||
with ``-d:nimTypeNames`` and call ``dumpNumberOfInstances`` at a strategic place in your program.
|
||||
with `-d:nimTypeNames` and call `dumpNumberOfInstances` at a strategic place in your program.
|
||||
This produces a list of the used types in your program and for every type
|
||||
the total amount of object instances for this type as well as the total
|
||||
amount of bytes these instances take up.
|
||||
|
||||
The numbers count the number of objects in all garbage collector heaps, they refer to
|
||||
all running threads, not only to the current thread. (The current thread
|
||||
would be the thread that calls ``dumpNumberOfInstances``.) This might
|
||||
would be the thread that calls `dumpNumberOfInstances`.) This might
|
||||
change in later versions.
|
||||
|
||||
28
doc/hcr.rst
28
doc/hcr.rst
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
===================================
|
||||
Hot code reloading
|
||||
===================================
|
||||
@@ -19,8 +21,8 @@ so we have to use a helper module where the major logic we want to change
|
||||
during development resides.
|
||||
|
||||
In this example, we use SDL2 to create a window and we reload the logic
|
||||
code when ``F9`` is pressed. The important lines are marked with ``#***``.
|
||||
To install SDL2 you can use ``nimble install sdl2``.
|
||||
code when `F9` is pressed. The important lines are marked with `#***`.
|
||||
To install SDL2 you can use `nimble install sdl2`.
|
||||
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -125,7 +127,7 @@ Then recompile the project, but do not restart or quit the mymain.exe program!
|
||||
|
||||
nim c --hotcodereloading:on mymain.nim
|
||||
|
||||
Now give the ``mymain`` SDL window the focus, press F9, and watch the
|
||||
Now give the `mymain` SDL window the focus, press F9, and watch the
|
||||
updated version of the program.
|
||||
|
||||
|
||||
@@ -133,8 +135,8 @@ updated version of the program.
|
||||
Reloading API
|
||||
=============
|
||||
|
||||
One can use the special event handlers ``beforeCodeReload`` and
|
||||
``afterCodeReload`` to reset the state of a particular variable or to force
|
||||
One can use the special event handlers `beforeCodeReload` and
|
||||
`afterCodeReload` to reset the state of a particular variable or to force
|
||||
the execution of certain statements:
|
||||
|
||||
.. code-block:: Nim
|
||||
@@ -178,8 +180,8 @@ It's expected that most projects will implement the reloading with a suitable
|
||||
build-system triggered IPC notification mechanism, but a polling solution is
|
||||
also possible through the provided `hasAnyModuleChanged()`:idx: API.
|
||||
|
||||
In order to access ``beforeCodeReload``, ``afterCodeReload``, ``hasModuleChanged``
|
||||
or ``hasAnyModuleChanged`` one must import the `hotcodereloading`:idx: module.
|
||||
In order to access `beforeCodeReload`, `afterCodeReload`, `hasModuleChanged`
|
||||
or `hasAnyModuleChanged` one must import the `hotcodereloading`:idx: module.
|
||||
|
||||
|
||||
Native code targets
|
||||
@@ -187,11 +189,11 @@ Native code targets
|
||||
|
||||
Native projects using the hot code reloading option will be implicitly
|
||||
compiled with the `-d:useNimRtl` option and they will depend on both
|
||||
the ``nimrtl`` library and the ``nimhcr`` library which implements the
|
||||
hot code reloading run-time. Both libraries can be found in the ``lib``
|
||||
the `nimrtl` library and the `nimhcr` library which implements the
|
||||
hot code reloading run-time. Both libraries can be found in the `lib`
|
||||
folder of Nim and can be compiled into dynamic libraries to satisfy
|
||||
runtime demands of the example code above. An example of compiling
|
||||
``nimhcr.nim`` and ``nimrtl.nim`` when the source dir of Nim is installed
|
||||
`nimhcr.nim` and `nimrtl.nim` when the source dir of Nim is installed
|
||||
with choosenim follows.
|
||||
|
||||
::
|
||||
@@ -208,16 +210,16 @@ with choosenim follows.
|
||||
# source directory (.dll for Windows, .so for Unix, .dylib for MacOS)
|
||||
|
||||
All modules of the project will be compiled to separate dynamic link
|
||||
libraries placed in the ``nimcache`` directory. Please note that during
|
||||
libraries placed in the `nimcache` directory. Please note that during
|
||||
the execution of the program, the hot code reloading run-time will load
|
||||
only copies of these libraries in order to not interfere with any newly
|
||||
issued build commands.
|
||||
|
||||
The main module of the program is considered non-reloadable. Please note
|
||||
that procs from reloadable modules should not appear in the call stack of
|
||||
program while ``performCodeReload`` is being called. Thus, the main module
|
||||
program while `performCodeReload` is being called. Thus, the main module
|
||||
is a suitable place for implementing a program loop capable of calling
|
||||
``performCodeReload``.
|
||||
`performCodeReload`.
|
||||
|
||||
Please note that reloading won't be possible when any of the type definitions
|
||||
in the program has been changed. When closure iterators are used (directly or
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
================================
|
||||
Nim IDE Integration Guide
|
||||
================================
|
||||
@@ -18,8 +20,8 @@ Note: this is mostly outdated, see instead `nimsuggest <nimsuggest.html>`_
|
||||
Nim differs from many other compilers in that it is really fast,
|
||||
and being so fast makes it suited to provide external queries for
|
||||
text editors about the source code being written. Through the
|
||||
``idetools`` command of `the compiler <nimc.html>`_, any IDE
|
||||
can query a ``.nim`` source file and obtain useful information like
|
||||
`idetools` command of `the compiler <nimc.html>`_, any IDE
|
||||
can query a `.nim` source file and obtain useful information like
|
||||
definition of symbols or suggestions for completion.
|
||||
|
||||
This document will guide you through the available options. If you
|
||||
@@ -36,7 +38,7 @@ Specifying the location of the query
|
||||
------------------------------------
|
||||
|
||||
All of the available idetools commands require you to specify a
|
||||
query location through the ``--track`` or ``--trackDirty`` switches.
|
||||
query location through the `--track` or `--trackDirty` switches.
|
||||
The general idetools invocations are::
|
||||
|
||||
nim idetools --track:FILE,LINE,COL <switches> proj.nim
|
||||
@@ -45,35 +47,35 @@ Or::
|
||||
|
||||
nim idetools --trackDirty:DIRTY_FILE,FILE,LINE,COL <switches> proj.nim
|
||||
|
||||
``proj.nim``
|
||||
`proj.nim`
|
||||
This is the main *project* filename. Most of the time you will
|
||||
pass in the same as **FILE**, but for bigger projects this is
|
||||
the file which is used as main entry point for the program, the
|
||||
one which users compile to generate a final binary.
|
||||
|
||||
``<switches>``
|
||||
`<switches>`
|
||||
This would be any of the other idetools available options, like
|
||||
``--def`` or ``--suggest`` explained in the following sections.
|
||||
`--def` or `--suggest` explained in the following sections.
|
||||
|
||||
``COL``
|
||||
`COL`
|
||||
An integer with the column you are going to query. For the
|
||||
compiler columns start at zero, so the first column will be
|
||||
**0** and the last in an 80 column terminal will be **79**.
|
||||
|
||||
``LINE``
|
||||
`LINE`
|
||||
An integer with the line you are going to query. For the compiler
|
||||
lines start at **1**.
|
||||
|
||||
``FILE``
|
||||
`FILE`
|
||||
The file you want to perform the query on. Usually you will
|
||||
pass in the same value as **proj.nim**.
|
||||
|
||||
``DIRTY_FILE``
|
||||
`DIRTY_FILE`
|
||||
The **FILE** parameter is enough for static analysis, but IDEs
|
||||
tend to have *unsaved buffers* where the user may still be in
|
||||
the middle of typing a line. In such situations the IDE can
|
||||
save the current contents to a temporary file and then use the
|
||||
``--trackDirty`` switch.
|
||||
`--trackDirty` switch.
|
||||
|
||||
Dirty files are likely to contain errors and they are usually
|
||||
compiled partially only to the point needed to service the
|
||||
@@ -91,7 +93,7 @@ Or::
|
||||
Definitions
|
||||
-----------
|
||||
|
||||
The ``--def`` idetools switch performs a query about the definition
|
||||
The `--def` idetools switch performs a query about the definition
|
||||
of a specific symbol. If available, idetools will answer with the
|
||||
type, source file, line/column information and other accessory data
|
||||
if available like a docstring. With this information an IDE can
|
||||
@@ -112,7 +114,7 @@ can't find any valid symbol matching the position of the query.
|
||||
Suggestions
|
||||
-----------
|
||||
|
||||
The ``--suggest`` idetools switch performs a query about possible
|
||||
The `--suggest` idetools switch performs a query about possible
|
||||
completion symbols at some point in the file. IDEs can easily provide
|
||||
an autocompletion feature where the IDE scans the current file (and
|
||||
related ones, if it knows about the language being edited and follows
|
||||
@@ -134,7 +136,7 @@ Idetools will try to return the suggestions sorted first by scope
|
||||
Invocation context
|
||||
------------------
|
||||
|
||||
The ``--context`` idetools switch is very similar to the suggestions
|
||||
The `--context` idetools switch is very similar to the suggestions
|
||||
switch, but instead of being used after the user has typed a dot
|
||||
character, this one is meant to be used after the user has typed
|
||||
an opening brace to start typing parameters.
|
||||
@@ -143,7 +145,7 @@ an opening brace to start typing parameters.
|
||||
Symbol usages
|
||||
-------------
|
||||
|
||||
The ``--usages`` idetools switch lists all usages of the symbol at
|
||||
The `--usages` idetools switch lists all usages of the symbol at
|
||||
a position. IDEs can use this to find all the places in the file
|
||||
where the symbol is used and offer the user to rename it in all
|
||||
places at the same time. Again, a pure string based search and
|
||||
@@ -207,15 +209,15 @@ Idetools outputs is always returned on single lines separated by
|
||||
tab characters (``\t``). The values of each column are:
|
||||
|
||||
1. Three characters indicating the type of returned answer (e.g.
|
||||
def for definition, ``sug`` for suggestion, etc).
|
||||
2. Type of the symbol. This can be ``skProc``, ``skLet``, and just
|
||||
about any of the enums defined in the module ``compiler/ast.nim``.
|
||||
def for definition, `sug` for suggestion, etc).
|
||||
2. Type of the symbol. This can be `skProc`, `skLet`, and just
|
||||
about any of the enums defined in the module `compiler/ast.nim`.
|
||||
3. Full qualified path of the symbol. If you are querying a symbol
|
||||
defined in the ``proj.nim`` file, this would have the form
|
||||
``proj.symbolName``.
|
||||
defined in the `proj.nim` file, this would have the form
|
||||
`proj.symbolName`.
|
||||
4. Type/signature. For variables and enums this will contain the
|
||||
type of the symbol, for procs, methods and templates this will
|
||||
contain the full unique signature (e.g. ``proc (File)``).
|
||||
contain the full unique signature (e.g. `proc (File)`).
|
||||
5. Full path to the file containing the symbol.
|
||||
6. Line where the symbol is located in the file. Lines start to
|
||||
count at **1**.
|
||||
@@ -374,8 +376,8 @@ While at the language level a method is differentiated from others
|
||||
by the parameters and return value, the signature of the method
|
||||
returned by idetools returns also the pragmas for the method.
|
||||
|
||||
Note that at the moment the word ``proc`` is returned for the
|
||||
signature of the found method instead of the expected ``method``.
|
||||
Note that at the moment the word `proc` is returned for the
|
||||
signature of the found method instead of the expected `method`.
|
||||
This may change in the future.
|
||||
|
||||
| **Third column**: module + [n scope nesting] + method name.
|
||||
@@ -517,7 +519,7 @@ Test suite
|
||||
==========
|
||||
|
||||
To verify that idetools is working properly there are files in the
|
||||
``tests/caas/`` directory which provide unit testing. If you find
|
||||
`tests/caas/` directory which provide unit testing. If you find
|
||||
odd idetools behaviour and are able to reproduce it, you are welcome
|
||||
to report it as a bug and add a test to the suite to avoid future
|
||||
regressions.
|
||||
@@ -533,27 +535,27 @@ run it manually. First you have to compile the tester::
|
||||
$ cd my/nim/checkout/tests
|
||||
$ nim c testament/caasdriver.nim
|
||||
|
||||
Running the ``caasdriver`` without parameters will attempt to process
|
||||
Running the `caasdriver` without parameters will attempt to process
|
||||
all the test cases in all three operation modes. If a test succeeds
|
||||
nothing will be printed and the process will exit with zero. If any
|
||||
test fails, the specific line of the test preceding the failure
|
||||
and the failure itself will be dumped to stdout, along with a final
|
||||
indicator of the success state and operation mode. You can pass the
|
||||
parameter ``verbose`` to force all output even on successful tests.
|
||||
parameter `verbose` to force all output even on successful tests.
|
||||
|
||||
The normal operation mode is called ``ProcRun`` and it involves
|
||||
The normal operation mode is called `ProcRun` and it involves
|
||||
starting a process for each command or query, similar to running
|
||||
manually the Nim compiler from the commandline. The ``CaasRun``
|
||||
mode starts a server process to answer all queries. The ``SymbolProcRun``
|
||||
manually the Nim compiler from the commandline. The `CaasRun`
|
||||
mode starts a server process to answer all queries. The `SymbolProcRun`
|
||||
mode is used by compiler developers. This means that running all
|
||||
tests involves processing all ``*.txt`` files three times, which
|
||||
tests involves processing all `*.txt` files three times, which
|
||||
can be quite time consuming.
|
||||
|
||||
If you don't want to run all the test case files you can pass any
|
||||
substring as a parameter to ``caasdriver``. Only files matching the
|
||||
substring as a parameter to `caasdriver`. Only files matching the
|
||||
passed substring will be run. The filtering doesn't use any globbing
|
||||
metacharacters, it's a plain match. For example, to run only
|
||||
``*-compile*.txt`` tests in verbose mode::
|
||||
`*-compile*.txt` tests in verbose mode::
|
||||
|
||||
./caasdriver verbose -compile
|
||||
|
||||
@@ -561,18 +563,18 @@ metacharacters, it's a plain match. For example, to run only
|
||||
Test case file format
|
||||
---------------------
|
||||
|
||||
All the ``tests/caas/*.txt`` files encode a session with the compiler:
|
||||
All the `tests/caas/*.txt` files encode a session with the compiler:
|
||||
|
||||
* The first line indicates the main project file.
|
||||
|
||||
* Lines starting with ``>`` indicate a command to be sent to the
|
||||
* Lines starting with `>` indicate a command to be sent to the
|
||||
compiler and the lines following a command include checks for
|
||||
expected or forbidden output (``!`` for forbidden).
|
||||
expected or forbidden output (`!` for forbidden).
|
||||
|
||||
* If a line starts with ``#`` it will be ignored completely, so you
|
||||
* If a line starts with `#` it will be ignored completely, so you
|
||||
can use that for comments.
|
||||
|
||||
* Since some cases are specific to either ``ProcRun`` or ``CaasRun``
|
||||
* Since some cases are specific to either `ProcRun` or `CaasRun`
|
||||
modes, you can prefix a line with the mode and the line will be
|
||||
processed only in that mode.
|
||||
|
||||
|
||||
138
doc/intern.rst
138
doc/intern.rst
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
=========================================
|
||||
Internals of the Nim Compiler
|
||||
=========================================
|
||||
@@ -19,19 +21,19 @@ The Nim project's directory structure is:
|
||||
============ ===================================================
|
||||
Path Purpose
|
||||
============ ===================================================
|
||||
``bin`` generated binary files
|
||||
``build`` generated C code for the installation
|
||||
``compiler`` the Nim compiler itself; note that this
|
||||
`bin` generated binary files
|
||||
`build` generated C code for the installation
|
||||
`compiler` the Nim compiler itself; note that this
|
||||
code has been translated from a bootstrapping
|
||||
version written in Pascal, so the code is **not**
|
||||
a poster child of good Nim code
|
||||
``config`` configuration files for Nim
|
||||
``dist`` additional packages for the distribution
|
||||
``doc`` the documentation; it is a bunch of
|
||||
`config` configuration files for Nim
|
||||
`dist` additional packages for the distribution
|
||||
`doc` the documentation; it is a bunch of
|
||||
reStructuredText files
|
||||
``lib`` the Nim library
|
||||
``web`` website of Nim; generated by ``nimweb``
|
||||
from the ``*.txt`` and ``*.nimf`` files
|
||||
`lib` the Nim library
|
||||
`web` website of Nim; generated by `nimweb`
|
||||
from the `*.txt` and `*.nimf` files
|
||||
============ ===================================================
|
||||
|
||||
|
||||
@@ -53,7 +55,7 @@ And for a debug version compatible with GDB::
|
||||
nim c koch.nim
|
||||
./koch boot --debuginfo --linedir:on
|
||||
|
||||
The ``koch`` program is Nim's maintenance script. It is a replacement for
|
||||
The `koch` program is Nim's maintenance script. It is a replacement for
|
||||
make and shell scripting with the advantage that it is much more portable.
|
||||
More information about its options can be found in the `koch <koch.html>`_
|
||||
documentation.
|
||||
@@ -67,8 +69,8 @@ Coding Guidelines
|
||||
* Max line length is 80 characters.
|
||||
* Provide spaces around binary operators if that enhances readability.
|
||||
* Use a space after a colon, but not before it.
|
||||
* [deprecated] Start types with a capital ``T``, unless they are
|
||||
pointers/references which start with ``P``.
|
||||
* [deprecated] Start types with a capital `T`, unless they are
|
||||
pointers/references which start with `P`.
|
||||
|
||||
See also the `API naming design <apis.html>`_ document.
|
||||
|
||||
@@ -81,12 +83,12 @@ portable programming language (within certain limits) and Nim generates
|
||||
C code, porting the code generator is not necessary.
|
||||
|
||||
POSIX-compliant systems on conventional hardware are usually pretty easy to
|
||||
port: Add the platform to ``platform`` (if it is not already listed there),
|
||||
port: Add the platform to `platform` (if it is not already listed there),
|
||||
check that the OS, System modules work and recompile Nim.
|
||||
|
||||
The only case where things aren't as easy is when the garbage
|
||||
collector needs some assembler tweaking to work. The standard
|
||||
version of the GC uses C's ``setjmp`` function to store all registers
|
||||
version of the GC uses C's `setjmp` function to store all registers
|
||||
on the hardware stack. It may be necessary that the new platform needs to
|
||||
replace this generic code by some assembler code.
|
||||
|
||||
@@ -111,7 +113,7 @@ Complex assignments
|
||||
|
||||
We already know the type information as a graph in the compiler.
|
||||
Thus we need to serialize this graph as RTTI for C code generation.
|
||||
Look at the file ``lib/system/hti.nim`` for more information.
|
||||
Look at the file `lib/system/hti.nim` for more information.
|
||||
|
||||
Rebuilding the compiler
|
||||
========================
|
||||
@@ -139,7 +141,7 @@ Debugging the compiler
|
||||
======================
|
||||
|
||||
You can of course use GDB or Visual Studio to debug the
|
||||
compiler (via ``--debuginfo --lineDir:on``). However, there
|
||||
compiler (via `--debuginfo --lineDir:on`). However, there
|
||||
are also lots of procs that aid in debugging:
|
||||
|
||||
|
||||
@@ -170,19 +172,19 @@ These procs may not be imported by a module. You can import them directly for de
|
||||
from renderer import renderTree
|
||||
from msgs import `??`
|
||||
|
||||
To create a new compiler for each run, use ``koch temp``::
|
||||
To create a new compiler for each run, use `koch temp`::
|
||||
|
||||
./koch temp c /tmp/test.nim
|
||||
|
||||
``koch temp`` creates a debug build of the compiler, which is useful
|
||||
`koch temp` creates a debug build of the compiler, which is useful
|
||||
to create stacktraces for compiler debugging. See also
|
||||
`Rebuilding the compiler`_ if you need more control.
|
||||
|
||||
Bisecting for regressions
|
||||
=========================
|
||||
|
||||
``koch temp`` returns 125 as the exit code in case the compiler
|
||||
compilation fails. This exit code tells ``git bisect`` to skip the
|
||||
`koch temp` returns 125 as the exit code in case the compiler
|
||||
compilation fails. This exit code tells `git bisect` to skip the
|
||||
current commit.::
|
||||
|
||||
git bisect start bad-commit good-commit
|
||||
@@ -219,15 +221,15 @@ examples how the AST represents each syntactic structure.
|
||||
How the RTL is compiled
|
||||
=======================
|
||||
|
||||
The ``system`` module contains the part of the RTL which needs support by
|
||||
The `system` module contains the part of the RTL which needs support by
|
||||
compiler magic (and the stuff that needs to be in it because the spec
|
||||
says so). The C code generator generates the C code for it, just like any other
|
||||
module. However, calls to some procedures like ``addInt`` are inserted by
|
||||
the CCG. Therefore the module ``magicsys`` contains a table (``compilerprocs``)
|
||||
with all symbols that are marked as ``compilerproc``. ``compilerprocs`` are
|
||||
needed by the code generator. A ``magic`` proc is not the same as a
|
||||
``compilerproc``: A ``magic`` is a proc that needs compiler magic for its
|
||||
semantic checking, a ``compilerproc`` is a proc that is used by the code
|
||||
module. However, calls to some procedures like `addInt` are inserted by
|
||||
the CCG. Therefore the module `magicsys` contains a table (`compilerprocs`)
|
||||
with all symbols that are marked as `compilerproc`. `compilerprocs` are
|
||||
needed by the code generator. A `magic` proc is not the same as a
|
||||
`compilerproc`: A `magic` is a proc that needs compiler magic for its
|
||||
semantic checking, a `compilerproc` is a proc that is used by the code
|
||||
generator.
|
||||
|
||||
|
||||
@@ -254,7 +256,7 @@ This solves the problem without having to special case the logic
|
||||
that fills the internal seqs which are affected by the pragmas.
|
||||
|
||||
In fact, this describes how the AST should be stored in the database,
|
||||
as a "shallow" tree. Let's assume we compile module ``m`` with the
|
||||
as a "shallow" tree. Let's assume we compile module `m` with the
|
||||
following contents:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -279,21 +281,21 @@ Conceptually this is the AST we store for the module:
|
||||
static:
|
||||
echo "static"
|
||||
|
||||
The symbol's ``ast`` field is loaded lazily, on demand. This is where most
|
||||
The symbol's `ast` field is loaded lazily, on demand. This is where most
|
||||
savings come from, only the shallow outer AST is reconstructed immediately.
|
||||
|
||||
It is also important that the replay involves the ``import`` statement so
|
||||
It is also important that the replay involves the `import` statement so
|
||||
that dependencies are resolved properly.
|
||||
|
||||
|
||||
Shared global compiletime state
|
||||
-------------------------------
|
||||
|
||||
Nim allows ``.global, compiletime`` variables that can be filled by macro
|
||||
Nim allows `.global, compiletime` variables that can be filled by macro
|
||||
invocations across different modules. This feature breaks modularity in a
|
||||
severe way. Plenty of different solutions have been proposed:
|
||||
|
||||
- Restrict the types of global compiletime variables to ``Set[T]`` or
|
||||
- Restrict the types of global compiletime variables to `Set[T]` or
|
||||
similar unordered, only-growable collections so that we can track
|
||||
the module's write effects to these variables and reapply the changes
|
||||
in a different order.
|
||||
@@ -306,7 +308,7 @@ severe way. Plenty of different solutions have been proposed:
|
||||
Since we adopt the "replay the top level statements" idea, the natural
|
||||
solution to this problem is to emit pseudo top level statements that
|
||||
reflect the mutations done to the global variable. However, this is
|
||||
MUCH harder than it sounds, for example ``squeaknim`` uses this
|
||||
MUCH harder than it sounds, for example `squeaknim` uses this
|
||||
snippet:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -314,12 +316,12 @@ snippet:
|
||||
"\t^self externalCallFailed\C!\C\C")
|
||||
stCode.add(st & "\C\t\"Generated by NimSqueak\"\C\t" & apicall)
|
||||
|
||||
We can "replay" ``stCode.add`` only if the values of ``st``
|
||||
and ``apicall`` are known. And even then a hash table's ``add`` with its
|
||||
We can "replay" `stCode.add` only if the values of `st`
|
||||
and `apicall` are known. And even then a hash table's `add` with its
|
||||
hashing mechanism is too hard to replay.
|
||||
|
||||
In practice, things are worse still, consider ``someGlobal[i][j].add arg``.
|
||||
We only know the root is ``someGlobal`` but the concrete path to the data
|
||||
In practice, things are worse still, consider `someGlobal[i][j].add arg`.
|
||||
We only know the root is `someGlobal` but the concrete path to the data
|
||||
is unknown as is the value that is added. We could compute a "diff" between
|
||||
the global states and use that to compute a symbol patchset, but this is
|
||||
quite some work, expensive to do at runtime (it would need to run after
|
||||
@@ -342,7 +344,7 @@ an alien API and works with some existing Nimble packages, at least.
|
||||
|
||||
On the other hand, in Nim's future I would like to replace the VM
|
||||
by native code. A diff algorithm wouldn't work for that.
|
||||
Instead the native code would work with an API like ``put``, ``get``:
|
||||
Instead the native code would work with an API like `put`, `get`:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
@@ -350,7 +352,7 @@ Instead the native code would work with an API like ``put``, ``get``:
|
||||
proc cacheGet*(key: string): NimNode
|
||||
|
||||
The API should embrace the AST diffing notion: See the
|
||||
module ``macrocache`` for the final details.
|
||||
module `macrocache` for the final details.
|
||||
|
||||
|
||||
|
||||
@@ -382,9 +384,9 @@ too. Type converters fall into this category:
|
||||
if 1:
|
||||
echo "ugly, but should work"
|
||||
|
||||
If in the above example module ``B`` is re-compiled, but ``A`` is not then
|
||||
``B`` needs to be aware of ``toBool`` even though ``toBool`` is not referenced
|
||||
in ``B`` *explicitly*.
|
||||
If in the above example module `B` is re-compiled, but `A` is not then
|
||||
`B` needs to be aware of `toBool` even though `toBool` is not referenced
|
||||
in `B` *explicitly*.
|
||||
|
||||
Both the multi method and the type converter problems are solved by the
|
||||
AST replay implementation.
|
||||
@@ -395,7 +397,7 @@ Generics
|
||||
|
||||
We cache generic instantiations and need to ensure this caching works
|
||||
well with the incremental compilation feature. Since the cache is
|
||||
attached to the ``PSym`` datastructure, it should work without any
|
||||
attached to the `PSym` datastructure, it should work without any
|
||||
special logic.
|
||||
|
||||
|
||||
@@ -405,22 +407,22 @@ Backend issues
|
||||
- Init procs must not be "forgotten" to be called.
|
||||
- Files must not be "forgotten" to be linked.
|
||||
- Method dispatchers are global.
|
||||
- DLL loading via ``dlsym`` is global.
|
||||
- DLL loading via `dlsym` is global.
|
||||
- Emulated thread vars are global.
|
||||
|
||||
However the biggest problem is that dead code elimination breaks modularity!
|
||||
To see why, consider this scenario: The module ``G`` (for example the huge
|
||||
To see why, consider this scenario: The module `G` (for example the huge
|
||||
Gtk2 module...) is compiled with dead code elimination turned on. So none
|
||||
of ``G``'s procs is generated at all.
|
||||
of `G`'s procs is generated at all.
|
||||
|
||||
Then module ``B`` is compiled that requires ``G.P1``. Ok, no problem,
|
||||
``G.P1`` is loaded from the symbol file and ``G.c`` now contains ``G.P1``.
|
||||
Then module `B` is compiled that requires `G.P1`. Ok, no problem,
|
||||
`G.P1` is loaded from the symbol file and `G.c` now contains `G.P1`.
|
||||
|
||||
Then module ``A`` (that depends on ``B`` and ``G``) is compiled and ``B``
|
||||
and ``G`` are left unchanged. ``A`` requires ``G.P2``.
|
||||
Then module `A` (that depends on `B` and `G`) is compiled and `B`
|
||||
and `G` are left unchanged. `A` requires `G.P2`.
|
||||
|
||||
So now ``G.c`` MUST contain both ``P1`` and ``P2``, but we haven't even
|
||||
loaded ``P1`` from the symbol file, nor do we want to because we then quickly
|
||||
So now `G.c` MUST contain both `P1` and `P2`, but we haven't even
|
||||
loaded `P1` from the symbol file, nor do we want to because we then quickly
|
||||
would restore large parts of the whole program.
|
||||
|
||||
|
||||
@@ -428,7 +430,7 @@ Solution
|
||||
~~~~~~~~
|
||||
|
||||
The backend must have some logic so that if the currently processed module
|
||||
is from the compilation cache, the ``ast`` field is not accessed. Instead
|
||||
is from the compilation cache, the `ast` field is not accessed. Instead
|
||||
the generated C(++) for the symbol's body needs to be cached too and
|
||||
inserted back into the produced C file. This approach seems to deal with
|
||||
all the outlined problems above.
|
||||
@@ -444,8 +446,8 @@ in mind:
|
||||
keeps allocating memory! Thus a stack overflow may happen, hiding the
|
||||
real issue.
|
||||
* What seem to be C code generation problems is often a bug resulting from
|
||||
not producing prototypes, so that some types default to ``cint``. Testing
|
||||
without the ``-w`` option helps!
|
||||
not producing prototypes, so that some types default to `cint`. Testing
|
||||
without the `-w` option helps!
|
||||
|
||||
|
||||
The Garbage Collector
|
||||
@@ -464,9 +466,9 @@ code generation.
|
||||
|
||||
Each cell has a header consisting of a RC and a pointer to its type
|
||||
descriptor. However the program does not know about these, so they are placed at
|
||||
negative offsets. In the GC code the type ``PCell`` denotes a pointer
|
||||
negative offsets. In the GC code the type `PCell` denotes a pointer
|
||||
decremented by the right offset, so that the header can be accessed easily. It
|
||||
is extremely important that ``pointer`` is not confused with a ``PCell``
|
||||
is extremely important that `pointer` is not confused with a `PCell`
|
||||
as this would lead to a memory corruption.
|
||||
|
||||
|
||||
@@ -474,9 +476,9 @@ The CellSet data structure
|
||||
--------------------------
|
||||
|
||||
The GC depends on an extremely efficient datastructure for storing a
|
||||
set of pointers - this is called a ``TCellSet`` in the source code.
|
||||
set of pointers - this is called a `TCellSet` in the source code.
|
||||
Inserting, deleting and searching are done in constant time. However,
|
||||
modifying a ``TCellSet`` during traversal leads to undefined behaviour.
|
||||
modifying a `TCellSet` during traversal leads to undefined behaviour.
|
||||
|
||||
.. code-block:: Nim
|
||||
type
|
||||
@@ -559,11 +561,11 @@ Code generation for closures is implemented by `lambda lifting`:idx:.
|
||||
Design
|
||||
------
|
||||
|
||||
A ``closure`` proc var can call ordinary procs of the default Nim calling
|
||||
A `closure` proc var can call ordinary procs of the default Nim calling
|
||||
convention. But not the other way round! A closure is implemented as a
|
||||
``tuple[prc, env]``. ``env`` can be nil implying a call without a closure.
|
||||
This means that a call through a closure generates an ``if`` but the
|
||||
interoperability is worth the cost of the ``if``. Thunk generation would be
|
||||
`tuple[prc, env]`. `env` can be nil implying a call without a closure.
|
||||
This means that a call through a closure generates an `if` but the
|
||||
interoperability is worth the cost of the `if`. Thunk generation would be
|
||||
possible too, but it's slightly more effort to implement.
|
||||
|
||||
Tests with GCC on Amd64 showed that it's really beneficial if the
|
||||
@@ -579,7 +581,7 @@ A thunk would need to call 'returnsDefaultCC[i]' somehow and that would require
|
||||
an *additional* closure generation... Ok, not really, but it requires to pass
|
||||
the function to call. So we'd end up with 2 indirect calls instead of one.
|
||||
Another much more severe problem which this solution is that it's not GC-safe
|
||||
to pass a proc pointer around via a generic ``ref`` type.
|
||||
to pass a proc pointer around via a generic `ref` type.
|
||||
|
||||
|
||||
Example code:
|
||||
@@ -695,15 +697,15 @@ Accumulator
|
||||
Internals
|
||||
---------
|
||||
|
||||
Lambda lifting is implemented as part of the ``transf`` pass. The ``transf``
|
||||
Lambda lifting is implemented as part of the `transf` pass. The `transf`
|
||||
pass generates code to setup the environment and to pass it around. However,
|
||||
this pass does not change the types! So we have some kind of mismatch here; on
|
||||
the one hand the proc expression becomes an explicit tuple, on the other hand
|
||||
the tyProc(ccClosure) type is not changed. For C code generation it's also
|
||||
important the hidden formal param is ``void*`` and not something more
|
||||
important the hidden formal param is `void*` and not something more
|
||||
specialized. However the more specialized env type needs to passed to the
|
||||
backend somehow. We deal with this by modifying ``s.ast[paramPos]`` to contain
|
||||
the formal hidden parameter, but not ``s.typ``!
|
||||
backend somehow. We deal with this by modifying `s.ast[paramPos]` to contain
|
||||
the formal hidden parameter, but not `s.typ`!
|
||||
|
||||
|
||||
Integer literals:
|
||||
|
||||
24
doc/koch.rst
24
doc/koch.rst
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
===============================
|
||||
Nim maintenance script
|
||||
===============================
|
||||
@@ -17,7 +19,7 @@ Introduction
|
||||
|
||||
The `koch`:idx: program is Nim's maintenance script. It is a replacement
|
||||
for make and shell scripting with the advantage that it is much more portable.
|
||||
The word *koch* means *cook* in German. ``koch`` is used mainly to build the
|
||||
The word *koch* means *cook* in German. `koch` is used mainly to build the
|
||||
Nim compiler, but it can also be used for other tasks. This document
|
||||
describes the supported commands and their options.
|
||||
|
||||
@@ -39,8 +41,8 @@ options:
|
||||
Use the linenoise library for interactive mode (not needed on Windows).
|
||||
|
||||
After compilation is finished you will hopefully end up with the nim
|
||||
compiler in the ``bin`` directory. You can add Nim's ``bin`` directory to
|
||||
your ``$PATH`` or use the install command to place it where it will be
|
||||
compiler in the `bin` directory. You can add Nim's `bin` directory to
|
||||
your `$PATH` or use the install command to place it where it will be
|
||||
found.
|
||||
|
||||
csource command
|
||||
@@ -54,33 +56,33 @@ temp command
|
||||
------------
|
||||
|
||||
The temp command builds the Nim compiler but with a different final name
|
||||
(``nim_temp``), so it doesn't overwrite your normal compiler. You can use
|
||||
(`nim_temp`), so it doesn't overwrite your normal compiler. You can use
|
||||
this command to test different options, the same you would issue for the `boot
|
||||
command <#commands-boot-command>`_.
|
||||
|
||||
test command
|
||||
------------
|
||||
|
||||
The `test`:idx: command can also be invoked with the alias ``tests``. This
|
||||
command will compile and run ``testament/tester.nim``, which is the main
|
||||
driver of Nim's test suite. You can pass options to the ``test`` command,
|
||||
The `test`:idx: command can also be invoked with the alias `tests`. This
|
||||
command will compile and run `testament/tester.nim`, which is the main
|
||||
driver of Nim's test suite. You can pass options to the `test` command,
|
||||
they will be forwarded to the tester. See its source code for available
|
||||
options.
|
||||
|
||||
web command
|
||||
-----------
|
||||
|
||||
The `web`:idx: command converts the documentation in the ``doc`` directory
|
||||
The `web`:idx: command converts the documentation in the `doc` directory
|
||||
from rst to HTML. It also repeats the same operation but places the result in
|
||||
the ``web/upload`` which can be used to update the website at
|
||||
the `web/upload` which can be used to update the website at
|
||||
https://nim-lang.org.
|
||||
|
||||
By default, the documentation will be built in parallel using the number of
|
||||
available CPU cores. If any documentation build sub-commands fail, they will
|
||||
be rerun in serial fashion so that meaningful error output can be gathered for
|
||||
inspection. The ``--parallelBuild:n`` switch or configuration option can be
|
||||
inspection. The `--parallelBuild:n` switch or configuration option can be
|
||||
used to force a specific number of parallel jobs or run everything serially
|
||||
from the start (``n == 1``).
|
||||
from the start (`n == 1`).
|
||||
|
||||
pdf command
|
||||
-----------
|
||||
|
||||
68
doc/lib.rst
68
doc/lib.rst
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
====================
|
||||
Nim Standard Library
|
||||
====================
|
||||
@@ -9,7 +11,7 @@ Nim Standard Library
|
||||
|
||||
Nim's library is divided into *pure libraries*, *impure libraries*, and *wrappers*.
|
||||
|
||||
Pure libraries do not depend on any external ``*.dll`` or ``lib*.so`` binary
|
||||
Pure libraries do not depend on any external `*.dll` or `lib*.so` binary
|
||||
while impure libraries do. A wrapper is an impure library that is a very
|
||||
low-level interface to a C library.
|
||||
|
||||
@@ -37,11 +39,11 @@ Automatic imports
|
||||
|
||||
* `threads <threads.html>`_
|
||||
Basic Nim thread support. **Note:** This is part of the system module. Do not
|
||||
import it explicitly. Enabled with ``--threads:on``.
|
||||
import it explicitly. Enabled with `--threads:on`.
|
||||
|
||||
* `channels <channels_builtin.html>`_
|
||||
Nim message passing support for threads. **Note:** This is part of the
|
||||
system module. Do not import it explicitly. Enabled with ``--threads:on``.
|
||||
system module. Do not import it explicitly. Enabled with `--threads:on`.
|
||||
|
||||
|
||||
Core
|
||||
@@ -86,14 +88,14 @@ Algorithms
|
||||
This module implements some common generic algorithms like sort or binary search.
|
||||
|
||||
* `std/enumutils <enumutils.html>`_
|
||||
This module adds functionality for the built-in ``enum`` type.
|
||||
This module adds functionality for the built-in `enum` type.
|
||||
|
||||
* `sequtils <sequtils.html>`_
|
||||
This module implements operations for the built-in ``seq`` type
|
||||
This module implements operations for the built-in `seq` type
|
||||
which were inspired by functional programming languages.
|
||||
|
||||
* `std/setutils <setutils.html>`_
|
||||
This module adds functionality for the built-in ``set`` type.
|
||||
This module adds functionality for the built-in `set` type.
|
||||
|
||||
|
||||
Collections
|
||||
@@ -105,7 +107,7 @@ Collections
|
||||
|
||||
* `deques <deques.html>`_
|
||||
Implementation of a double-ended queue.
|
||||
The underlying implementation uses a ``seq``.
|
||||
The underlying implementation uses a `seq`.
|
||||
|
||||
* `heapqueue <heapqueue.html>`_
|
||||
Implementation of a heap data structure that can be used as a priority queue.
|
||||
@@ -140,7 +142,7 @@ String handling
|
||||
---------------
|
||||
|
||||
* `cstrutils <cstrutils.html>`_
|
||||
Utilities for ``cstring`` handling.
|
||||
Utilities for `cstring` handling.
|
||||
|
||||
* `std/editdistance <editdistance.html>`_
|
||||
This module contains an algorithm to compute the edit distance between two
|
||||
@@ -148,7 +150,7 @@ String handling
|
||||
|
||||
* `encodings <encodings.html>`_
|
||||
Converts between different character encodings. On UNIX, this uses
|
||||
the ``iconv`` library, on Windows the Windows API.
|
||||
the `iconv` library, on Windows the Windows API.
|
||||
|
||||
* `parseutils <parseutils.html>`_
|
||||
This module contains helpers for parsing tokens, numbers, identifiers, etc.
|
||||
@@ -166,17 +168,17 @@ String handling
|
||||
|
||||
* `strformat <strformat.html>`_
|
||||
Macro based standard string interpolation/formatting. Inspired by
|
||||
Python's ``f``-strings.
|
||||
Python's `f`-strings.
|
||||
|
||||
* `strmisc <strmisc.html>`_
|
||||
This module contains uncommon string handling operations that do not
|
||||
fit with the commonly used operations in strutils.
|
||||
|
||||
* `strscans <strscans.html>`_
|
||||
This module contains a ``scanf`` macro for convenient parsing of mini languages.
|
||||
This module contains a `scanf` macro for convenient parsing of mini languages.
|
||||
|
||||
* `strtabs <strtabs.html>`_
|
||||
The ``strtabs`` module implements an efficient hash table that is a mapping
|
||||
The `strtabs` module implements an efficient hash table that is a mapping
|
||||
from strings to strings. Supports a case-sensitive, case-insensitive and
|
||||
style-insensitive modes.
|
||||
|
||||
@@ -200,10 +202,10 @@ Time handling
|
||||
-------------
|
||||
|
||||
* `std/monotimes <monotimes.html>`_
|
||||
The ``monotimes`` module implements monotonic timestamps.
|
||||
The `monotimes` module implements monotonic timestamps.
|
||||
|
||||
* `times <times.html>`_
|
||||
The ``times`` module contains support for working with time.
|
||||
The `times` module contains support for working with time.
|
||||
|
||||
|
||||
Generic Operating System Services
|
||||
@@ -225,7 +227,7 @@ Generic Operating System Services
|
||||
data structures.
|
||||
|
||||
* `memfiles <memfiles.html>`_
|
||||
This module provides support for memory-mapped files (Posix's ``mmap``)
|
||||
This module provides support for memory-mapped files (Posix's `mmap`)
|
||||
on the different operating systems.
|
||||
|
||||
* `os <os.html>`_
|
||||
@@ -234,12 +236,12 @@ Generic Operating System Services
|
||||
commands, etc.
|
||||
|
||||
* `osproc <osproc.html>`_
|
||||
Module for process communication beyond ``os.execShellCmd``.
|
||||
Module for process communication beyond `os.execShellCmd`.
|
||||
|
||||
* `streams <streams.html>`_
|
||||
This module provides a stream interface and two implementations thereof:
|
||||
the ``FileStream`` and the ``StringStream`` which implement the stream
|
||||
interface for Nim file objects (``File``) and strings. Other modules
|
||||
the `FileStream` and the `StringStream` which implement the stream
|
||||
interface for Nim file objects (`File`) and strings. Other modules
|
||||
may provide other implementations for this standard stream interface.
|
||||
|
||||
* `terminal <terminal.html>`_
|
||||
@@ -288,22 +290,22 @@ Internet Protocols and Support
|
||||
|
||||
* `asyncfile <asyncfile.html>`_
|
||||
This module implements asynchronous file reading and writing using
|
||||
``asyncdispatch``.
|
||||
`asyncdispatch`.
|
||||
|
||||
* `asyncftpclient <asyncftpclient.html>`_
|
||||
This module implements an asynchronous FTP client using the ``asyncnet``
|
||||
This module implements an asynchronous FTP client using the `asyncnet`
|
||||
module.
|
||||
|
||||
* `asynchttpserver <asynchttpserver.html>`_
|
||||
This module implements an asynchronous HTTP server using the ``asyncnet``
|
||||
This module implements an asynchronous HTTP server using the `asyncnet`
|
||||
module.
|
||||
|
||||
* `asyncnet <asyncnet.html>`_
|
||||
This module implements asynchronous sockets based on the ``asyncdispatch``
|
||||
This module implements asynchronous sockets based on the `asyncdispatch`
|
||||
module.
|
||||
|
||||
* `asyncstreams <asyncstreams.html>`_
|
||||
This module provides ``FutureStream`` - a future that acts as a queue.
|
||||
This module provides `FutureStream` - a future that acts as a queue.
|
||||
|
||||
* `cgi <cgi.html>`_
|
||||
This module implements helpers for CGI applications.
|
||||
@@ -323,7 +325,7 @@ Internet Protocols and Support
|
||||
|
||||
* `net <net.html>`_
|
||||
This module implements a high-level sockets API. It replaces the
|
||||
``sockets`` module.
|
||||
`sockets` module.
|
||||
|
||||
* `selectors <selectors.html>`_
|
||||
This module implements a selector API with backends specific to each OS.
|
||||
@@ -357,23 +359,23 @@ Parsers
|
||||
scheme for lexers and parsers. This is used by the diverse parsing modules.
|
||||
|
||||
* `parsecfg <parsecfg.html>`_
|
||||
The ``parsecfg`` module implements a high-performance configuration file
|
||||
parser. The configuration file's syntax is similar to the Windows ``.ini``
|
||||
The `parsecfg` module implements a high-performance configuration file
|
||||
parser. The configuration file's syntax is similar to the Windows `.ini`
|
||||
format, but much more powerful, as it is not a line based parser. String
|
||||
literals, raw string literals, and triple quote string literals are supported
|
||||
as in the Nim programming language.
|
||||
|
||||
* `parsecsv <parsecsv.html>`_
|
||||
The ``parsecsv`` module implements a simple high-performance CSV parser.
|
||||
The `parsecsv` module implements a simple high-performance CSV parser.
|
||||
|
||||
* `parseopt <parseopt.html>`_
|
||||
The ``parseopt`` module implements a command line option parser.
|
||||
The `parseopt` module implements a command line option parser.
|
||||
|
||||
* `parsesql <parsesql.html>`_
|
||||
The ``parsesql`` module implements a simple high-performance SQL parser.
|
||||
The `parsesql` module implements a simple high-performance SQL parser.
|
||||
|
||||
* `parsexml <parsexml.html>`_
|
||||
The ``parsexml`` module implements a simple high performance XML/HTML parser.
|
||||
The `parsexml` module implements a simple high performance XML/HTML parser.
|
||||
The only encoding that is supported is UTF-8. The parser has been designed
|
||||
to be somewhat error-correcting, so that even some "wild HTML" found on the
|
||||
web can be parsed with it.
|
||||
@@ -458,7 +460,7 @@ Miscellaneous
|
||||
This module implements a simple logger.
|
||||
|
||||
* `segfaults <segfaults.html>`_
|
||||
Turns access violations or segfaults into a ``NilAccessDefect`` exception.
|
||||
Turns access violations or segfaults into a `NilAccessDefect` exception.
|
||||
|
||||
* `sugar <sugar.html>`_
|
||||
This module implements nice syntactic sugar based on Nim's macro system.
|
||||
@@ -480,11 +482,11 @@ Modules for JS backend
|
||||
Declaration of the Document Object Model for the JS backend.
|
||||
|
||||
* `jsconsole <jsconsole.html>`_
|
||||
Wrapper for the ``console`` object.
|
||||
Wrapper for the `console` object.
|
||||
|
||||
* `jscore <jscore.html>`_
|
||||
The wrapper of core JavaScript functions. For most purposes, you should be using
|
||||
the ``math``, ``json``, and ``times`` stdlib modules instead of this module.
|
||||
the `math`, `json`, and `times` stdlib modules instead of this module.
|
||||
|
||||
* `jsffi <jsffi.html>`_
|
||||
Types and macros for easier interaction with JavaScript.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
Memory safety for returning by ``var T`` is ensured by a simple borrowing
|
||||
rule: If ``result`` does not refer to a location pointing to the heap
|
||||
(that is in ``result = X`` the ``X`` involves a ``ptr`` or ``ref`` access)
|
||||
.. default-role:: code
|
||||
|
||||
Memory safety for returning by `var T` is ensured by a simple borrowing
|
||||
rule: If `result` does not refer to a location pointing to the heap
|
||||
(that is in `result = X` the `X` involves a `ptr` or `ref` access)
|
||||
then it has to be derived from the routine's first parameter:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -11,10 +13,10 @@ then it has to be derived from the routine's first parameter:
|
||||
var x: int
|
||||
# we know 'forward' provides a view into the location derived from
|
||||
# its first argument 'x'.
|
||||
result = forward(x) # Error: location is derived from ``x``
|
||||
result = forward(x) # Error: location is derived from `x`
|
||||
# which is not p's first parameter and lives
|
||||
# on the stack.
|
||||
|
||||
In other words, the lifetime of what ``result`` points to is attached to the
|
||||
In other words, the lifetime of what `result` points to is attached to the
|
||||
lifetime of the first parameter and that is enough knowledge to verify
|
||||
memory safety at the call site.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
||||
.. default-role:: code
|
||||
|
||||
Strict not nil checking
|
||||
=========================
|
||||
@@ -14,9 +15,9 @@ or
|
||||
|
||||
In the second case it would check builtin and imported modules as well.
|
||||
|
||||
It checks the nilability of ref-like types and makes dereferencing safer based on flow typing and ``not nil`` annotations.
|
||||
It checks the nilability of ref-like types and makes dereferencing safer based on flow typing and `not nil` annotations.
|
||||
|
||||
Its implementation is different than the ``notnil`` one: defined under ``strictNotNil``. Keep in mind the difference in option names, be careful with distinguishing them.
|
||||
Its implementation is different than the `notnil` one: defined under `strictNotNil`. Keep in mind the difference in option names, be careful with distinguishing them.
|
||||
|
||||
We check several kinds of types for nilability:
|
||||
|
||||
@@ -28,14 +29,14 @@ We check several kinds of types for nilability:
|
||||
nil
|
||||
-------
|
||||
|
||||
The default kind of nilability types is the nilable kind: they can have the value ``nil``.
|
||||
If you have a non-nilable type ``T``, you can use ``T nil`` to get a nilable type for it.
|
||||
The default kind of nilability types is the nilable kind: they can have the value `nil`.
|
||||
If you have a non-nilable type `T`, you can use `T nil` to get a nilable type for it.
|
||||
|
||||
|
||||
not nil
|
||||
--------
|
||||
|
||||
You can annotate a type where nil isn't a valid value with ``not nil``.
|
||||
You can annotate a type where nil isn't a valid value with `not nil`.
|
||||
|
||||
.. code-block:: nim
|
||||
type
|
||||
@@ -58,40 +59,40 @@ You can annotate a type where nil isn't a valid value with ``not nil``.
|
||||
|
||||
|
||||
|
||||
If a type can include ``nil`` as a valid value, dereferencing values of the type
|
||||
is checked by the compiler: if a value which might be nil is derefenced, this produces a warning by default, you can turn this into an error using the compiler options ``--warningAsError:strictNotNil``
|
||||
If a type can include `nil` as a valid value, dereferencing values of the type
|
||||
is checked by the compiler: if a value which might be nil is derefenced, this produces a warning by default, you can turn this into an error using the compiler options `--warningAsError:strictNotNil`
|
||||
|
||||
If a type is nilable, you should dereference its values only after a ``isNil`` or equivalent check.
|
||||
If a type is nilable, you should dereference its values only after a `isNil` or equivalent check.
|
||||
|
||||
local turn on/off
|
||||
---------------------
|
||||
|
||||
You can still turn off nil checking on function/module level by using a ``{.strictNotNil: off}.`` pragma.
|
||||
You can still turn off nil checking on function/module level by using a `{.strictNotNil: off}.` pragma.
|
||||
Note: test that/TODO for code/manual.
|
||||
|
||||
nilability state
|
||||
-----------------
|
||||
|
||||
Currently a nilable value can be ``Safe``, ``MaybeNil`` or ``Nil`` : we use internally ``Parent`` and ``Unreachable`` but this is an implementation detail(a parent layer has the actual nilability).
|
||||
Currently a nilable value can be `Safe`, `MaybeNil` or `Nil` : we use internally `Parent` and `Unreachable` but this is an implementation detail(a parent layer has the actual nilability).
|
||||
|
||||
``Safe`` means it shouldn't be nil at that point: e.g. after assignment to a non-nil value or ``not a.isNil`` check
|
||||
``MaybeNil`` means it might be nil, but it might not be nil: e.g. an argument, a call argument or a value after an ``if`` and ``else``.
|
||||
``Nil`` means it should be nil at that point; e.g. after an assignment to ``nil`` or a ``.isNil`` check.
|
||||
`Safe` means it shouldn't be nil at that point: e.g. after assignment to a non-nil value or `not a.isNil` check
|
||||
`MaybeNil` means it might be nil, but it might not be nil: e.g. an argument, a call argument or a value after an `if` and `else`.
|
||||
`Nil` means it should be nil at that point; e.g. after an assignment to `nil` or a `.isNil` check.
|
||||
|
||||
``Unreachable`` means it shouldn't be possible to access this in this branch: so we do generate a warning as well.
|
||||
`Unreachable` means it shouldn't be possible to access this in this branch: so we do generate a warning as well.
|
||||
|
||||
We show an error for each dereference (``[]``, ``.field``, ``[index]`` ``()`` etc) which is of a tracked expression which is
|
||||
in ``MaybeNil`` or ``Nil`` state.
|
||||
We show an error for each dereference (`[]`, `.field`, `[index]` `()` etc) which is of a tracked expression which is
|
||||
in `MaybeNil` or `Nil` state.
|
||||
|
||||
|
||||
type nilability
|
||||
----------------
|
||||
|
||||
Types are either nilable or non-nilable.
|
||||
When you pass a param or a default value, we use the type : for nilable types we return ``MaybeNil``
|
||||
and for non-nilable ``Safe``.
|
||||
When you pass a param or a default value, we use the type : for nilable types we return `MaybeNil`
|
||||
and for non-nilable `Safe`.
|
||||
|
||||
TODO: fix the manual here. (This is not great, as default values for non-nilables and nilables are usually actually ``nil`` , so we should think a bit more about this section.)
|
||||
TODO: fix the manual here. (This is not great, as default values for non-nilables and nilables are usually actually `nil` , so we should think a bit more about this section.)
|
||||
|
||||
params rules
|
||||
------------
|
||||
@@ -102,9 +103,9 @@ Param's nilability is detected based on type nilability. We use the type of the
|
||||
assignment rules
|
||||
-----------------
|
||||
|
||||
Let's say we have ``left = right``.
|
||||
Let's say we have `left = right`.
|
||||
|
||||
When we assign, we pass the right's nilability to the left's expression. There should be special handling of aliasing and compound expressions which we specify in their sections. (Assignment is a possible alias ``move`` or ``move out``).
|
||||
When we assign, we pass the right's nilability to the left's expression. There should be special handling of aliasing and compound expressions which we specify in their sections. (Assignment is a possible alias `move` or `move out`).
|
||||
|
||||
call args rules
|
||||
-----------------
|
||||
@@ -114,20 +115,20 @@ When we call with arguments, we have two cases when we might change the nilabili
|
||||
.. code-block:: nim
|
||||
callByVar(a)
|
||||
|
||||
Here ``callByVar`` can re-assign ``a``, so this might change ``a``'s nilability, so we change it to ``MaybeNil``.
|
||||
This is also a possible aliasing ``move out`` (moving out of a current alias set).
|
||||
Here `callByVar` can re-assign `a`, so this might change `a`'s nilability, so we change it to `MaybeNil`.
|
||||
This is also a possible aliasing `move out` (moving out of a current alias set).
|
||||
|
||||
.. code-block:: nim
|
||||
call(a)
|
||||
|
||||
Here ``call`` can change a field or element of ``a``, so if we have a dependant expression of ``a`` : e.g. ``a.field``. Dependats become ``MaybeNil``.
|
||||
Here `call` can change a field or element of `a`, so if we have a dependant expression of `a` : e.g. `a.field`. Dependats become `MaybeNil`.
|
||||
|
||||
|
||||
branches rules
|
||||
---------------
|
||||
|
||||
Branches are the reason we do nil checking like this: with flow checking.
|
||||
Sources of brancing are ``if``, ``while``, ``for``, ``and``, ``or``, ``case``, ``try`` and combinations with ``return``, ``break``, ``continue`` and ``raise``
|
||||
Sources of brancing are `if`, `while`, `for`, `and`, `or`, `case`, `try` and combinations with `return`, `break`, `continue` and `raise`
|
||||
|
||||
We create a new layer/"scope" for each branch where we map expressions to nilability. This happens when we "fork": usually on the beginning of a construct.
|
||||
When branches "join" we usually unify their expression maps or/and nilabilities.
|
||||
@@ -142,33 +143,33 @@ Merging usually merges maps and alias sets: nilabilities are merged like this:
|
||||
else:
|
||||
MaybeNil
|
||||
|
||||
Special handling is for ``.isNil`` and `` == nil``, also for ``not``, ``and`` and ``or``.
|
||||
Special handling is for `.isNil` and ` == nil`, also for `not`, `and` and `or`.
|
||||
|
||||
``not`` reverses the nilability, ``and`` is similar to "forking" : the right expression is checked in the layer resulting from the left one and ``or`` is similar to "merging": the right and left expression should be both checked in the original layer.
|
||||
`not` reverses the nilability, `and` is similar to "forking" : the right expression is checked in the layer resulting from the left one and `or` is similar to "merging": the right and left expression should be both checked in the original layer.
|
||||
|
||||
``isNil``, ``== nil`` make expressions ``Nil``. If there is a ``not`` or ``!= nil``, they make them ``Safe``.
|
||||
We also reverse the nilability in the opposite branch: e.g. ``else``.
|
||||
`isNil`, `== nil` make expressions `Nil`. If there is a `not` or `!= nil`, they make them `Safe`.
|
||||
We also reverse the nilability in the opposite branch: e.g. `else`.
|
||||
|
||||
compound expressions: field, index expressions
|
||||
-----------------------------------------------
|
||||
|
||||
We want to track also field(dot) and index(bracket) expressions.
|
||||
|
||||
We track some of those compound expressions which might be nilable as dependants of their bases: ``a.field`` is changed if ``a`` is moved (re-assigned),
|
||||
similarly ``a[index]`` is dependent on ``a`` and ``a.field.field`` on ``a.field``.
|
||||
We track some of those compound expressions which might be nilable as dependants of their bases: `a.field` is changed if `a` is moved (re-assigned),
|
||||
similarly `a[index]` is dependent on `a` and `a.field.field` on `a.field`.
|
||||
|
||||
When we move the base, we update dependants to ``MaybeNil``. Otherwise we usually start with type nilability.
|
||||
When we move the base, we update dependants to `MaybeNil`. Otherwise we usually start with type nilability.
|
||||
|
||||
When we call args, we update the nilability of their dependants to ``MaybeNil`` as the calls usually can change them.
|
||||
We might need to check for ``strictFuncs`` pure funcs and not do that then.
|
||||
When we call args, we update the nilability of their dependants to `MaybeNil` as the calls usually can change them.
|
||||
We might need to check for `strictFuncs` pure funcs and not do that then.
|
||||
|
||||
For field expressions ``a.field``, we calculate an integer value based on a hash of the tree and just accept equivalent trees as equivalent expressions.
|
||||
For field expressions `a.field`, we calculate an integer value based on a hash of the tree and just accept equivalent trees as equivalent expressions.
|
||||
|
||||
For item expression ``a[index]``, we also calculate an integer value based on a hash of the tree and accept equivalent trees as equivalent expressions: for static values only.
|
||||
For now we support only constant indices: we dont track expression with no-const indices. For those we just report a warning even if they are safe for now: one can use a local variable to workaround. For loops this might be annoying: so one should be able to turn off locally the warning using the ``{.warning[StrictCheckNotNil]:off}.``.
|
||||
For item expression `a[index]`, we also calculate an integer value based on a hash of the tree and accept equivalent trees as equivalent expressions: for static values only.
|
||||
For now we support only constant indices: we dont track expression with no-const indices. For those we just report a warning even if they are safe for now: one can use a local variable to workaround. For loops this might be annoying: so one should be able to turn off locally the warning using the `{.warning[StrictCheckNotNil]:off}.`.
|
||||
|
||||
For bracket expressions, in the future we might count ``a[<any>]`` as the same general expression.
|
||||
This means we should should the index but otherwise handle it the same for assign (maybe "aliasing" all the non-static elements) and differentiate only for static: e.g. ``a[0]`` and ``a[1]``.
|
||||
For bracket expressions, in the future we might count `a[<any>]` as the same general expression.
|
||||
This means we should should the index but otherwise handle it the same for assign (maybe "aliasing" all the non-static elements) and differentiate only for static: e.g. `a[0]` and `a[1]`.
|
||||
|
||||
element tracking
|
||||
-----------------
|
||||
@@ -185,8 +186,8 @@ Also related to tracking initialization of expressions/fields.
|
||||
unstructured control flow rules
|
||||
-------------------------------
|
||||
|
||||
Unstructured control flow keywords as ``return``, ``break``, ``continue``, ``raise`` mean that we jump from a branch out.
|
||||
This means that if there is code after the finishing of the branch, it would be ran if one hasn't hit the direct parent branch of those: so it is similar to an ``else``. In those cases we should use the reverse nilabilities for the local to the condition expressions. E.g.
|
||||
Unstructured control flow keywords as `return`, `break`, `continue`, `raise` mean that we jump from a branch out.
|
||||
This means that if there is code after the finishing of the branch, it would be ran if one hasn't hit the direct parent branch of those: so it is similar to an `else`. In those cases we should use the reverse nilabilities for the local to the condition expressions. E.g.
|
||||
|
||||
.. code-block:: nim
|
||||
for a in c:
|
||||
@@ -204,14 +205,14 @@ We support alias detection for local expressions.
|
||||
We track sets of aliased expressions. We start with all nilable local expressions in separate sets.
|
||||
Assignments and other changes to nilability can move / move out expressions of sets.
|
||||
|
||||
``move``: Moving ``left`` to ``right`` means we remove ``left`` from its current set and unify it with the ``right``'s set.
|
||||
`move`: Moving `left` to `right` means we remove `left` from its current set and unify it with the `right`'s set.
|
||||
This means it stops being aliased with its previous aliases.
|
||||
|
||||
.. code-block:: nim
|
||||
var left = b
|
||||
left = right # moving left to right
|
||||
|
||||
``move out``: Moving out ``left`` might remove it from the current set and ensure that it's in its own set as a single element.
|
||||
`move out`: Moving out `left` might remove it from the current set and ensure that it's in its own set as a single element.
|
||||
e.g.
|
||||
|
||||
|
||||
@@ -229,7 +230,7 @@ warnings and errors
|
||||
---------------------
|
||||
|
||||
We show an error for each dereference (`[]`, `.field`, `[index]` `()` etc) which is of a tracked expression which is
|
||||
in ``MaybeNil`` or ``Nil`` state.
|
||||
in `MaybeNil` or `Nil` state.
|
||||
|
||||
We might also show a history of the transitions and the reasons for them that might change the nilability of the expression.
|
||||
|
||||
|
||||
42
doc/nep1.rst
42
doc/nep1.rst
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
==========================================================
|
||||
Nim Enhancement Proposal #1 - Standard Library Style Guide
|
||||
==========================================================
|
||||
@@ -124,11 +126,11 @@ Naming Conventions
|
||||
|
||||
- In the age of HTTP, HTML, FTP, TCP, IP, UTF, WWW it is foolish to pretend
|
||||
these are somewhat special words requiring all uppercase. Instead treat them
|
||||
as what they are: Real words. So it's ``parseUrl`` rather than
|
||||
``parseURL``, ``checkHttpHeader`` instead of ``checkHTTPHeader`` etc.
|
||||
as what they are: Real words. So it's `parseUrl` rather than
|
||||
`parseURL`, `checkHttpHeader` instead of `checkHTTPHeader` etc.
|
||||
|
||||
- Operations like ``mitems`` or ``mpairs`` (or the now deprecated ``mget``)
|
||||
that allow a *mutating view* into some data structure should start with an ``m``.
|
||||
- Operations like `mitems` or `mpairs` (or the now deprecated `mget`)
|
||||
that allow a *mutating view* into some data structure should start with an `m`.
|
||||
- When both in-place mutation and 'returns transformed copy' are available the latter
|
||||
is a past participle of the former:
|
||||
|
||||
@@ -136,8 +138,8 @@ Naming Conventions
|
||||
- sort and sorted
|
||||
- rotate and rotated
|
||||
|
||||
- When the 'returns transformed copy' version already exists like ``strutils.replace``
|
||||
an in-place version should get an ``-In`` suffix (``replaceIn`` for this example).
|
||||
- When the 'returns transformed copy' version already exists like `strutils.replace`
|
||||
an in-place version should get an `-In` suffix (`replaceIn` for this example).
|
||||
|
||||
|
||||
- Use `subjectVerb`, not `verbSubject`, e.g.: `fileExists`, not `existsFile`.
|
||||
@@ -153,25 +155,25 @@ to keep the names short but meaningful.
|
||||
------------------- ------------ --------------------------------------
|
||||
English word To use Notes
|
||||
------------------- ------------ --------------------------------------
|
||||
initialize initFoo initializes a value type ``Foo``
|
||||
new newFoo initializes a reference type ``Foo``
|
||||
via ``new``
|
||||
initialize initFoo initializes a value type `Foo`
|
||||
new newFoo initializes a reference type `Foo`
|
||||
via `new`
|
||||
this or self self for method like procs, e.g.:
|
||||
`proc fun(self: Foo, a: int)`
|
||||
rationale: `self` is more unique in English
|
||||
than `this`, and `foo` would not be DRY.
|
||||
find find should return the position where
|
||||
something was found; for a bool result
|
||||
use ``contains``
|
||||
contains contains often short for ``find() >= 0``
|
||||
append add use ``add`` instead of ``append``
|
||||
use `contains`
|
||||
contains contains often short for `find() >= 0`
|
||||
append add use `add` instead of `append`
|
||||
compare cmp should return an int with the
|
||||
``< 0`` ``== 0`` or ``> 0`` semantics;
|
||||
for a bool result use ``sameXYZ``
|
||||
put put, ``[]=`` consider overloading ``[]=`` for put
|
||||
get get, ``[]`` consider overloading ``[]`` for get;
|
||||
consider to not use ``get`` as a
|
||||
prefix: ``len`` instead of ``getLen``
|
||||
`< 0` `== 0` or `> 0` semantics;
|
||||
for a bool result use `sameXYZ`
|
||||
put put, `[]=` consider overloading `[]=` for put
|
||||
get get, `[]` consider overloading `[]` for get;
|
||||
consider to not use `get` as a
|
||||
prefix: `len` instead of `getLen`
|
||||
length len also used for *number of elements*
|
||||
size size, len size should refer to a byte size
|
||||
capacity cap
|
||||
@@ -236,8 +238,8 @@ Coding Conventions
|
||||
- Use a proc when possible, only using the more powerful facilities of macros,
|
||||
templates, iterators, and converters when necessary.
|
||||
|
||||
- Use the ``let`` statement (not the ``var`` statement) when declaring variables that
|
||||
do not change within their scope. Using the ``let`` statement ensures that
|
||||
- Use the `let` statement (not the `var` statement) when declaring variables that
|
||||
do not change within their scope. Using the `let` statement ensures that
|
||||
variables remain immutable, and gives those who read the code a better idea
|
||||
of the code's purpose.
|
||||
|
||||
|
||||
222
doc/nimc.rst
222
doc/nimc.rst
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
===================================
|
||||
Nim Compiler User Guide
|
||||
===================================
|
||||
@@ -45,8 +47,8 @@ Advanced command-line switches are:
|
||||
List of warnings
|
||||
----------------
|
||||
|
||||
Each warning can be activated individually with ``--warning[NAME]:on|off`` or
|
||||
in a ``push`` pragma.
|
||||
Each warning can be activated individually with `--warning[NAME]:on|off` or
|
||||
in a `push` pragma.
|
||||
|
||||
========================== ============================================
|
||||
Name Description
|
||||
@@ -60,7 +62,7 @@ ConfigDeprecated The project makes use of a deprecated config
|
||||
file.
|
||||
SmallLshouldNotBeUsed The letter 'l' should not be used as an
|
||||
identifier.
|
||||
EachIdentIsTuple The code contains a confusing ``var``
|
||||
EachIdentIsTuple The code contains a confusing `var`
|
||||
declaration.
|
||||
User Some user-defined warning.
|
||||
========================== ============================================
|
||||
@@ -69,8 +71,8 @@ User Some user-defined warning.
|
||||
List of hints
|
||||
-------------
|
||||
|
||||
Each hint can be activated individually with ``--hint[NAME]:on|off`` or in a
|
||||
``push`` pragma.
|
||||
Each hint can be activated individually with `--hint[NAME]:on|off` or in a
|
||||
`push` pragma.
|
||||
|
||||
========================== ============================================
|
||||
Name Description
|
||||
@@ -129,52 +131,52 @@ Level Description
|
||||
Compile-time symbols
|
||||
--------------------
|
||||
|
||||
Through the ``-d:x`` or ``--define:x`` switch you can define compile-time
|
||||
Through the `-d:x` or `--define:x` switch you can define compile-time
|
||||
symbols for conditional compilation. The defined switches can be checked in
|
||||
source code with the `when statement
|
||||
<manual.html#statements-and-expressions-when-statement>`_ and
|
||||
`defined proc <system.html#defined,untyped>`_. The typical use of this switch is
|
||||
to enable builds in release mode (``-d:release``) where optimizations are
|
||||
enabled for better performance. Another common use is the ``-d:ssl`` switch to
|
||||
to enable builds in release mode (`-d:release`) where optimizations are
|
||||
enabled for better performance. Another common use is the `-d:ssl` switch to
|
||||
activate SSL sockets.
|
||||
|
||||
Additionally, you may pass a value along with the symbol: ``-d:x=y``
|
||||
Additionally, you may pass a value along with the symbol: `-d:x=y`
|
||||
which may be used in conjunction with the `compile-time define
|
||||
pragmas<manual.html#implementation-specific-pragmas-compileminustime-define-pragmas>`_
|
||||
to override symbols during build time.
|
||||
|
||||
Compile-time symbols are completely **case insensitive** and underscores are
|
||||
ignored too. ``--define:FOO`` and ``--define:foo`` are identical.
|
||||
ignored too. `--define:FOO` and `--define:foo` are identical.
|
||||
|
||||
Compile-time symbols starting with the ``nim`` prefix are reserved for the
|
||||
Compile-time symbols starting with the `nim` prefix are reserved for the
|
||||
implementation and should not be used elsewhere.
|
||||
|
||||
|
||||
Configuration files
|
||||
-------------------
|
||||
|
||||
**Note:** The *project file name* is the name of the ``.nim`` file that is
|
||||
**Note:** The *project file name* is the name of the `.nim` file that is
|
||||
passed as a command-line argument to the compiler.
|
||||
|
||||
|
||||
The ``nim`` executable processes configuration files in the following
|
||||
The `nim` executable processes configuration files in the following
|
||||
directories (in this order; later files overwrite previous settings):
|
||||
|
||||
1) ``$nim/config/nim.cfg``, ``/etc/nim/nim.cfg`` (UNIX) or ``<Nim's installation directory>\config\nim.cfg`` (Windows). This file can be skipped with the ``--skipCfg`` command line option.
|
||||
2) If environment variable ``XDG_CONFIG_HOME`` is defined, ``$XDG_CONFIG_HOME/nim/nim.cfg`` or ``~/.config/nim/nim.cfg`` (POSIX) or ``%APPDATA%/nim/nim.cfg`` (Windows). This file can be skipped with the ``--skipUserCfg`` command line option.
|
||||
3) ``$parentDir/nim.cfg`` where ``$parentDir`` stands for any parent directory of the project file's path. These files can be skipped with the ``--skipParentCfg`` command-line option.
|
||||
4) ``$projectDir/nim.cfg`` where ``$projectDir`` stands for the project file's path. This file can be skipped with the ``--skipProjCfg`` command-line option.
|
||||
5) A project can also have a project-specific configuration file named ``$project.nim.cfg`` that resides in the same directory as ``$project.nim``. This file can be skipped with the ``--skipProjCfg`` command-line option.
|
||||
1) `$nim/config/nim.cfg`, `/etc/nim/nim.cfg` (UNIX) or ``<Nim's installation directory>\config\nim.cfg`` (Windows). This file can be skipped with the `--skipCfg` command line option.
|
||||
2) If environment variable `XDG_CONFIG_HOME` is defined, `$XDG_CONFIG_HOME/nim/nim.cfg` or `~/.config/nim/nim.cfg` (POSIX) or `%APPDATA%/nim/nim.cfg` (Windows). This file can be skipped with the `--skipUserCfg` command line option.
|
||||
3) `$parentDir/nim.cfg` where `$parentDir` stands for any parent directory of the project file's path. These files can be skipped with the `--skipParentCfg` command-line option.
|
||||
4) `$projectDir/nim.cfg` where `$projectDir` stands for the project file's path. This file can be skipped with the `--skipProjCfg` command-line option.
|
||||
5) A project can also have a project-specific configuration file named `$project.nim.cfg` that resides in the same directory as `$project.nim`. This file can be skipped with the `--skipProjCfg` command-line option.
|
||||
|
||||
|
||||
Command-line settings have priority over configuration file settings.
|
||||
|
||||
The default build of a project is a `debug build`:idx:. To compile a
|
||||
`release build`:idx: define the ``release`` symbol::
|
||||
`release build`:idx: define the `release` symbol::
|
||||
|
||||
nim c -d:release myproject.nim
|
||||
|
||||
To compile a `dangerous release build`:idx: define the ``danger`` symbol::
|
||||
To compile a `dangerous release build`:idx: define the `danger` symbol::
|
||||
|
||||
nim c -d:danger myproject.nim
|
||||
|
||||
@@ -186,10 +188,10 @@ Nim has the concept of a global search path (PATH) that is queried to
|
||||
determine where to find imported modules or include files. If multiple files are
|
||||
found an ambiguity error is produced.
|
||||
|
||||
``nim dump`` shows the contents of the PATH.
|
||||
`nim dump` shows the contents of the PATH.
|
||||
|
||||
However before the PATH is used the current directory is checked for the
|
||||
file's existence. So if PATH contains ``$lib`` and ``$lib/bar`` and the
|
||||
file's existence. So if PATH contains `$lib` and `$lib/bar` and the
|
||||
directory structure looks like this::
|
||||
|
||||
$lib/x.nim
|
||||
@@ -198,27 +200,27 @@ directory structure looks like this::
|
||||
foo/main.nim
|
||||
other.nim
|
||||
|
||||
And ``main`` imports ``x``, ``foo/x`` is imported. If ``other`` imports ``x``
|
||||
then both ``$lib/x.nim`` and ``$lib/bar/x.nim`` match but ``$lib/x.nim`` is used
|
||||
And `main` imports `x`, `foo/x` is imported. If `other` imports `x`
|
||||
then both `$lib/x.nim` and `$lib/bar/x.nim` match but `$lib/x.nim` is used
|
||||
as it is the first match.
|
||||
|
||||
|
||||
Generated C code directory
|
||||
--------------------------
|
||||
The generated files that Nim produces all go into a subdirectory called
|
||||
``nimcache``. Its full path is
|
||||
`nimcache`. Its full path is
|
||||
|
||||
- ``$XDG_CACHE_HOME/nim/$projectname(_r|_d)`` or ``~/.cache/nim/$projectname(_r|_d)``
|
||||
- `$XDG_CACHE_HOME/nim/$projectname(_r|_d)` or `~/.cache/nim/$projectname(_r|_d)`
|
||||
on Posix
|
||||
- ``$HOME/nimcache/$projectname(_r|_d)`` on Windows.
|
||||
- `$HOME/nimcache/$projectname(_r|_d)` on Windows.
|
||||
|
||||
The ``_r`` suffix is used for release builds, ``_d`` is for debug builds.
|
||||
The `_r` suffix is used for release builds, `_d` is for debug builds.
|
||||
|
||||
This makes it easy to delete all generated files.
|
||||
|
||||
The ``--nimcache``
|
||||
The `--nimcache`
|
||||
`compiler switch <#compiler-usage-commandminusline-switches>`_ can be used to
|
||||
to change the ``nimcache`` directory.
|
||||
to change the `nimcache` directory.
|
||||
|
||||
However, the generated C code is not platform-independent. C code generated for
|
||||
Linux does not compile on Windows, for instance. The comment on top of the
|
||||
@@ -232,16 +234,16 @@ To change the compiler from the default compiler (at the command line)::
|
||||
|
||||
nim c --cc:llvm_gcc --compile_only myfile.nim
|
||||
|
||||
This uses the configuration defined in ``config\nim.cfg`` for ``lvm_gcc``.
|
||||
This uses the configuration defined in ``config\nim.cfg`` for `lvm_gcc`.
|
||||
|
||||
If nimcache already contains compiled code from a different compiler for the same project,
|
||||
add the ``-f`` flag to force all files to be recompiled.
|
||||
add the `-f` flag to force all files to be recompiled.
|
||||
|
||||
The default compiler is defined at the top of ``config\nim.cfg``.
|
||||
Changing this setting affects the compiler used by ``koch`` to (re)build Nim.
|
||||
Changing this setting affects the compiler used by `koch` to (re)build Nim.
|
||||
|
||||
To use the ``CC`` environment variable, use ``nim c --cc:env myfile.nim``. To use the
|
||||
``CXX`` environment variable, use ``nim cpp --cc:env myfile.nim``. ``--cc:env`` is available
|
||||
To use the `CC` environment variable, use `nim c --cc:env myfile.nim`. To use the
|
||||
`CXX` environment variable, use `nim cpp --cc:env myfile.nim`. `--cc:env` is available
|
||||
since Nim version 1.4.
|
||||
|
||||
|
||||
@@ -252,7 +254,7 @@ To cross compile, use for example::
|
||||
|
||||
nim c --cpu:i386 --os:linux --compileOnly --genScript myproject.nim
|
||||
|
||||
Then move the C code and the compile script ``compile_myproject.sh`` to your
|
||||
Then move the C code and the compile script `compile_myproject.sh` to your
|
||||
Linux i386 machine and run the script.
|
||||
|
||||
Another way is to make Nim invoke a cross compiler toolchain::
|
||||
@@ -260,8 +262,8 @@ Another way is to make Nim invoke a cross compiler toolchain::
|
||||
nim c --cpu:arm --os:linux myproject.nim
|
||||
|
||||
For cross compilation, the compiler invokes a C compiler named
|
||||
like ``$cpu.$os.$cc`` (for example arm.linux.gcc) and the configuration
|
||||
system is used to provide meaningful defaults. For example for ``ARM`` your
|
||||
like `$cpu.$os.$cc` (for example arm.linux.gcc) and the configuration
|
||||
system is used to provide meaningful defaults. For example for `ARM` your
|
||||
configuration file should contain something like::
|
||||
|
||||
arm.linux.gcc.path = "/usr/bin"
|
||||
@@ -275,7 +277,7 @@ To cross-compile for Windows from Linux or macOS using the MinGW-w64 toolchain::
|
||||
|
||||
nim c -d:mingw myproject.nim
|
||||
|
||||
Use ``--cpu:i386`` or ``--cpu:amd64`` to switch the CPU architecture.
|
||||
Use `--cpu:i386` or `--cpu:amd64` to switch the CPU architecture.
|
||||
|
||||
The MinGW-w64 toolchain can be installed as follows::
|
||||
|
||||
@@ -295,7 +297,7 @@ The first one is to treat Android as a simple Linux and use
|
||||
directly on android as if it was Linux. These programs are console-only
|
||||
programs that can't be distributed in the Play Store.
|
||||
|
||||
Use regular ``nim c`` inside termux to make Android terminal programs.
|
||||
Use regular `nim c` inside termux to make Android terminal programs.
|
||||
|
||||
Normal Android apps are written in Java, to use Nim inside an Android app
|
||||
you need a small Java stub that calls out to a native library written in
|
||||
@@ -303,16 +305,16 @@ Nim using the `NDK <https://developer.android.com/ndk>`_. You can also use
|
||||
`native-activity <https://developer.android.com/ndk/samples/sample_na>`_
|
||||
to have the Java stub be auto-generated for you.
|
||||
|
||||
Use ``nim c -c --cpu:arm --os:android -d:androidNDK --noMain:on`` to
|
||||
Use `nim c -c --cpu:arm --os:android -d:androidNDK --noMain:on` to
|
||||
generate the C source files you need to include in your Android Studio
|
||||
project. Add the generated C files to CMake build script in your Android
|
||||
project. Then do the final compile with Android Studio which uses Gradle
|
||||
to call CMake to compile the project.
|
||||
|
||||
Because Nim is part of a library it can't have its own c style ``main()``
|
||||
so you would need to define your own ``android_main`` and init the Java
|
||||
Because Nim is part of a library it can't have its own c style `main()`
|
||||
so you would need to define your own `android_main` and init the Java
|
||||
environment, or use a library like SDL2 or GLFM to do it. After the Android
|
||||
stuff is done, it's very important to call ``NimMain()`` in order to
|
||||
stuff is done, it's very important to call `NimMain()` in order to
|
||||
initialize Nim's garbage collector and to run the top level statements
|
||||
of your program.
|
||||
|
||||
@@ -331,14 +333,14 @@ Normal languages for iOS development are Swift and Objective C. Both of these
|
||||
use LLVM and can be compiled into object files linked together with C, C++
|
||||
or Objective C code produced by Nim.
|
||||
|
||||
Use ``nim c -c --os:ios --noMain:on`` to generate C files and include them in
|
||||
Use `nim c -c --os:ios --noMain:on` to generate C files and include them in
|
||||
your XCode project. Then you can use XCode to compile, link, package and
|
||||
sign everything.
|
||||
|
||||
Because Nim is part of a library it can't have its own c style ``main()`` so you
|
||||
would need to define `main` that calls ``autoreleasepool`` and
|
||||
``UIApplicationMain`` to do it, or use a library like SDL2 or GLFM. After
|
||||
the iOS setup is done, it's very important to call ``NimMain()`` to
|
||||
Because Nim is part of a library it can't have its own c style `main()` so you
|
||||
would need to define `main` that calls `autoreleasepool` and
|
||||
`UIApplicationMain` to do it, or use a library like SDL2 or GLFM. After
|
||||
the iOS setup is done, it's very important to call `NimMain()` to
|
||||
initialize Nim's garbage collector and to run the top-level statements
|
||||
of your program.
|
||||
|
||||
@@ -356,8 +358,8 @@ Cross-compilation for Nintendo Switch
|
||||
=====================================
|
||||
|
||||
Simply add --os:nintendoswitch
|
||||
to your usual ``nim c`` or ``nim cpp`` command and set the ``passC``
|
||||
and ``passL`` command line switches to something like:
|
||||
to your usual `nim c` or `nim cpp` command and set the `passC`
|
||||
and `passL` command line switches to something like:
|
||||
|
||||
.. code-block:: console
|
||||
nim c ... --passC="-I$DEVKITPRO/libnx/include" ...
|
||||
@@ -378,8 +380,8 @@ For example, with the above-mentioned config::
|
||||
|
||||
nim c --os:nintendoswitch switchhomebrew.nim
|
||||
|
||||
This will generate a file called ``switchhomebrew.elf`` which can then be turned into
|
||||
an nro file with the ``elf2nro`` tool in the DevkitPro release. Examples can be found at
|
||||
This will generate a file called `switchhomebrew.elf` which can then be turned into
|
||||
an nro file with the `elf2nro` tool in the DevkitPro release. Examples can be found at
|
||||
`the nim-libnx github repo <https://github.com/jyapayne/nim-libnx.git>`_.
|
||||
|
||||
There are a few things that don't work because the DevkitPro libraries don't support them.
|
||||
@@ -399,62 +401,62 @@ DLL generation
|
||||
|
||||
Nim supports the generation of DLLs. However, there must be only one
|
||||
instance of the GC per process/address space. This instance is contained in
|
||||
``nimrtl.dll``. This means that every generated Nim DLL depends
|
||||
on ``nimrtl.dll``. To generate the "nimrtl.dll" file, use the command::
|
||||
`nimrtl.dll`. This means that every generated Nim DLL depends
|
||||
on `nimrtl.dll`. To generate the "nimrtl.dll" file, use the command::
|
||||
|
||||
nim c -d:release lib/nimrtl.nim
|
||||
|
||||
To link against ``nimrtl.dll`` use the command::
|
||||
To link against `nimrtl.dll` use the command::
|
||||
|
||||
nim c -d:useNimRtl myprog.nim
|
||||
|
||||
**Note**: Currently the creation of ``nimrtl.dll`` with thread support has
|
||||
**Note**: Currently the creation of `nimrtl.dll` with thread support has
|
||||
never been tested and is unlikely to work!
|
||||
|
||||
|
||||
Additional compilation switches
|
||||
===============================
|
||||
|
||||
The standard library supports a growing number of ``useX`` conditional defines
|
||||
The standard library supports a growing number of `useX` conditional defines
|
||||
affecting how some features are implemented. This section tries to give a
|
||||
complete list.
|
||||
|
||||
====================== =========================================================
|
||||
Define Effect
|
||||
====================== =========================================================
|
||||
``release`` Turns on the optimizer.
|
||||
`release` Turns on the optimizer.
|
||||
More aggressive optimizations are possible, e.g.:
|
||||
``--passC:-ffast-math`` (but see issue #10305)
|
||||
``danger`` Turns off all runtime checks and turns on the optimizer.
|
||||
``useFork`` Makes ``osproc`` use ``fork`` instead of ``posix_spawn``.
|
||||
``useNimRtl`` Compile and link against ``nimrtl.dll``.
|
||||
``useMalloc`` Makes Nim use C's `malloc`:idx: instead of Nim's
|
||||
`--passC:-ffast-math` (but see issue #10305)
|
||||
`danger` Turns off all runtime checks and turns on the optimizer.
|
||||
`useFork` Makes `osproc` use `fork` instead of `posix_spawn`.
|
||||
`useNimRtl` Compile and link against `nimrtl.dll`.
|
||||
`useMalloc` Makes Nim use C's `malloc`:idx: instead of Nim's
|
||||
own memory manager, albeit prefixing each allocation with
|
||||
its size to support clearing memory on reallocation.
|
||||
This only works with ``gc:none``, ``gc:arc`` and
|
||||
``--gc:orc``.
|
||||
``useRealtimeGC`` Enables support of Nim's GC for *soft* realtime
|
||||
This only works with `gc:none`, `gc:arc` and
|
||||
`--gc:orc`.
|
||||
`useRealtimeGC` Enables support of Nim's GC for *soft* realtime
|
||||
systems. See the documentation of the `gc <gc.html>`_
|
||||
for further information.
|
||||
``logGC`` Enable GC logging to stdout.
|
||||
``nodejs`` The JS target is actually ``node.js``.
|
||||
``ssl`` Enables OpenSSL support for the sockets module.
|
||||
``memProfiler`` Enables memory profiling for the native GC.
|
||||
``uClibc`` Use uClibc instead of libc. (Relevant for Unix-like OSes)
|
||||
``checkAbi`` When using types from C headers, add checks that compare
|
||||
`logGC` Enable GC logging to stdout.
|
||||
`nodejs` The JS target is actually `node.js`.
|
||||
`ssl` Enables OpenSSL support for the sockets module.
|
||||
`memProfiler` Enables memory profiling for the native GC.
|
||||
`uClibc` Use uClibc instead of libc. (Relevant for Unix-like OSes)
|
||||
`checkAbi` When using types from C headers, add checks that compare
|
||||
what's in the Nim file with what's in the C header.
|
||||
This may become enabled by default in the future.
|
||||
``tempDir`` This symbol takes a string as its value, like
|
||||
``--define:tempDir:/some/temp/path`` to override the
|
||||
temporary directory returned by ``os.getTempDir()``.
|
||||
`tempDir` This symbol takes a string as its value, like
|
||||
`--define:tempDir:/some/temp/path` to override the
|
||||
temporary directory returned by `os.getTempDir()`.
|
||||
The value **should** end with a directory separator
|
||||
character. (Relevant for the Android platform)
|
||||
``useShPath`` This symbol takes a string as its value, like
|
||||
``--define:useShPath:/opt/sh/bin/sh`` to override the
|
||||
path for the ``sh`` binary, in cases where it is not
|
||||
located in the default location ``/bin/sh``.
|
||||
``noSignalHandler`` Disable the crash handler from ``system.nim``.
|
||||
``globalSymbols`` Load all ``{.dynlib.}`` libraries with the ``RTLD_GLOBAL``
|
||||
`useShPath` This symbol takes a string as its value, like
|
||||
`--define:useShPath:/opt/sh/bin/sh` to override the
|
||||
path for the `sh` binary, in cases where it is not
|
||||
located in the default location `/bin/sh`.
|
||||
`noSignalHandler` Disable the crash handler from `system.nim`.
|
||||
`globalSymbols` Load all `{.dynlib.}` libraries with the `RTLD_GLOBAL`
|
||||
flag on Posix systems to resolve symbols in subsequently
|
||||
loaded libraries.
|
||||
====================== =========================================================
|
||||
@@ -471,20 +473,20 @@ generator and are subject to change.
|
||||
|
||||
LineDir option
|
||||
--------------
|
||||
The ``lineDir`` option can be turned on or off. If turned on the
|
||||
generated C code contains ``#line`` directives. This may be helpful for
|
||||
The `lineDir` option can be turned on or off. If turned on the
|
||||
generated C code contains `#line` directives. This may be helpful for
|
||||
debugging with GDB.
|
||||
|
||||
|
||||
StackTrace option
|
||||
-----------------
|
||||
If the ``stackTrace`` option is turned on, the generated C contains code to
|
||||
If the `stackTrace` option is turned on, the generated C contains code to
|
||||
ensure that proper stack traces are given if the program crashes or some uncaught exception is raised.
|
||||
|
||||
|
||||
LineTrace option
|
||||
----------------
|
||||
The ``lineTrace`` option implies the ``stackTrace`` option. If turned on,
|
||||
The `lineTrace` option implies the `stackTrace` option. If turned on,
|
||||
the generated C contains code to ensure that proper stack traces with line
|
||||
number information are given if the program crashes or an uncaught exception
|
||||
is raised.
|
||||
@@ -493,10 +495,10 @@ is raised.
|
||||
DynlibOverride
|
||||
==============
|
||||
|
||||
By default Nim's ``dynlib`` pragma causes the compiler to generate
|
||||
``GetProcAddress`` (or their Unix counterparts)
|
||||
calls to bind to a DLL. With the ``dynlibOverride`` command line switch this
|
||||
can be prevented and then via ``--passL`` the static library can be linked
|
||||
By default Nim's `dynlib` pragma causes the compiler to generate
|
||||
`GetProcAddress` (or their Unix counterparts)
|
||||
calls to bind to a DLL. With the `dynlibOverride` command line switch this
|
||||
can be prevented and then via `--passL` the static library can be linked
|
||||
against. For instance, to link statically against Lua this command might work
|
||||
on Linux::
|
||||
|
||||
@@ -506,8 +508,8 @@ on Linux::
|
||||
Backend language options
|
||||
========================
|
||||
|
||||
The typical compiler usage involves using the ``compile`` or ``c`` command to
|
||||
transform a ``.nim`` file into one or more ``.c`` files which are then
|
||||
The typical compiler usage involves using the `compile` or `c` command to
|
||||
transform a `.nim` file into one or more `.c` files which are then
|
||||
compiled with the platform's C compiler into a static binary. However, there
|
||||
are other commands to compile to C++, Objective-C, or JavaScript. More details
|
||||
can be read in the `Nim Backend Integration document <backends.html>`_.
|
||||
@@ -517,7 +519,7 @@ Nim documentation tools
|
||||
=======================
|
||||
|
||||
Nim provides the `doc`:idx: command to generate HTML
|
||||
documentation from ``.nim`` source files. Only exported symbols will appear in
|
||||
documentation from `.nim` source files. Only exported symbols will appear in
|
||||
the output. For more details `see the docgen documentation <docgen.html>`_.
|
||||
|
||||
Nim idetools integration
|
||||
@@ -533,15 +535,15 @@ for further information.
|
||||
|
||||
The Nim compiler supports an interactive mode. This is also known as
|
||||
a `REPL`:idx: (*read eval print loop*). If Nim has been built with the
|
||||
``-d:nimUseLinenoise`` switch, it uses the GNU readline library for terminal
|
||||
`-d:nimUseLinenoise` switch, it uses the GNU readline library for terminal
|
||||
input management. To start Nim in interactive mode use the command
|
||||
``nim secret``. To quit use the ``quit()`` command. To determine whether an input
|
||||
`nim secret`. To quit use the `quit()` command. To determine whether an input
|
||||
line is an incomplete statement to be continued these rules are used:
|
||||
|
||||
1. The line ends with ``[-+*/\\<>!\?\|%&$@~,;:=#^]\s*$`` (operator symbol followed by optional whitespace).
|
||||
2. The line starts with a space (indentation).
|
||||
3. The line is within a triple quoted string literal. However, the detection
|
||||
does not work if the line contains more than one ``"""``.
|
||||
does not work if the line contains more than one `"""`.
|
||||
|
||||
|
||||
Nim for embedded systems
|
||||
@@ -552,22 +554,22 @@ modern PC hardware and operating systems with ample memory, it is very well
|
||||
possible to run Nim code and a good part of the Nim standard libraries on small
|
||||
embedded microprocessors with only a few kilobytes of memory.
|
||||
|
||||
A good start is to use the ``any`` operating target together with the
|
||||
``malloc`` memory allocator and the ``arc`` garbage collector. For example:
|
||||
A good start is to use the `any` operating target together with the
|
||||
`malloc` memory allocator and the `arc` garbage collector. For example:
|
||||
|
||||
``nim c --os:any --gc:arc -d:useMalloc [...] x.nim``
|
||||
`nim c --os:any --gc:arc -d:useMalloc [...] x.nim`
|
||||
|
||||
- ``--gc:arc`` will enable the reference counting memory management instead
|
||||
- `--gc:arc` will enable the reference counting memory management instead
|
||||
of the default garbage collector. This enables Nim to use heap memory which
|
||||
is required for strings and seqs, for example.
|
||||
|
||||
- The ``--os:any`` target makes sure Nim does not depend on any specific
|
||||
- The `--os:any` target makes sure Nim does not depend on any specific
|
||||
operating system primitives. Your platform should support only some basic
|
||||
ANSI C library ``stdlib`` and ``stdio`` functions which should be available
|
||||
ANSI C library `stdlib` and `stdio` functions which should be available
|
||||
on almost any platform.
|
||||
|
||||
- The ``-d:useMalloc`` option configures Nim to use only the standard C memory
|
||||
manage primitives ``malloc()``, ``free()``, ``realloc()``.
|
||||
- The `-d:useMalloc` option configures Nim to use only the standard C memory
|
||||
manage primitives `malloc()`, `free()`, `realloc()`.
|
||||
|
||||
If your platform does not provide these functions it should be trivial to
|
||||
provide an implementation for them and link these to your program.
|
||||
@@ -577,10 +579,10 @@ additional flags to both the Nim compiler and the C compiler and/or linker
|
||||
to optimize the build for size. For example, the following flags can be used
|
||||
when targeting a gcc compiler:
|
||||
|
||||
``--opt:size --passC:-flto --passL:-flto``
|
||||
`--opt:size --passC:-flto --passL:-flto`
|
||||
|
||||
The ``--opt:size`` flag instructs Nim to optimize code generation for small
|
||||
size (with the help of the C compiler), the ``flto`` flags enable link-time
|
||||
The `--opt:size` flag instructs Nim to optimize code generation for small
|
||||
size (with the help of the C compiler), the `flto` flags enable link-time
|
||||
optimization in the compiler and linker.
|
||||
|
||||
Check the `Cross-compilation` section for instructions on how to compile the
|
||||
@@ -600,7 +602,7 @@ The Nim programming language has no concept of Posix's signal handling
|
||||
mechanisms. However, the standard library offers some rudimentary support
|
||||
for signal handling, in particular, segmentation faults are turned into
|
||||
fatal errors that produce a stack trace. This can be disabled with the
|
||||
``-d:noSignalHandler`` switch.
|
||||
`-d:noSignalHandler` switch.
|
||||
|
||||
|
||||
Optimizing for Nim
|
||||
@@ -642,7 +644,7 @@ However, it is not efficient to do:
|
||||
.. code-block:: Nim
|
||||
var s = varA # assignment has to copy the whole string into a new buffer!
|
||||
|
||||
For ``let`` symbols a copy is not always necessary:
|
||||
For `let` symbols a copy is not always necessary:
|
||||
|
||||
.. code-block:: Nim
|
||||
let s = varA # may only copy a pointer if it safe to do so
|
||||
@@ -656,7 +658,7 @@ objects as `shallow`:idx:\:
|
||||
shallow(s) # mark 's' as a shallow string
|
||||
var x = s # now might not copy the string!
|
||||
|
||||
Usage of ``shallow`` is always safe once you know the string won't be modified
|
||||
Usage of `shallow` is always safe once you know the string won't be modified
|
||||
anymore, similar to Ruby's `freeze`:idx:.
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
=====================
|
||||
Nimfix User Guide
|
||||
=====================
|
||||
@@ -14,12 +16,12 @@ It performs 3 different actions:
|
||||
|
||||
1. It makes your code case consistent.
|
||||
2. It renames every symbol that has a deprecation rule. So if a module has a
|
||||
rule ``{.deprecated: [TFoo: Foo].}`` then ``TFoo`` is replaced by ``Foo``.
|
||||
rule `{.deprecated: [TFoo: Foo].}` then `TFoo` is replaced by `Foo`.
|
||||
3. It can also check that your identifiers adhere to the official style guide
|
||||
and optionally modify them to do so (via ``--styleCheck:auto``).
|
||||
and optionally modify them to do so (via `--styleCheck:auto`).
|
||||
|
||||
Note that ``nimfix`` defaults to **overwrite** your code unless you
|
||||
use ``--overwriteFiles:off``! But hey, if you do not use a version control
|
||||
Note that `nimfix` defaults to **overwrite** your code unless you
|
||||
use `--overwriteFiles:off`! But hey, if you do not use a version control
|
||||
system by this day and age, your project is already in big trouble.
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
=========================
|
||||
nimgrep User's manual
|
||||
=========================
|
||||
@@ -22,7 +24,7 @@ Compile nimgrep with the command::
|
||||
|
||||
nim c -d:release tools/nimgrep.nim
|
||||
|
||||
And copy the executable somewhere in your ``$PATH``.
|
||||
And copy the executable somewhere in your `$PATH`.
|
||||
|
||||
|
||||
Command line switches
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
=========================
|
||||
niminst User's manual
|
||||
=========================
|
||||
@@ -31,8 +33,8 @@ configuration file. Here's an example of how the syntax looks like:
|
||||
:literal:
|
||||
|
||||
The value of a key-value pair can reference user-defined variables via
|
||||
the ``$variable`` notation: They can be defined in the command line with the
|
||||
``--var:name=value`` switch. This is useful to not hard-coding the
|
||||
the `$variable` notation: They can be defined in the command line with the
|
||||
`--var:name=value` switch. This is useful to not hard-coding the
|
||||
program's version number into the configuration file, for instance.
|
||||
|
||||
It follows a description of each possible section and how it affects the
|
||||
@@ -47,28 +49,28 @@ contain the following key-value pairs:
|
||||
==================== =======================================================
|
||||
Key description
|
||||
==================== =======================================================
|
||||
``Name`` the project's name; this needs to be a single word
|
||||
``DisplayName`` the project's long name; this can contain spaces. If
|
||||
not specified, this is the same as ``Name``.
|
||||
``Version`` the project's version
|
||||
``OS`` the OSes to generate C code for; for example:
|
||||
``"windows;linux;macosx"``
|
||||
``CPU`` the CPUs to generate C code for; for example:
|
||||
``"i386;amd64;powerpc"``
|
||||
``Authors`` the project's authors
|
||||
``Description`` the project's description
|
||||
``App`` the application's type: "Console" or "GUI". If
|
||||
`Name` the project's name; this needs to be a single word
|
||||
`DisplayName` the project's long name; this can contain spaces. If
|
||||
not specified, this is the same as `Name`.
|
||||
`Version` the project's version
|
||||
`OS` the OSes to generate C code for; for example:
|
||||
`"windows;linux;macosx"`
|
||||
`CPU` the CPUs to generate C code for; for example:
|
||||
`"i386;amd64;powerpc"`
|
||||
`Authors` the project's authors
|
||||
`Description` the project's description
|
||||
`App` the application's type: "Console" or "GUI". If
|
||||
"Console", niminst generates a special batch file
|
||||
for Windows to open up the command-line shell.
|
||||
``License`` the filename of the application's license
|
||||
`License` the filename of the application's license
|
||||
==================== =======================================================
|
||||
|
||||
|
||||
``files`` key
|
||||
`files` key
|
||||
-------------
|
||||
|
||||
Many sections support the ``files`` key. Listed filenames
|
||||
can be separated by semicolon or the ``files`` key can be repeated. Wildcards
|
||||
Many sections support the `files` key. Listed filenames
|
||||
can be separated by semicolon or the `files` key can be repeated. Wildcards
|
||||
in filenames are supported. If it is a directory name, all files in the
|
||||
directory are used::
|
||||
|
||||
@@ -80,63 +82,63 @@ directory are used::
|
||||
Config section
|
||||
--------------
|
||||
|
||||
The ``config`` section currently only supports the ``files`` key. Listed files
|
||||
The `config` section currently only supports the `files` key. Listed files
|
||||
will be installed into the OS's configuration directory.
|
||||
|
||||
|
||||
Documentation section
|
||||
---------------------
|
||||
|
||||
The ``documentation`` section supports the ``files`` key.
|
||||
The `documentation` section supports the `files` key.
|
||||
Listed files will be installed into the OS's native documentation directory
|
||||
(which might be ``$appdir/doc``).
|
||||
(which might be `$appdir/doc`).
|
||||
|
||||
There is a ``start`` key which determines whether the Windows installer
|
||||
generates a link to e.g. the ``index.html`` of your documentation.
|
||||
There is a `start` key which determines whether the Windows installer
|
||||
generates a link to e.g. the `index.html` of your documentation.
|
||||
|
||||
|
||||
Other section
|
||||
-------------
|
||||
|
||||
The ``other`` section currently only supports the ``files`` key.
|
||||
The `other` section currently only supports the `files` key.
|
||||
Listed files will be installed into the application installation directory
|
||||
(``$appdir``).
|
||||
(`$appdir`).
|
||||
|
||||
|
||||
Lib section
|
||||
-----------
|
||||
|
||||
The ``lib`` section currently only supports the ``files`` key.
|
||||
The `lib` section currently only supports the `files` key.
|
||||
Listed files will be installed into the OS's native library directory
|
||||
(which might be ``$appdir/lib``).
|
||||
(which might be `$appdir/lib`).
|
||||
|
||||
|
||||
Windows section
|
||||
---------------
|
||||
|
||||
The ``windows`` section supports the ``files`` key for Windows-specific files.
|
||||
The `windows` section supports the `files` key for Windows-specific files.
|
||||
Listed files will be installed into the application installation directory
|
||||
(``$appdir``).
|
||||
(`$appdir`).
|
||||
|
||||
Other possible options are:
|
||||
|
||||
==================== =======================================================
|
||||
Key description
|
||||
==================== =======================================================
|
||||
``BinPath`` paths to add to the Windows ``%PATH%`` environment
|
||||
`BinPath` paths to add to the Windows `%PATH%` environment
|
||||
variable. Example: ``BinPath: r"bin;dist\mingw\bin"``
|
||||
``InnoSetup`` boolean flag whether an Inno Setup installer should be
|
||||
generated for Windows. Example: ``InnoSetup: "Yes"``
|
||||
`InnoSetup` boolean flag whether an Inno Setup installer should be
|
||||
generated for Windows. Example: `InnoSetup: "Yes"`
|
||||
==================== =======================================================
|
||||
|
||||
|
||||
UnixBin section
|
||||
---------------
|
||||
|
||||
The ``UnixBin`` section currently only supports the ``files`` key.
|
||||
The `UnixBin` section currently only supports the `files` key.
|
||||
Listed files will be installed into the OS's native bin directory
|
||||
(e.g. ``/usr/local/bin``). The exact location depends on the
|
||||
installation path the user specifies when running the ``install.sh`` script.
|
||||
(e.g. `/usr/local/bin`). The exact location depends on the
|
||||
installation path the user specifies when running the `install.sh` script.
|
||||
|
||||
|
||||
Unix section
|
||||
@@ -147,11 +149,11 @@ Possible options are:
|
||||
==================== =======================================================
|
||||
Key description
|
||||
==================== =======================================================
|
||||
``InstallScript`` boolean flag whether an installation shell script
|
||||
should be generated. Example: ``InstallScript: "Yes"``
|
||||
``UninstallScript`` boolean flag whether a de-installation shell script
|
||||
`InstallScript` boolean flag whether an installation shell script
|
||||
should be generated. Example: `InstallScript: "Yes"`
|
||||
`UninstallScript` boolean flag whether a de-installation shell script
|
||||
should be generated.
|
||||
Example: ``UninstallScript: "Yes"``
|
||||
Example: `UninstallScript: "Yes"`
|
||||
==================== =======================================================
|
||||
|
||||
|
||||
@@ -163,10 +165,10 @@ Possible options are:
|
||||
==================== =======================================================
|
||||
Key description
|
||||
==================== =======================================================
|
||||
``path`` Path to Inno Setup.
|
||||
`path` Path to Inno Setup.
|
||||
Example: ``path = r"c:\inno setup 5\iscc.exe"``
|
||||
``flags`` Flags to pass to Inno Setup.
|
||||
Example: ``flags = "/Q"``
|
||||
`flags` Flags to pass to Inno Setup.
|
||||
Example: `flags = "/Q"`
|
||||
==================== =======================================================
|
||||
|
||||
|
||||
@@ -178,9 +180,9 @@ Possible options are:
|
||||
==================== =======================================================
|
||||
Key description
|
||||
==================== =======================================================
|
||||
``path`` Path to the C compiler.
|
||||
``flags`` Flags to pass to the C Compiler.
|
||||
Example: ``flags = "-w"``
|
||||
`path` Path to the C compiler.
|
||||
`flags` Flags to pass to the C Compiler.
|
||||
Example: `flags = "-w"`
|
||||
==================== =======================================================
|
||||
|
||||
|
||||
|
||||
78
doc/nims.rst
78
doc/nims.rst
@@ -1,30 +1,32 @@
|
||||
.. default-role:: code
|
||||
|
||||
================================
|
||||
NimScript
|
||||
================================
|
||||
|
||||
Strictly speaking, ``NimScript`` is the subset of Nim that can be evaluated
|
||||
Strictly speaking, `NimScript` is the subset of Nim that can be evaluated
|
||||
by Nim's builtin virtual machine (VM). This VM is used for Nim's compiletime
|
||||
function evaluation features.
|
||||
|
||||
The ``nim`` executable processes the ``.nims`` configuration files in
|
||||
The `nim` executable processes the `.nims` configuration files in
|
||||
the following directories (in this order; later files overwrite
|
||||
previous settings):
|
||||
|
||||
1) If environment variable ``XDG_CONFIG_HOME`` is defined,
|
||||
``$XDG_CONFIG_HOME/nim/config.nims`` or
|
||||
``~/.config/nim/config.nims`` (POSIX) or
|
||||
``%APPDATA%/nim/config.nims`` (Windows). This file can be skipped
|
||||
with the ``--skipUserCfg`` command line option.
|
||||
2) ``$parentDir/config.nims`` where ``$parentDir`` stands for any
|
||||
1) If environment variable `XDG_CONFIG_HOME` is defined,
|
||||
`$XDG_CONFIG_HOME/nim/config.nims` or
|
||||
`~/.config/nim/config.nims` (POSIX) or
|
||||
`%APPDATA%/nim/config.nims` (Windows). This file can be skipped
|
||||
with the `--skipUserCfg` command line option.
|
||||
2) `$parentDir/config.nims` where `$parentDir` stands for any
|
||||
parent directory of the project file's path. These files can be
|
||||
skipped with the ``--skipParentCfg`` command line option.
|
||||
3) ``$projectDir/config.nims`` where ``$projectDir`` stands for the
|
||||
project's path. This file can be skipped with the ``--skipProjCfg``
|
||||
skipped with the `--skipParentCfg` command line option.
|
||||
3) `$projectDir/config.nims` where `$projectDir` stands for the
|
||||
project's path. This file can be skipped with the `--skipProjCfg`
|
||||
command line option.
|
||||
4) A project can also have a project specific configuration file named
|
||||
``$project.nims`` that resides in the same directory as
|
||||
``$project.nim``. This file can be skipped with the same
|
||||
``--skipProjCfg`` command line option.
|
||||
`$project.nims` that resides in the same directory as
|
||||
`$project.nim`. This file can be skipped with the same
|
||||
`--skipProjCfg` command line option.
|
||||
|
||||
For available procs and implementation details see `nimscript <nimscript.html>`_.
|
||||
|
||||
@@ -36,13 +38,13 @@ NimScript is subject to some limitations caused by the implementation of the VM
|
||||
(virtual machine):
|
||||
|
||||
* Nim's FFI (foreign function interface) is not available in NimScript. This
|
||||
means that any stdlib module which relies on ``importc`` can not be used in
|
||||
means that any stdlib module which relies on `importc` can not be used in
|
||||
the VM.
|
||||
|
||||
* ``ptr`` operations are are hard to emulate with the symbolic representation
|
||||
* `ptr` operations are are hard to emulate with the symbolic representation
|
||||
the VM uses. They are available and tested extensively but there are bugs left.
|
||||
|
||||
* ``var T`` function arguments rely on ``ptr`` operations internally and might
|
||||
* `var T` function arguments rely on `ptr` operations internally and might
|
||||
also be problematic in some cases.
|
||||
|
||||
* More than one level of `ref` is generally not supported (for example, the type
|
||||
@@ -50,7 +52,7 @@ NimScript is subject to some limitations caused by the implementation of the VM
|
||||
|
||||
* Multimethods are not available.
|
||||
|
||||
* ``random.randomize()`` requires an ``int64`` explicitly passed as argument, you *must* pass a Seed integer.
|
||||
* `random.randomize()` requires an `int64` explicitly passed as argument, you *must* pass a Seed integer.
|
||||
|
||||
|
||||
Standard library modules
|
||||
@@ -109,11 +111,11 @@ See also:
|
||||
NimScript as a configuration file
|
||||
=================================
|
||||
|
||||
A command-line switch ``--FOO`` is written as ``switch("FOO")`` in
|
||||
NimScript. Similarly, command-line ``--FOO:VAL`` translates to
|
||||
``switch("FOO", "VAL")``.
|
||||
A command-line switch `--FOO` is written as `switch("FOO")` in
|
||||
NimScript. Similarly, command-line `--FOO:VAL` translates to
|
||||
`switch("FOO", "VAL")`.
|
||||
|
||||
Here are few examples of using the ``switch`` proc:
|
||||
Here are few examples of using the `switch` proc:
|
||||
|
||||
.. code-block:: nim
|
||||
# command-line: --opt:size
|
||||
@@ -123,7 +125,7 @@ Here are few examples of using the ``switch`` proc:
|
||||
# command-line: --forceBuild
|
||||
switch("forceBuild")
|
||||
|
||||
NimScripts also support ``--`` templates for convenience, which look
|
||||
NimScripts also support `--` templates for convenience, which look
|
||||
like command-line switches written as-is in the NimScript file. So the
|
||||
above example can be rewritten as:
|
||||
|
||||
@@ -133,17 +135,17 @@ above example can be rewritten as:
|
||||
--forceBuild
|
||||
|
||||
**Note**: In general, the *define* switches can also be set in
|
||||
NimScripts using ``switch`` or ``--``, as shown in above
|
||||
examples. Only the ``release`` define (``-d:release``) cannot be set
|
||||
NimScripts using `switch` or `--`, as shown in above
|
||||
examples. Only the `release` define (`-d:release`) cannot be set
|
||||
in NimScripts.
|
||||
|
||||
|
||||
NimScript as a build tool
|
||||
=========================
|
||||
|
||||
The ``task`` template that the ``system`` module defines allows a NimScript
|
||||
The `task` template that the `system` module defines allows a NimScript
|
||||
file to be used as a build tool. The following example defines a
|
||||
task ``build`` that is an alias for the ``c`` command:
|
||||
task `build` that is an alias for the `c` command:
|
||||
|
||||
.. code-block:: nim
|
||||
task build, "builds an example":
|
||||
@@ -155,11 +157,11 @@ In fact, as a convention the following tasks should be available:
|
||||
========= ===================================================
|
||||
Task Description
|
||||
========= ===================================================
|
||||
``help`` List all the available NimScript tasks along with their docstrings.
|
||||
``build`` Build the project with the required
|
||||
backend (``c``, ``cpp`` or ``js``).
|
||||
``tests`` Runs the tests belonging to the project.
|
||||
``bench`` Runs benchmarks belonging to the project.
|
||||
`help` List all the available NimScript tasks along with their docstrings.
|
||||
`build` Build the project with the required
|
||||
backend (`c`, `cpp` or `js`).
|
||||
`tests` Runs the tests belonging to the project.
|
||||
`bench` Runs benchmarks belonging to the project.
|
||||
========= ===================================================
|
||||
|
||||
|
||||
@@ -178,7 +180,7 @@ Standalone NimScript
|
||||
====================
|
||||
|
||||
NimScript can also be used directly as a portable replacement for Bash and
|
||||
Batch files. Use ``nim myscript.nims`` to run ``myscript.nims``. For example,
|
||||
Batch files. Use `nim myscript.nims` to run `myscript.nims`. For example,
|
||||
installation of Nimble could be accomplished with this simple script:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -196,8 +198,8 @@ installation of Nimble could be accomplished with this simple script:
|
||||
|
||||
mvFile "nimble" & $id & "/src/nimble".toExe, "bin/nimble".toExe
|
||||
|
||||
On Unix, you can also use the shebang ``#!/usr/bin/env nim``, as long as your filename
|
||||
ends with ``.nims``:
|
||||
On Unix, you can also use the shebang `#!/usr/bin/env nim`, as long as your filename
|
||||
ends with `.nims`:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
@@ -206,7 +208,7 @@ ends with ``.nims``:
|
||||
|
||||
echo "hello world"
|
||||
|
||||
Use ``#!/usr/bin/env -S nim --hints:off`` to disable hints.
|
||||
Use `#!/usr/bin/env -S nim --hints:off` to disable hints.
|
||||
|
||||
|
||||
Benefits
|
||||
@@ -268,7 +270,7 @@ Powerful Metaprogramming
|
||||
NimScript can use Nim's templates, macros, types, concepts, effect tracking system, and more,
|
||||
you can create modules that work on compiled Nim and also on interpreted NimScript.
|
||||
|
||||
``func`` will still check for side effects, ``debugEcho`` also works as expected,
|
||||
`func` will still check for side effects, `debugEcho` also works as expected,
|
||||
making it ideal for functional scripting metaprogramming.
|
||||
|
||||
This is an example of a third party module that uses macros and templates to
|
||||
@@ -315,7 +317,7 @@ See the following NimScript:
|
||||
echo CompileDate
|
||||
|
||||
|
||||
``likely()``, ``unlikely()``, ``static:`` and ``{.compiletime.}``
|
||||
`likely()`, `unlikely()`, `static:` and `{.compiletime.}`
|
||||
will produce no code at all when run on NimScript,
|
||||
but still no error nor warning is produced and the code just works.
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
================================
|
||||
Nim IDE Integration Guide
|
||||
================================
|
||||
@@ -11,8 +13,8 @@
|
||||
Nim differs from many other compilers in that it is really fast,
|
||||
and being so fast makes it suited to provide external queries for
|
||||
text editors about the source code being written. Through the
|
||||
``nimsuggest`` tool, any IDE
|
||||
can query a ``.nim`` source file and obtain useful information like
|
||||
`nimsuggest` tool, any IDE
|
||||
can query a `.nim` source file and obtain useful information like
|
||||
definition of symbols or suggestions for completion.
|
||||
|
||||
This document will guide you through the available options. If you
|
||||
@@ -33,50 +35,50 @@ Nimsuggest is part of Nim's core. Build it via::
|
||||
Nimsuggest invocation
|
||||
=====================
|
||||
|
||||
Run it via ``nimsuggest --stdin --debug myproject.nim``. Nimsuggest is a
|
||||
server that takes queries that are related to ``myproject``. There is some
|
||||
support so that you can throw random ``.nim`` files which are not part
|
||||
of ``myproject`` at Nimsuggest too, but usually the query refer to modules/files
|
||||
that are part of ``myproject``.
|
||||
Run it via `nimsuggest --stdin --debug myproject.nim`. Nimsuggest is a
|
||||
server that takes queries that are related to `myproject`. There is some
|
||||
support so that you can throw random `.nim` files which are not part
|
||||
of `myproject` at Nimsuggest too, but usually the query refer to modules/files
|
||||
that are part of `myproject`.
|
||||
|
||||
``--stdin`` means that Nimsuggest reads the query from ``stdin``. This is great
|
||||
`--stdin` means that Nimsuggest reads the query from `stdin`. This is great
|
||||
for testing things out and playing with it but for an editor communication
|
||||
via sockets is more reasonable so that is the default. It listens to port 6000
|
||||
by default.
|
||||
|
||||
Nimsuggest is basically a frontend for the nim compiler so ``--path`` flags and
|
||||
Nimsuggest is basically a frontend for the nim compiler so `--path` flags and
|
||||
`config files <https://nim-lang.org/docs/nimc.html#compiler-usage-configuration-files>`_
|
||||
can be used to specify additional dependencies like
|
||||
``nimsuggest --stdin --debug --path:"dependencies" myproject.nim``.
|
||||
`nimsuggest --stdin --debug --path:"dependencies" myproject.nim`.
|
||||
|
||||
|
||||
Specifying the location of the query
|
||||
------------------------------------
|
||||
|
||||
Nimsuggest then waits for queries to process. A query consists of a
|
||||
cryptic 3 letter "command" ``def`` or ``con`` or ``sug`` or ``use`` followed by
|
||||
cryptic 3 letter "command" `def` or `con` or `sug` or `use` followed by
|
||||
a location. A query location consists of:
|
||||
|
||||
|
||||
``file.nim``
|
||||
`file.nim`
|
||||
This is the name of the module or include file the query refers to.
|
||||
|
||||
``dirtyfile.nim``
|
||||
`dirtyfile.nim`
|
||||
This is optional.
|
||||
|
||||
The ``file`` parameter is enough for static analysis, but IDEs
|
||||
The `file` parameter is enough for static analysis, but IDEs
|
||||
tend to have *unsaved buffers* where the user may still be in
|
||||
the middle of typing a line. In such situations the IDE can
|
||||
save the current contents to a temporary file and then use the
|
||||
``dirtyfile.nim`` option to tell Nimsuggest that ``foobar.nim`` should
|
||||
be taken from ``temporary/foobar.nim``.
|
||||
`dirtyfile.nim` option to tell Nimsuggest that `foobar.nim` should
|
||||
be taken from `temporary/foobar.nim`.
|
||||
|
||||
|
||||
``line``
|
||||
`line`
|
||||
An integer with the line you are going to query. For the compiler
|
||||
lines start at **1**.
|
||||
|
||||
``col``
|
||||
`col`
|
||||
An integer with the column you are going to query. For the
|
||||
compiler columns start at **0**.
|
||||
|
||||
@@ -84,7 +86,7 @@ a location. A query location consists of:
|
||||
Definitions
|
||||
-----------
|
||||
|
||||
The ``def`` Nimsuggest command performs a query about the definition
|
||||
The `def` Nimsuggest command performs a query about the definition
|
||||
of a specific symbol. If available, Nimsuggest will answer with the
|
||||
type, source file, line/column information and other accessory data
|
||||
if available like a docstring. With this information an IDE can
|
||||
@@ -105,7 +107,7 @@ can't find any valid symbol matching the position of the query.
|
||||
Suggestions
|
||||
-----------
|
||||
|
||||
The ``sug`` Nimsuggest command performs a query about possible
|
||||
The `sug` Nimsuggest command performs a query about possible
|
||||
completion symbols at some point in the file.
|
||||
|
||||
The typical usage scenario for this option is to call it after the
|
||||
@@ -118,7 +120,7 @@ Nimsuggest will try to return the suggestions sorted first by scope
|
||||
Invocation context
|
||||
------------------
|
||||
|
||||
The ``con`` Nimsuggest command is very similar to the suggestions
|
||||
The `con` Nimsuggest command is very similar to the suggestions
|
||||
command, but instead of being used after the user has typed a dot
|
||||
character, this one is meant to be used after the user has typed
|
||||
an opening brace to start typing parameters.
|
||||
@@ -127,7 +129,7 @@ an opening brace to start typing parameters.
|
||||
Symbol usages
|
||||
-------------
|
||||
|
||||
The ``use`` Nimsuggest command lists all usages of the symbol at
|
||||
The `use` Nimsuggest command lists all usages of the symbol at
|
||||
a position. IDEs can use this to find all the places in the file
|
||||
where the symbol is used and offer the user to rename it in all
|
||||
places at the same time.
|
||||
@@ -145,15 +147,15 @@ Nimsuggest output is always returned on single lines separated by
|
||||
tab characters (``\t``). The values of each column are:
|
||||
|
||||
1. Three characters indicating the type of returned answer (e.g.
|
||||
``def`` for definition, ``sug`` for suggestion, etc).
|
||||
2. Type of the symbol. This can be ``skProc``, ``skLet``, and just
|
||||
about any of the enums defined in the module ``compiler/ast.nim``.
|
||||
`def` for definition, `sug` for suggestion, etc).
|
||||
2. Type of the symbol. This can be `skProc`, `skLet`, and just
|
||||
about any of the enums defined in the module `compiler/ast.nim`.
|
||||
3. Fully qualified path of the symbol. If you are querying a symbol
|
||||
defined in the ``proj.nim`` file, this would have the form
|
||||
``proj.symbolName``.
|
||||
defined in the `proj.nim` file, this would have the form
|
||||
`proj.symbolName`.
|
||||
4. Type/signature. For variables and enums this will contain the
|
||||
type of the symbol, for procs, methods and templates this will
|
||||
contain the full unique signature (e.g. ``proc (File)``).
|
||||
contain the full unique signature (e.g. `proc (File)`).
|
||||
5. Full path to the file containing the symbol.
|
||||
6. Line where the symbol is located in the file. Lines start to
|
||||
count at **1**.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
Testament is an advanced automatic unittests runner for Nim tests, is used for the development of Nim itself,
|
||||
offers process isolation for your tests, it can generate statistics about test cases,
|
||||
supports multiple targets (C, C++, ObjectiveC, JavaScript, etc),
|
||||
@@ -9,29 +11,29 @@ so can be useful to run your tests, even the most complex ones.
|
||||
Test files location
|
||||
===================
|
||||
|
||||
By default Testament looks for test files on ``"./tests/*.nim"``.
|
||||
You can overwrite this pattern glob using ``pattern <glob>``.
|
||||
By default Testament looks for test files on `"./tests/*.nim"`.
|
||||
You can overwrite this pattern glob using `pattern <glob>`.
|
||||
The default working directory path can be changed using
|
||||
``--directory:"folder/subfolder/"``.
|
||||
`--directory:"folder/subfolder/"`.
|
||||
|
||||
Testament uses the ``nim`` compiler on ``PATH``.
|
||||
You can change that using ``--nim:"folder/subfolder/nim"``.
|
||||
Running JavaScript tests with ``--targets:"js"`` requires a working NodeJS on
|
||||
``PATH``.
|
||||
Testament uses the `nim` compiler on `PATH`.
|
||||
You can change that using `--nim:"folder/subfolder/nim"`.
|
||||
Running JavaScript tests with `--targets:"js"` requires a working NodeJS on
|
||||
`PATH`.
|
||||
|
||||
|
||||
Options
|
||||
=======
|
||||
|
||||
* ``--print`` Also print results to the console
|
||||
* ``--simulate`` See what tests would be run but don't run them (for debugging)
|
||||
* ``--failing`` Only show failing/ignored tests
|
||||
* ``--targets:"c cpp js objc"`` Run tests for specified targets (default: all)
|
||||
* ``--nim:path`` Use a particular nim executable (default: ``$PATH/nim``)
|
||||
* ``--directory:dir`` Change to directory dir before reading the tests or doing anything else.
|
||||
* ``--colors:on|off`` Turn messages coloring on|off.
|
||||
* ``--backendLogging:on|off`` Disable or enable backend logging. By default turned on.
|
||||
* ``--skipFrom:file`` Read tests to skip from ``file`` - one test per line, # comments ignored
|
||||
* `--print` Also print results to the console
|
||||
* `--simulate` See what tests would be run but don't run them (for debugging)
|
||||
* `--failing` Only show failing/ignored tests
|
||||
* `--targets:"c cpp js objc"` Run tests for specified targets (default: all)
|
||||
* `--nim:path` Use a particular nim executable (default: `$PATH/nim`)
|
||||
* `--directory:dir` Change to directory dir before reading the tests or doing anything else.
|
||||
* `--colors:on|off` Turn messages coloring on|off.
|
||||
* `--backendLogging:on|off` Disable or enable backend logging. By default turned on.
|
||||
* `--skipFrom:file` Read tests to skip from `file` - one test per line, # comments ignored
|
||||
|
||||
|
||||
Running a single test
|
||||
@@ -68,7 +70,7 @@ To search for tests deeper in a directory, use
|
||||
HTML Reports
|
||||
============
|
||||
|
||||
Generate HTML Reports ``testresults.html`` from unittests,
|
||||
Generate HTML Reports `testresults.html` from unittests,
|
||||
you have to run at least 1 test *before* generating a report:
|
||||
|
||||
.. code::
|
||||
@@ -172,7 +174,7 @@ Example "template" **to edit** and write a Testament unittest:
|
||||
assert 42 == 42, "Assert error message"
|
||||
|
||||
|
||||
* As you can see the "Spec" is just a ``discard """ """``.
|
||||
* As you can see the "Spec" is just a `discard """ """`.
|
||||
* Spec has sane defaults, so you don't need to provide them all, any simple assert will work just fine.
|
||||
* `This is not the full spec of Testament, check the Testament Spec on GitHub, see parseSpec(). <https://github.com/nim-lang/Nim/blob/devel/testament/specs.nim#L238>`_
|
||||
* `Nim itself uses Testament, so there are plenty of test examples. <https://github.com/nim-lang/Nim/tree/devel/tests>`_
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
========================
|
||||
Tools available with Nim
|
||||
========================
|
||||
@@ -9,11 +11,11 @@ The standard distribution ships with the following tools:
|
||||
document explaining how it works.
|
||||
|
||||
- | `Documentation generator <docgen.html>`_
|
||||
| The builtin document generator ``nim doc`` generates HTML documentation
|
||||
from ``.nim`` source files.
|
||||
| The builtin document generator `nim doc` generates HTML documentation
|
||||
from `.nim` source files.
|
||||
|
||||
- | `Nimsuggest for IDE support <nimsuggest.html>`_
|
||||
| Through the ``nimsuggest`` tool, any IDE can query a ``.nim`` source file
|
||||
| Through the `nimsuggest` tool, any IDE can query a `.nim` source file
|
||||
and obtain useful information like the definition of symbols or suggestions for
|
||||
completion.
|
||||
|
||||
@@ -27,11 +29,11 @@ The standard distribution ships with the following tools:
|
||||
| Nim search and replace utility.
|
||||
|
||||
- | nimpretty
|
||||
| ``nimpretty`` is a Nim source code beautifier,
|
||||
| `nimpretty` is a Nim source code beautifier,
|
||||
to format code according to the official style guide.
|
||||
|
||||
- | `testament <https://nim-lang.github.io/Nim/testament.html>`_
|
||||
| ``testament`` is an advanced automatic *unittests runner* for Nim tests,
|
||||
| `testament` is an advanced automatic *unittests runner* for Nim tests,
|
||||
is used for the development of Nim itself, offers process isolation for your tests,
|
||||
it can generate statistics about test cases, supports multiple targets (C, JS, etc),
|
||||
`simulated Dry-Runs <https://en.wikipedia.org/wiki/Dry_run_(testing)>`_,
|
||||
|
||||
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)
|
||||
======================
|
||||
@@ -24,7 +26,7 @@ Pragmas
|
||||
|
||||
Pragmas are Nim's method to give the compiler additional information/
|
||||
commands without introducing a massive number of new keywords. Pragmas are
|
||||
enclosed in the special ``{.`` and ``.}`` curly dot brackets. This tutorial
|
||||
enclosed in the special `{.` and `.}` curly dot brackets. This tutorial
|
||||
does not cover pragmas. See the `manual <manual.html#pragmas>`_ or `user guide
|
||||
<nimc.html#additional-features>`_ for a description of the available
|
||||
pragmas.
|
||||
@@ -45,11 +47,11 @@ Inheritance
|
||||
|
||||
Inheritance in Nim is entirely optional. To enable inheritance with
|
||||
runtime type information the object needs to inherit from
|
||||
``RootObj``. This can be done directly, or indirectly by
|
||||
inheriting from an object that inherits from ``RootObj``. Usually
|
||||
types with inheritance are also marked as ``ref`` types even though
|
||||
`RootObj`. This can be done directly, or indirectly by
|
||||
inheriting from an object that inherits from `RootObj`. Usually
|
||||
types with inheritance are also marked as `ref` types even though
|
||||
this isn't strictly enforced. To check at runtime if an object is of a certain
|
||||
type, the ``of`` operator can be used.
|
||||
type, the `of` operator can be used.
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
@@ -69,16 +71,16 @@ type, the ``of`` operator can be used.
|
||||
student = Student(name: "Anton", age: 5, id: 2)
|
||||
echo student[]
|
||||
|
||||
Inheritance is done with the ``object of`` syntax. Multiple inheritance is
|
||||
currently not supported. If an object type has no suitable ancestor, ``RootObj``
|
||||
Inheritance is done with the `object of` syntax. Multiple inheritance is
|
||||
currently not supported. If an object type has no suitable ancestor, `RootObj`
|
||||
can be used as its ancestor, but this is only a convention. Objects that have
|
||||
no ancestor are implicitly ``final``. You can use the ``inheritable`` pragma
|
||||
to introduce new object roots apart from ``system.RootObj``. (This is used
|
||||
no ancestor are implicitly `final`. You can use the `inheritable` pragma
|
||||
to introduce new object roots apart from `system.RootObj`. (This is used
|
||||
in the GTK wrapper for instance.)
|
||||
|
||||
Ref objects should be used whenever inheritance is used. It isn't strictly
|
||||
necessary, but with non-ref objects assignments such as ``let person: Person =
|
||||
Student(id: 123)`` will truncate subclass fields.
|
||||
necessary, but with non-ref objects assignments such as `let person: Person =
|
||||
Student(id: 123)` will truncate subclass fields.
|
||||
|
||||
**Note**: Composition (*has-a* relation) is often preferable to inheritance
|
||||
(*is-a* relation) for simple code reuse. Since objects are value types in
|
||||
@@ -111,7 +113,7 @@ Example:
|
||||
Type conversions
|
||||
----------------
|
||||
Nim distinguishes between `type casts`:idx: and `type conversions`:idx:.
|
||||
Casts are done with the ``cast`` operator and force the compiler to
|
||||
Casts are done with the `cast` operator and force the compiler to
|
||||
interpret a bit pattern to be of another type.
|
||||
|
||||
Type conversions are a much more polite way to convert a type into another:
|
||||
@@ -119,15 +121,15 @@ They preserve the abstract *value*, not necessarily the *bit-pattern*. If a
|
||||
type conversion is not possible, the compiler complains or an exception is
|
||||
raised.
|
||||
|
||||
The syntax for type conversions is ``destination_type(expression_to_convert)``
|
||||
The syntax for type conversions is `destination_type(expression_to_convert)`
|
||||
(like an ordinary call):
|
||||
|
||||
.. code-block:: nim
|
||||
proc getID(x: Person): int =
|
||||
Student(x).id
|
||||
|
||||
The ``InvalidObjectConversionDefect`` exception is raised if ``x`` is not a
|
||||
``Student``.
|
||||
The `InvalidObjectConversionDefect` exception is raised if `x` is not a
|
||||
`Student`.
|
||||
|
||||
|
||||
Object variants
|
||||
@@ -150,7 +152,7 @@ An example:
|
||||
nkSub, # a subtraction
|
||||
nkIf # an if statement
|
||||
Node = ref object
|
||||
case kind: NodeKind # the ``kind`` field is the discriminator
|
||||
case kind: NodeKind # the `kind` field is the discriminator
|
||||
of nkInt: intVal: int
|
||||
of nkFloat: floatVal: float
|
||||
of nkString: strVal: string
|
||||
@@ -173,9 +175,9 @@ Method call syntax
|
||||
------------------
|
||||
|
||||
There is a syntactic sugar for calling routines:
|
||||
The syntax ``obj.method(args)`` can be used instead of ``method(obj, args)``.
|
||||
The syntax `obj.method(args)` can be used instead of `method(obj, args)`.
|
||||
If there are no remaining arguments, the parentheses can be omitted:
|
||||
``obj.len`` (instead of ``len(obj)``).
|
||||
`obj.len` (instead of `len(obj)`).
|
||||
|
||||
This method call syntax is not restricted to objects, it can be used
|
||||
for any type:
|
||||
@@ -229,10 +231,10 @@ is needed:
|
||||
new s
|
||||
s.host = 34 # same as `host=`(s, 34)
|
||||
|
||||
(The example also shows ``inline`` procedures.)
|
||||
(The example also shows `inline` procedures.)
|
||||
|
||||
|
||||
The ``[]`` array access operator can be overloaded to provide
|
||||
The `[]` array access operator can be overloaded to provide
|
||||
`array properties`:idx:\ :
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -258,14 +260,14 @@ The ``[]`` array access operator can be overloaded to provide
|
||||
else: assert(false)
|
||||
|
||||
The example is silly, since a vector is better modelled by a tuple which
|
||||
already provides ``v[]`` access.
|
||||
already provides `v[]` access.
|
||||
|
||||
|
||||
Dynamic dispatch
|
||||
----------------
|
||||
|
||||
Procedures always use static dispatch. For dynamic dispatch replace the
|
||||
``proc`` keyword by ``method``:
|
||||
`proc` keyword by `method`:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
@@ -289,12 +291,12 @@ Procedures always use static dispatch. For dynamic dispatch replace the
|
||||
|
||||
echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4)))
|
||||
|
||||
Note that in the example the constructors ``newLit`` and ``newPlus`` are procs
|
||||
because it makes more sense for them to use static binding, but ``eval`` is a
|
||||
Note that in the example the constructors `newLit` and `newPlus` are procs
|
||||
because it makes more sense for them to use static binding, but `eval` is a
|
||||
method because it requires dynamic binding.
|
||||
|
||||
**Note:** Starting from Nim 0.20, to use multi-methods one must explicitly pass
|
||||
``--multimethods:on`` when compiling.
|
||||
`--multimethods:on` when compiling.
|
||||
|
||||
In a multi-method all parameters that have an object type are used for the
|
||||
dispatching:
|
||||
@@ -324,7 +326,7 @@ dispatching:
|
||||
|
||||
As the example demonstrates, invocation of a multi-method cannot be ambiguous:
|
||||
Collide 2 is preferred over collide 1 because the resolution works from left to
|
||||
right. Thus ``Unit, Thing`` is preferred over ``Thing, Unit``.
|
||||
right. Thus `Unit, Thing` is preferred over `Thing, Unit`.
|
||||
|
||||
**Performance note**: Nim does not produce a virtual method table, but
|
||||
generates dispatch trees. This avoids the expensive indirect branch for method
|
||||
@@ -338,19 +340,19 @@ Exceptions
|
||||
In Nim exceptions are objects. By convention, exception types are
|
||||
suffixed with 'Error'. The `system <system.html>`_ module defines an
|
||||
exception hierarchy that you might want to stick to. Exceptions derive from
|
||||
``system.Exception``, which provides the common interface.
|
||||
`system.Exception`, which provides the common interface.
|
||||
|
||||
Exceptions have to be allocated on the heap because their lifetime is unknown.
|
||||
The compiler will prevent you from raising an exception created on the stack.
|
||||
All raised exceptions should at least specify the reason for being raised in
|
||||
the ``msg`` field.
|
||||
the `msg` field.
|
||||
|
||||
A convention is that exceptions should be raised in *exceptional* cases,
|
||||
they should not be used as an alternative method of control flow.
|
||||
|
||||
Raise statement
|
||||
---------------
|
||||
Raising an exception is done with the ``raise`` statement:
|
||||
Raising an exception is done with the `raise` statement:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
@@ -360,9 +362,9 @@ Raising an exception is done with the ``raise`` statement:
|
||||
e.msg = "the request to the OS failed"
|
||||
raise e
|
||||
|
||||
If the ``raise`` keyword is not followed by an expression, the last exception
|
||||
If the `raise` keyword is not followed by an expression, the last exception
|
||||
is *re-raised*. For the purpose of avoiding repeating this common code pattern,
|
||||
the template ``newException`` in the ``system`` module can be used:
|
||||
the template `newException` in the `system` module can be used:
|
||||
|
||||
.. code-block:: nim
|
||||
raise newException(OSError, "the request to the OS failed")
|
||||
@@ -371,7 +373,7 @@ the template ``newException`` in the ``system`` module can be used:
|
||||
Try statement
|
||||
-------------
|
||||
|
||||
The ``try`` statement handles exceptions:
|
||||
The `try` statement handles exceptions:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
@@ -399,23 +401,23 @@ The ``try`` statement handles exceptions:
|
||||
finally:
|
||||
close(f)
|
||||
|
||||
The statements after the ``try`` are executed unless an exception is
|
||||
raised. Then the appropriate ``except`` part is executed.
|
||||
The statements after the `try` are executed unless an exception is
|
||||
raised. Then the appropriate `except` part is executed.
|
||||
|
||||
The empty ``except`` part is executed if there is an exception that is
|
||||
not explicitly listed. It is similar to an ``else`` part in ``if``
|
||||
The empty `except` part is executed if there is an exception that is
|
||||
not explicitly listed. It is similar to an `else` part in `if`
|
||||
statements.
|
||||
|
||||
If there is a ``finally`` part, it is always executed after the
|
||||
If there is a `finally` part, it is always executed after the
|
||||
exception handlers.
|
||||
|
||||
The exception is *consumed* in an ``except`` part. If an exception is not
|
||||
The exception is *consumed* in an `except` part. If an exception is not
|
||||
handled, it is propagated through the call stack. This means that often
|
||||
the rest of the procedure - that is not within a ``finally`` clause -
|
||||
the rest of the procedure - that is not within a `finally` clause -
|
||||
is not executed (if an exception occurs).
|
||||
|
||||
If you need to *access* the actual exception object or message inside an
|
||||
``except`` branch you can use the `getCurrentException()
|
||||
`except` branch you can use the `getCurrentException()
|
||||
<system.html#getCurrentException>`_ and `getCurrentExceptionMsg()
|
||||
<system.html#getCurrentExceptionMsg>`_ procs from the `system <system.html>`_
|
||||
module. Example:
|
||||
@@ -433,10 +435,10 @@ module. Example:
|
||||
Annotating procs with raised exceptions
|
||||
---------------------------------------
|
||||
|
||||
Through the use of the optional ``{.raises.}`` pragma you can specify that a
|
||||
Through the use of the optional `{.raises.}` pragma you can specify that a
|
||||
proc is meant to raise a specific set of exceptions, or none at all. If the
|
||||
``{.raises.}`` pragma is used, the compiler will verify that this is true. For
|
||||
instance, if you specify that a proc raises ``IOError``, and at some point it
|
||||
`{.raises.}` pragma is used, the compiler will verify that this is true. For
|
||||
instance, if you specify that a proc raises `IOError`, and at some point it
|
||||
(or one of the procs it calls) starts raising a new exception the compiler will
|
||||
prevent that proc from compiling. Usage example:
|
||||
|
||||
@@ -453,11 +455,11 @@ stopped validating the pragma and the raised exception not being caught, along
|
||||
with the file and line where the uncaught exception is being raised, which may
|
||||
help you locate the offending code which has changed.
|
||||
|
||||
If you want to add the ``{.raises.}`` pragma to existing code, the compiler can
|
||||
also help you. You can add the ``{.effects.}`` pragma statement to your proc and
|
||||
If you want to add the `{.raises.}` pragma to existing code, the compiler can
|
||||
also help you. You can add the `{.effects.}` pragma statement to your proc and
|
||||
the compiler will output all inferred effects up to that point (exception
|
||||
tracking is part of Nim's effect system). Another more roundabout way to
|
||||
find out the list of exceptions raised by a proc is to use the Nim ``doc``
|
||||
find out the list of exceptions raised by a proc is to use the Nim `doc`
|
||||
command which generates documentation for a whole module and decorates all
|
||||
procs with the list of raised exceptions. You can read more about Nim's
|
||||
`effect system and related pragmas in the manual <manual.html#effect-system>`_.
|
||||
@@ -468,14 +470,14 @@ Generics
|
||||
|
||||
Generics are Nim's means to parametrize procs, iterators or types
|
||||
with `type parameters`:idx:. Generic parameters are written within square
|
||||
brackets, for example ``Foo[T]``. They are most useful for efficient type safe
|
||||
brackets, for example `Foo[T]`. They are most useful for efficient type safe
|
||||
containers:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
type
|
||||
BinaryTree*[T] = ref object # BinaryTree is a generic type with
|
||||
# generic param ``T``
|
||||
# generic param `T`
|
||||
le, ri: BinaryTree[T] # left and right subtrees; may be nil
|
||||
data: T # the data stored in a node
|
||||
|
||||
@@ -491,8 +493,8 @@ containers:
|
||||
else:
|
||||
var it = root
|
||||
while it != nil:
|
||||
# compare the data items; uses the generic ``cmp`` proc
|
||||
# that works for any type that has a ``==`` and ``<`` operator
|
||||
# compare the data items; uses the generic `cmp` proc
|
||||
# that works for any type that has a `==` and `<` operator
|
||||
var c = cmp(it.data, n.data)
|
||||
if c < 0:
|
||||
if it.le == nil:
|
||||
@@ -522,19 +524,19 @@ containers:
|
||||
n = n.le # and follow the left pointer
|
||||
|
||||
var
|
||||
root: BinaryTree[string] # instantiate a BinaryTree with ``string``
|
||||
add(root, newNode("hello")) # instantiates ``newNode`` and ``add``
|
||||
add(root, "world") # instantiates the second ``add`` proc
|
||||
root: BinaryTree[string] # instantiate a BinaryTree with `string`
|
||||
add(root, newNode("hello")) # instantiates `newNode` and `add`
|
||||
add(root, "world") # instantiates the second `add` proc
|
||||
for str in preorder(root):
|
||||
stdout.writeLine(str)
|
||||
|
||||
The example shows a generic binary tree. Depending on context, the brackets are
|
||||
used either to introduce type parameters or to instantiate a generic proc,
|
||||
iterator or type. As the example shows, generics work with overloading: the
|
||||
best match of ``add`` is used. The built-in ``add`` procedure for sequences
|
||||
is not hidden and is used in the ``preorder`` iterator.
|
||||
best match of `add` is used. The built-in `add` procedure for sequences
|
||||
is not hidden and is used in the `preorder` iterator.
|
||||
|
||||
There is a special ``[:T]`` syntax when using generics with the method call syntax:
|
||||
There is a special `[:T]` syntax when using generics with the method call syntax:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
@@ -567,14 +569,14 @@ Example:
|
||||
|
||||
assert(5 != 6) # the compiler rewrites that to: assert(not (5 == 6))
|
||||
|
||||
The ``!=``, ``>``, ``>=``, ``in``, ``notin``, ``isnot`` operators are in fact
|
||||
templates: this has the benefit that if you overload the ``==`` operator,
|
||||
the ``!=`` operator is available automatically and does the right thing. (Except
|
||||
The `!=`, `>`, `>=`, `in`, `notin`, `isnot` operators are in fact
|
||||
templates: this has the benefit that if you overload the `==` operator,
|
||||
the `!=` operator is available automatically and does the right thing. (Except
|
||||
for IEEE floating point numbers - NaN breaks basic boolean logic.)
|
||||
|
||||
``a > b`` is transformed into ``b < a``.
|
||||
``a in b`` is transformed into ``contains(b, a)``.
|
||||
``notin`` and ``isnot`` have the obvious meanings.
|
||||
`a > b` is transformed into `b < a`.
|
||||
`a in b` is transformed into `contains(b, a)`.
|
||||
`notin` and `isnot` have the obvious meanings.
|
||||
|
||||
Templates are especially useful for lazy evaluation purposes. Consider a
|
||||
simple proc for logging:
|
||||
@@ -591,11 +593,11 @@ simple proc for logging:
|
||||
x = 4
|
||||
log("x has the value: " & $x)
|
||||
|
||||
This code has a shortcoming: if ``debug`` is set to false someday, the quite
|
||||
expensive ``$`` and ``&`` operations are still performed! (The argument
|
||||
This code has a shortcoming: if `debug` is set to false someday, the quite
|
||||
expensive `$` and `&` operations are still performed! (The argument
|
||||
evaluation for procedures is *eager*).
|
||||
|
||||
Turning the ``log`` proc into a template solves this problem:
|
||||
Turning the `log` proc into a template solves this problem:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
@@ -609,15 +611,15 @@ Turning the ``log`` proc into a template solves this problem:
|
||||
x = 4
|
||||
log("x has the value: " & $x)
|
||||
|
||||
The parameters' types can be ordinary types or the meta types ``untyped``,
|
||||
``typed``, or ``type``. ``type`` suggests that only a type symbol may be given
|
||||
as an argument, and ``untyped`` means symbol lookups and type resolution is not
|
||||
The parameters' types can be ordinary types or the meta types `untyped`,
|
||||
`typed`, or `type`. `type` suggests that only a type symbol may be given
|
||||
as an argument, and `untyped` means symbol lookups and type resolution is not
|
||||
performed before the expression is passed to the template.
|
||||
|
||||
If the template has no explicit return type,
|
||||
``void`` is used for consistency with procs and methods.
|
||||
`void` is used for consistency with procs and methods.
|
||||
|
||||
To pass a block of statements to a template, use ``untyped`` for the last parameter:
|
||||
To pass a block of statements to a template, use `untyped` for the last parameter:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
@@ -638,10 +640,10 @@ To pass a block of statements to a template, use ``untyped`` for the last parame
|
||||
txt.writeLine("line 1")
|
||||
txt.writeLine("line 2")
|
||||
|
||||
In the example the two ``writeLine`` statements are bound to the ``body``
|
||||
parameter. The ``withFile`` template contains boilerplate code and helps to
|
||||
In the example the two `writeLine` statements are bound to the `body`
|
||||
parameter. The `withFile` template contains boilerplate code and helps to
|
||||
avoid a common bug: to forget to close the file. Note how the
|
||||
``let fn = filename`` statement ensures that ``filename`` is evaluated only
|
||||
`let fn = filename` statement ensures that `filename` is evaluated only
|
||||
once.
|
||||
|
||||
Example: Lifting Procs
|
||||
@@ -653,7 +655,7 @@ Example: Lifting Procs
|
||||
|
||||
template liftScalarProc(fname) =
|
||||
## Lift a proc taking one scalar parameter and returning a
|
||||
## scalar value (eg ``proc sssss[T](x: T): float``),
|
||||
## scalar value (eg `proc sssss[T](x: T): float`),
|
||||
## to provide templated procs that can handle a single
|
||||
## parameter of seq[T] or nested seq[seq[]] or the same type
|
||||
##
|
||||
@@ -675,15 +677,15 @@ Compilation to JavaScript
|
||||
|
||||
Nim code can be compiled to JavaScript. However in order to write
|
||||
JavaScript-compatible code you should remember the following:
|
||||
- ``addr`` and ``ptr`` have slightly different semantic meaning in JavaScript.
|
||||
- `addr` and `ptr` have slightly different semantic meaning in JavaScript.
|
||||
It is recommended to avoid those if you're not sure how they are translated
|
||||
to JavaScript.
|
||||
- ``cast[T](x)`` in JavaScript is translated to ``(x)``, except for casting
|
||||
- `cast[T](x)` in JavaScript is translated to `(x)`, except for casting
|
||||
between signed/unsigned ints, in which case it behaves as static cast in
|
||||
C language.
|
||||
- ``cstring`` in JavaScript means JavaScript string. It is a good practice to
|
||||
use ``cstring`` only when it is semantically appropriate. E.g. don't use
|
||||
``cstring`` as a binary data buffer.
|
||||
- `cstring` in JavaScript means JavaScript string. It is a good practice to
|
||||
use `cstring` only when it is semantically appropriate. E.g. don't use
|
||||
`cstring` as a binary data buffer.
|
||||
|
||||
|
||||
Part 3
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
=======================
|
||||
Nim Tutorial (Part III)
|
||||
=======================
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. default-role:: code
|
||||
|
||||
The System module imports several separate modules, and their documentation
|
||||
is in separate files:
|
||||
|
||||
@@ -36,7 +38,7 @@ Proc Usage
|
||||
* `strutils module <strutils.html>`_ for common string functions
|
||||
* `strformat module <strformat.html>`_ for string interpolation and formatting
|
||||
* `unicode module <unicode.html>`_ for Unicode UTF-8 handling
|
||||
* `strscans <strscans.html>`_ for ``scanf`` and ``scanp`` macros, which offer
|
||||
* `strscans <strscans.html>`_ for `scanf` and `scanp` macros, which offer
|
||||
easier substring extraction than regular expressions
|
||||
* `strtabs module <strtabs.html>`_ for efficient hash tables
|
||||
(dictionaries, in some programming languages) mapping from strings to strings
|
||||
|
||||
Reference in New Issue
Block a user