diff options
author | quantimnot <54247259+quantimnot@users.noreply.github.com> | 2021-03-18 23:37:55 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-18 20:37:55 -0700 |
commit | 83ae70cb540661934b263d38f0a3864a982c0681 (patch) | |
tree | 2c7dab75410062ad06a0b6f40bee41e3f0bb3cff /doc | |
parent | 15586c7a7a54f9d573eed9ec4ec90994e1e0c483 (diff) | |
download | Nim-83ae70cb540661934b263d38f0a3864a982c0681.tar.gz |
RST backtick refactor (all *.rst except manual.rst and rst_examples.rst) (#17258)
Co-authored-by: quantimnot <quantimnot@users.noreply.github.com>
Diffstat (limited to 'doc')
-rw-r--r-- | doc/apis.rst | 30 | ||||
-rw-r--r-- | doc/backends.rst | 114 | ||||
-rw-r--r-- | doc/destructors.rst | 197 | ||||
-rw-r--r-- | doc/docgen.rst | 100 | ||||
-rw-r--r-- | doc/docstyle.rst | 20 | ||||
-rw-r--r-- | doc/drnim.rst | 52 | ||||
-rw-r--r-- | doc/estp.rst | 24 | ||||
-rw-r--r-- | doc/filters.rst | 46 | ||||
-rw-r--r-- | doc/gc.rst | 92 | ||||
-rw-r--r-- | doc/hcr.rst | 28 | ||||
-rw-r--r-- | doc/idetools.rst | 76 | ||||
-rw-r--r-- | doc/intern.rst | 138 | ||||
-rw-r--r-- | doc/koch.rst | 24 | ||||
-rw-r--r-- | doc/lib.rst | 68 | ||||
-rw-r--r-- | doc/manual/var_t_return.rst | 12 | ||||
-rw-r--r-- | doc/manual_experimental.rst | 514 | ||||
-rw-r--r-- | doc/manual_experimental_strictnotnil.rst | 89 | ||||
-rw-r--r-- | doc/nep1.rst | 42 | ||||
-rw-r--r-- | doc/nimc.rst | 222 | ||||
-rw-r--r-- | doc/nimfix.rst | 10 | ||||
-rw-r--r-- | doc/nimgrep.rst | 4 | ||||
-rw-r--r-- | doc/niminst.rst | 90 | ||||
-rw-r--r-- | doc/nims.rst | 78 | ||||
-rw-r--r-- | doc/nimsuggest.rst | 58 | ||||
-rw-r--r-- | doc/testament.rst | 38 | ||||
-rw-r--r-- | doc/tools.rst | 12 | ||||
-rw-r--r-- | doc/tut1.rst | 410 | ||||
-rw-r--r-- | doc/tut2.rst | 160 | ||||
-rw-r--r-- | doc/tut3.rst | 2 |
29 files changed, 1400 insertions, 1350 deletions
diff --git a/doc/apis.rst b/doc/apis.rst index 03374c2db..d01e75d78 100644 --- a/doc/apis.rst +++ b/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 diff --git a/doc/backends.rst b/doc/backends.rst index 070cadbfd..896b0f834 100644 --- a/doc/backends.rst +++ b/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. diff --git a/doc/destructors.rst b/doc/destructors.rst index 4f06de455..01e2d2ee9 100644 --- a/doc/destructors.rst +++ b/doc/destructors.rst @@ -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 - -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" -``` +.. 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" No matter how many times `moveMem` is called, the program compiles and runs. diff --git a/doc/docgen.rst b/doc/docgen.rst index e383bd8d0..c002ddb83 100644 --- a/doc/docgen.rst +++ b/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 diff --git a/doc/docstyle.rst b/doc/docstyle.rst index 090032b98..7f3fa8cf2 100644 --- a/doc/docstyle.rst +++ b/doc/docstyle.rst @@ -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 diff --git a/doc/drnim.rst b/doc/drnim.rst index ee6e0ea17..d33a6066e 100644 --- a/doc/drnim.rst +++ b/doc/drnim.rst @@ -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`. diff --git a/doc/estp.rst b/doc/estp.rst index 805a84eb7..8146562b6 100644 --- a/doc/estp.rst +++ b/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 diff --git a/doc/filters.rst b/doc/filters.rst index 40346ecaf..52704411f 100644 --- a/doc/filters.rst +++ b/doc/filters.rst @@ -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:: diff --git a/doc/gc.rst b/doc/gc.rst index 29b9a4131..4455afcbe 100644 --- a/doc/gc.rst +++ b/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. diff --git a/doc/hcr.rst b/doc/hcr.rst index 6dc65b1cd..7e9d71da3 100644 --- a/doc/hcr.rst +++ b/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 diff --git a/doc/idetools.rst b/doc/idetools.rst index 27926b14f..dcafaf45f 100644 --- a/doc/idetools.rst +++ b/doc/idetools.rst @@ -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. diff --git a/doc/intern.rst b/doc/intern.rst index 0eb70e143..2456b25fd 100644 --- a/doc/intern.rst +++ b/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: diff --git a/doc/koch.rst b/doc/koch.rst index c92e29812..1eb02d785 100644 --- a/doc/koch.rst +++ b/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 ----------- diff --git a/doc/lib.rst b/doc/lib.rst index 2a4c2c03c..3202c5a53 100644 --- a/doc/lib.rst +++ b/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. diff --git a/doc/manual/var_t_return.rst b/doc/manual/var_t_return.rst index c6de8cf7c..e34993e3e 100644 --- a/doc/manual/var_t_return.rst +++ b/doc/manual/var_t_return.rst @@ -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. diff --git a/doc/manual_experimental.rst b/doc/manual_experimental.rst index b76839842..cf2e0c247 100644 --- a/doc/manual_experimental.rst +++ b/doc/manual_experimental.rst @@ -1,3 +1,5 @@ +.. default-role:: code + ========================= Nim Experimental Features ========================= @@ -12,8 +14,8 @@ About this document =================== This document describes features of Nim that are to be considered experimental. -Some of these are not covered by the ``.experimental`` pragma or -``--experimental`` switch because they are already behind a special syntax and +Some of these are not covered by the `.experimental` pragma or +`--experimental` switch because they are already behind a special syntax and one may want to use Nim libraries using these features without using them oneself. @@ -28,13 +30,13 @@ Every Nim module resides in a (nimble) package. An object type can be attached to the package it resides in. If that is done, the type can be referenced from other modules as an `incomplete`:idx: object type. This feature allows to break up recursive type dependencies across module boundaries. Incomplete -object types are always passed ``byref`` and can only be used in pointer like -contexts (``var/ref/ptr IncompleteObject``) in general since the compiler does +object types are always passed `byref` and can only be used in pointer like +contexts (`var/ref/ptr IncompleteObject`) in general since the compiler does not yet know the size of the object. To complete an incomplete object -the ``package`` pragma has to be used. ``package`` implies ``byref``. +the `package` pragma has to be used. `package` implies `byref`. -As long as a type ``T`` is incomplete, neither ``sizeof(T)`` nor runtime -type information for ``T`` is available. +As long as a type `T` is incomplete, neither `sizeof(T)` nor runtime +type information for `T` is available. Example: @@ -63,8 +65,8 @@ Example: Void type ========= -The ``void`` type denotes the absence of any type. Parameters of -type ``void`` are treated as non-existent, ``void`` as a return type means that +The `void` type denotes the absence of any type. Parameters of +type `void` are treated as non-existent, `void` as a return type means that the procedure does not return a value: .. code-block:: nim @@ -73,7 +75,7 @@ the procedure does not return a value: nothing() # writes "ha" to stdout -The ``void`` type is particularly useful for generic code: +The `void` type is particularly useful for generic code: .. code-block:: nim proc callProc[T](p: proc (x: T), x: T) = @@ -88,7 +90,7 @@ The ``void`` type is particularly useful for generic code: callProc[int](intProc, 12) callProc[void](emptyProc) -However, a ``void`` type cannot be inferred in generic code: +However, a `void` type cannot be inferred in generic code: .. code-block:: nim callProc(emptyProc) @@ -96,8 +98,8 @@ However, a ``void`` type cannot be inferred in generic code: # but expected one of: # callProc(p: proc (T), x: T) -The ``void`` type is only valid for parameters and return types; other symbols -cannot have the type ``void``. +The `void` type is only valid for parameters and return types; other symbols +cannot have the type `void`. @@ -105,19 +107,19 @@ Covariance ========== Covariance in Nim can be introduced only through pointer-like types such -as ``ptr`` and ``ref``. Sequence, Array and OpenArray types, instantiated +as `ptr` and `ref`. Sequence, Array and OpenArray types, instantiated with pointer-like types will be considered covariant if and only if they -are also immutable. The introduction of a ``var`` modifier or additional -``ptr`` or ``ref`` indirections would result in invariant treatment of +are also immutable. The introduction of a `var` modifier or additional +`ptr` or `ref` indirections would result in invariant treatment of these types. -``proc`` types are currently always invariant, but future versions of Nim +`proc` types are currently always invariant, but future versions of Nim may relax this rule. User-defined generic types may also be covariant with respect to some of their parameters. By default, all generic params are considered invariant, -but you may choose the apply the prefix modifier ``in`` to a parameter to -make it contravariant or ``out`` to make it covariant: +but you may choose the apply the prefix modifier `in` to a parameter to +make it contravariant or `out` to make it covariant: .. code-block:: nim type @@ -166,10 +168,10 @@ values: # to point to a ComboBox On the other hand, in the `RingBuffer` example above, the designated generic -param is used to instantiate the non-pointer ``seq`` type, which means that +param is used to instantiate the non-pointer `seq` type, which means that the resulting generic type will have covariance that mimics an array or -sequence (i.e. it will be covariant only when instantiated with ``ptr`` and -``ref`` types): +sequence (i.e. it will be covariant only when instantiated with `ptr` and +`ref` types): .. code-block:: nim @@ -196,7 +198,7 @@ as `seq[AnnotatedPtr[T]]` or `RingBuffer[AnnotatedPtr[T]]` will also be considered covariant and you can create new pointer-like types by instantiating other user-defined pointer-like types. -The contravariant parameters introduced with the ``in`` modifier are currently +The contravariant parameters introduced with the `in` modifier are currently useful only when interfacing with imported types having such semantics. @@ -204,7 +206,7 @@ Automatic dereferencing ======================= Automatic dereferencing is performed for the first argument of a routine call. -This feature has to be enabled via ``{.experimental: "implicitDeref".}``: +This feature has to be enabled via `{.experimental: "implicitDeref".}`: .. code-block:: nim {.experimental: "implicitDeref".} @@ -257,7 +259,7 @@ preface definitions inside a module. Please note that if a callable symbol is never used in this scenario, its body will never be compiled. This is the default behavior leading to best compilation times, but if exhaustive compilation of all definitions is - required, using ``nim check`` provides this option as well. + required, using `nim check` provides this option as well. Example: @@ -290,10 +292,10 @@ what code is executed at the top level: .. TODO: Let's table this for now. This is an *experimental feature* and so the - specific manner in which ``declared`` operates with it can be decided in + specific manner in which `declared` operates with it can be decided in eventuality, because right now it works a bit weirdly. - The values of expressions involving ``declared`` are decided *before* the + The values of expressions involving `declared` are decided *before* the code reordering process, and not after. As an example, the output of this code is the same as it would be with code reordering disabled. @@ -325,7 +327,7 @@ Named argument overloading ========================== Routines with the same type signature can be called differently if a parameter -has different names. This does not need an ``experimental`` switch, but is an +has different names. This does not need an `experimental` switch, but is an unstable feature. .. code-block::nim @@ -344,7 +346,7 @@ Do notation =========== As a special more convenient notation, proc expressions involved in procedure -calls can use the ``do`` keyword: +calls can use the `do` keyword: .. code-block:: nim sort(cities) do (x,y: string) -> int: @@ -359,13 +361,13 @@ calls can use the ``do`` keyword: if not `ex`: echo `info`, ": Check failed: ", `expString` -``do`` is written after the parentheses enclosing the regular proc params. +`do` is written after the parentheses enclosing the regular proc params. The proc expression represented by the do block is appended to them. In calls using the command syntax, the do block will bind to the immediately preceding expression, transforming it in a call. -``do`` with parentheses is an anonymous ``proc``; however a ``do`` without -parentheses is just a block of code. The ``do`` notation can be used to +`do` with parentheses is an anonymous `proc`; however a `do` without +parentheses is just a block of code. The `do` notation can be used to pass multiple blocks to a macro: .. code-block:: nim @@ -385,7 +387,7 @@ dot operators ------------- **Note**: Dot operators are still experimental and so need to be enabled -via ``{.experimental: "dotOperators".}``. +via `{.experimental: "dotOperators".}`. Nim offers a special family of dot operators that can be used to intercept and rewrite proc call and field access attempts, referring @@ -398,7 +400,7 @@ When Nim encounters an expression that cannot be resolved by the standard overload resolution rules, the current scope will be searched for a dot operator that can be matched against a re-written form of the expression, where the unknown field or proc name is passed to -an ``untyped`` parameter: +an `untyped` parameter: .. code-block:: nim a.b # becomes `.`(a, b) @@ -471,10 +473,10 @@ Not nil annotation ================== **Note:** This is an experimental feature. It can be enabled with -``{.experimental: "notnil"}``. +`{.experimental: "notnil"}`. -All types for which ``nil`` is a valid value can be annotated with the ``not -nil`` annotation to exclude ``nil`` as a valid value: +All types for which `nil` is a valid value can be annotated with the `not +nil` annotation to exclude `nil` as a valid value: .. code-block:: nim {.experimental: "notnil"} @@ -526,9 +528,9 @@ The concept is a match if: a) all of the expressions within the body can be compiled for the tested type b) all statically evaluable boolean expressions in the body must be true -The identifiers following the ``concept`` keyword represent instances of the +The identifiers following the `concept` keyword represent instances of the currently matched type. You can apply any of the standard type modifiers such -as ``var``, ``ref``, ``ptr`` and ``static`` to denote a more specific type of +as `var`, `ref`, `ptr` and `static` to denote a more specific type of instance. You can also apply the `type` modifier to create a named instance of the type itself: @@ -546,9 +548,9 @@ the presence of callable symbols with specific signatures: OutputStream = concept var s s.write(string) -In order to check for symbols accepting ``type`` params, you must prefix -the type with the explicit ``type`` modifier. The named instance of the -type, following the ``concept`` keyword is also considered to have the +In order to check for symbols accepting `type` params, you must prefix +the type with the explicit `type` modifier. The named instance of the +type, following the `concept` keyword is also considered to have the explicit modifier and will be matched only as a type. .. code-block:: nim @@ -570,7 +572,7 @@ explicit modifier and will be matched only as a type. -x is T x - y is T -Please note that the ``is`` operator allows one to easily verify the precise +Please note that the `is` operator allows one to easily verify the precise type signatures of the required operations, but since type inference and default parameters are still applied in the concept body, it's also possible to describe usage protocols that do not reveal implementation details. @@ -586,7 +588,7 @@ By default, the compiler will report the matching errors in concepts only when no other overload can be selected and a normal compilation error is produced. When you need to understand why the compiler is not matching a particular concept and, as a result, a wrong overload is selected, you can apply the -``explain`` pragma to either the concept body or a particular call-site. +`explain` pragma to either the concept body or a particular call-site. .. code-block:: nim type @@ -670,7 +672,7 @@ resembles the way generic parameters of callable symbols are inferred on call sites. Unbound types can appear both as params to calls such as `s.push(T)` and -on the right-hand side of the ``is`` operator in cases such as `x.pop is T` +on the right-hand side of the `is` operator in cases such as `x.pop is T` and `x.data is seq[T]`. Unbound static params will be inferred from expressions involving the `==` @@ -684,8 +686,8 @@ operator and also when types dependent on them are being matched: The Nim compiler includes a simple linear equation solver, allowing it to infer static params in some situations where integer arithmetic is involved. -Just like in regular type classes, Nim discriminates between ``bind once`` -and ``bind many`` types when matching the concept. You can add the ``distinct`` +Just like in regular type classes, Nim discriminates between `bind once` +and `bind many` types when matching the concept. You can add the `distinct` modifier to any of the otherwise inferable types to get a type that will be matched without permanently inferring it. This may be useful when you need to match several procs accepting the same wide class of types: @@ -708,7 +710,7 @@ to match several procs accepting the same wide class of types: type Enum = distinct Enumerable o.baz is Enum -On the other hand, using ``bind once`` types allows you to test for equivalent +On the other hand, using `bind once` types allows you to test for equivalent types used in multiple signatures, without actually requiring any concrete types, thus allowing you to encode implementation-defined types: @@ -804,7 +806,7 @@ concept, we say that the outer concept is a refinement of the inner concept and thus it is more-specific. When both concepts are matched in a call during overload resolution, Nim will assign a higher precedence to the most specific one. As an alternative way of defining concept refinements, you can use the -object inheritance syntax involving the ``of`` keyword: +object inheritance syntax involving the `of` keyword: .. code-block:: nim type @@ -895,8 +897,8 @@ object inheritance syntax involving the ``of`` keyword: any type can implement an unlimited number of protocols or interfaces not originally envisioned by the type's author. - Any concept type can be turned into a VTable type by using the ``vtref`` - or the ``vtptr`` compiler magics. Under the hood, these magics generate + Any concept type can be turned into a VTable type by using the `vtref` + or the `vtptr` compiler magics. Under the hood, these magics generate a converter type class, which converts the regular instances of the matching types to the corresponding VTable type. @@ -928,8 +930,8 @@ object inheritance syntax involving the ``of`` keyword: but it will include a smaller number of captured procs. A completely empty vtable will be reported as an error. - The ``vtref`` magic produces types which can be bound to ``ref`` types and - the ``vtptr`` magic produced types bound to ``ptr`` types. + The `vtref` magic produces types which can be bound to `ref` types and + the `vtptr` magic produced types bound to `ptr` types. Type bound operations @@ -944,12 +946,12 @@ There are 4 operations that are bound to a type: These operations can be *overridden* instead of *overloaded*. This means the implementation is automatically lifted to structured types. For instance if type -``T`` has an overridden assignment operator ``=`` this operator is also used -for assignments of the type ``seq[T]``. Since these operations are bound to a +`T` has an overridden assignment operator `=` this operator is also used +for assignments of the type `seq[T]`. Since these operations are bound to a type they have to be bound to a nominal type for reasons of simplicity of -implementation: This means an overridden ``deepCopy`` for ``ref T`` is really -bound to ``T`` and not to ``ref T``. This also means that one cannot override -``deepCopy`` for both ``ptr T`` and ``ref T`` at the same time; instead a +implementation: This means an overridden `deepCopy` for `ref T` is really +bound to `T` and not to `ref T`. This also means that one cannot override +`deepCopy` for both `ptr T` and `ref T` at the same time; instead a helper distinct or object type has to be used for one pointer type. Assignments, moves and destruction are specified in @@ -959,9 +961,9 @@ the `destructors <destructors.html>`_ document. deepCopy -------- -``=deepCopy`` is a builtin that is invoked whenever data is passed to -a ``spawn``'ed proc to ensure memory safety. The programmer can override its -behaviour for a specific ``ref`` or ``ptr`` type ``T``. (Later versions of the +`=deepCopy` is a builtin that is invoked whenever data is passed to +a `spawn`'ed proc to ensure memory safety. The programmer can override its +behaviour for a specific `ref` or `ptr` type `T`. (Later versions of the language may weaken this restriction.) The signature has to be: @@ -972,7 +974,7 @@ The signature has to be: This mechanism will be used by most data structures that support shared memory like channels to implement thread safe automatic memory management. -The builtin ``deepCopy`` can even clone closures and their environments. See +The builtin `deepCopy` can even clone closures and their environments. See the documentation of `spawn <#parallel-amp-spawn-spawn-statement>`_ for details. @@ -982,7 +984,7 @@ Case statement macros Macros named `case` can rewrite `case` statements for certain types in order to implement `pattern matching`:idx:. The following example implements a simplistic form of pattern matching for tuples, leveraging the existing -equality operator for tuples (as provided in ``system.==``): +equality operator for tuples (as provided in `system.==`): .. code-block:: nim :test: "nim c $1" @@ -1013,7 +1015,7 @@ equality operator for tuples (as provided in ``system.==``): Currently case statement macros must be enabled explicitly -via ``{.experimental: "caseStmtMacros".}``. +via `{.experimental: "caseStmtMacros".}`. `case` macros are subject to overload resolution. The type of the `case` statement's selector expression is matched against the type @@ -1039,10 +1041,10 @@ compilation pipeline with user defined optimizations: let x = 3 echo x * 2 -The compiler now rewrites ``x * 2`` as ``x + x``. The code inside the -curlies is the pattern to match against. The operators ``*``, ``**``, -``|``, ``~`` have a special meaning in patterns if they are written in infix -notation, so to match verbatim against ``*`` the ordinary function call syntax +The compiler now rewrites `x * 2` as `x + x`. The code inside the +curlies is the pattern to match against. The operators `*`, `**`, +`|`, `~` have a special meaning in patterns if they are written in infix +notation, so to match verbatim against `*` the ordinary function call syntax needs to be used. Term rewriting macro are applied recursively, up to a limit. This means that @@ -1080,7 +1082,7 @@ You can make one overload matching with a constraint and one without, and the one with a constraint will have precedence, and so you can handle both cases differently. -So what about ``2 * a``? We should tell the compiler ``*`` is commutative. We +So what about `2 * a`? We should tell the compiler `*` is commutative. We cannot really do that however as the following code only swaps arguments blindly: @@ -1092,59 +1094,59 @@ What optimizers really need to do is a *canonicalization*: .. code-block:: nim template canonMul{`*`(a, b)}(a: int{lit}, b: int): int = b*a -The ``int{lit}`` parameter pattern matches against an expression of -type ``int``, but only if it's a literal. +The `int{lit}` parameter pattern matches against an expression of +type `int`, but only if it's a literal. Parameter constraints --------------------- -The `parameter constraint`:idx: expression can use the operators ``|`` (or), -``&`` (and) and ``~`` (not) and the following predicates: +The `parameter constraint`:idx: expression can use the operators `|` (or), +`&` (and) and `~` (not) and the following predicates: =================== ===================================================== Predicate Meaning =================== ===================================================== -``atom`` The matching node has no children. -``lit`` The matching node is a literal like "abc", 12. -``sym`` The matching node must be a symbol (a bound +`atom` The matching node has no children. +`lit` The matching node is a literal like "abc", 12. +`sym` The matching node must be a symbol (a bound identifier). -``ident`` The matching node must be an identifier (an unbound +`ident` The matching node must be an identifier (an unbound identifier). -``call`` The matching AST must be a call/apply expression. -``lvalue`` The matching AST must be an lvalue. -``sideeffect`` The matching AST must have a side effect. -``nosideeffect`` The matching AST must have no side effect. -``param`` A symbol which is a parameter. -``genericparam`` A symbol which is a generic parameter. -``module`` A symbol which is a module. -``type`` A symbol which is a type. -``var`` A symbol which is a variable. -``let`` A symbol which is a ``let`` variable. -``const`` A symbol which is a constant. -``result`` The special ``result`` variable. -``proc`` A symbol which is a proc. -``method`` A symbol which is a method. -``iterator`` A symbol which is an iterator. -``converter`` A symbol which is a converter. -``macro`` A symbol which is a macro. -``template`` A symbol which is a template. -``field`` A symbol which is a field in a tuple or an object. -``enumfield`` A symbol which is a field in an enumeration. -``forvar`` A for loop variable. -``label`` A label (used in ``block`` statements). -``nk*`` The matching AST must have the specified kind. - (Example: ``nkIfStmt`` denotes an ``if`` statement.) -``alias`` States that the marked parameter needs to alias +`call` The matching AST must be a call/apply expression. +`lvalue` The matching AST must be an lvalue. +`sideeffect` The matching AST must have a side effect. +`nosideeffect` The matching AST must have no side effect. +`param` A symbol which is a parameter. +`genericparam` A symbol which is a generic parameter. +`module` A symbol which is a module. +`type` A symbol which is a type. +`var` A symbol which is a variable. +`let` A symbol which is a `let` variable. +`const` A symbol which is a constant. +`result` The special `result` variable. +`proc` A symbol which is a proc. +`method` A symbol which is a method. +`iterator` A symbol which is an iterator. +`converter` A symbol which is a converter. +`macro` A symbol which is a macro. +`template` A symbol which is a template. +`field` A symbol which is a field in a tuple or an object. +`enumfield` A symbol which is a field in an enumeration. +`forvar` A for loop variable. +`label` A label (used in `block` statements). +`nk*` The matching AST must have the specified kind. + (Example: `nkIfStmt` denotes an `if` statement.) +`alias` States that the marked parameter needs to alias with *some* other parameter. -``noalias`` States that *every* other parameter must not alias +`noalias` States that *every* other parameter must not alias with the marked parameter. =================== ===================================================== Predicates that share their name with a keyword have to be escaped with backticks. -The ``alias`` and ``noalias`` predicates refer not only to the matching AST, +The `alias` and `noalias` predicates refer not only to the matching AST, but also to every other bound parameter; syntactically they need to occur after the ordinary AST predicates: @@ -1158,14 +1160,14 @@ the ordinary AST predicates: Pattern operators ----------------- -The operators ``*``, ``**``, ``|``, ``~`` have a special meaning in patterns +The operators `*`, `**`, `|`, `~` have a special meaning in patterns if they are written in infix notation. -The ``|`` operator +The `|` operator ~~~~~~~~~~~~~~~~~~ -The ``|`` operator if used as infix operator creates an ordered choice: +The `|` operator if used as infix operator creates an ordered choice: .. code-block:: nim template t{0|1}(): untyped = 3 @@ -1182,15 +1184,15 @@ constant folding, so the following does not work: echo 1 The reason is that the compiler already transformed the 1 into "1" for -the ``echo`` statement. However, a term rewriting macro should not change the -semantics anyway. In fact they can be deactivated with the ``--patterns:off`` -command line option or temporarily with the ``patterns`` pragma. +the `echo` statement. However, a term rewriting macro should not change the +semantics anyway. In fact they can be deactivated with the `--patterns:off` +command line option or temporarily with the `patterns` pragma. -The ``{}`` operator +The `{}` operator ~~~~~~~~~~~~~~~~~~~ -A pattern expression can be bound to a pattern parameter via the ``expr{param}`` +A pattern expression can be bound to a pattern parameter via the `expr{param}` notation: .. code-block:: nim @@ -1200,10 +1202,10 @@ notation: echo a -The ``~`` operator +The `~` operator ~~~~~~~~~~~~~~~~~~ -The ``~`` operator is the **not** operator in patterns: +The `~` operator is the **not** operator in patterns: .. code-block:: nim template t{x = (~x){y} and (~x){z}}(x, y, z: bool) = @@ -1218,11 +1220,11 @@ The ``~`` operator is the **not** operator in patterns: echo a -The ``*`` operator +The `*` operator ~~~~~~~~~~~~~~~~~~ -The ``*`` operator can *flatten* a nested binary expression like ``a & b & c`` -to ``&(a, b, c)``: +The `*` operator can *flatten* a nested binary expression like `a & b & c` +to `&(a, b, c)`: .. code-block:: nim var @@ -1243,19 +1245,19 @@ to ``&(a, b, c)``: The second operator of `*` must be a parameter; it is used to gather all the -arguments. The expression ``"my" && (space & "awe" && "some " ) && "concat"`` -is passed to ``optConc`` in ``a`` as a special list (of kind ``nkArgList``) -which is flattened into a call expression; thus the invocation of ``optConc`` +arguments. The expression `"my" && (space & "awe" && "some " ) && "concat"` +is passed to `optConc` in `a` as a special list (of kind `nkArgList`) +which is flattened into a call expression; thus the invocation of `optConc` produces: .. code-block:: nim `&&`("my", space & "awe", "some ", "concat") -The ``**`` operator +The `**` operator ~~~~~~~~~~~~~~~~~~~ -The ``**`` is much like the ``*`` operator, except that it gathers not only +The `**` is much like the `*` operator, except that it gathers not only all the arguments, but also the matched operators in reverse polish notation: .. code-block:: nim @@ -1280,8 +1282,8 @@ all the arguments, but also the matched operators in reverse polish notation: echo x + y * z - x -This passes the expression ``x + y * z - x`` to the ``optM`` macro as -an ``nnkArglist`` node containing:: +This passes the expression `x + y * z - x` to the `optM` macro as +an `nnkArglist` node containing:: Arglist Sym "x" @@ -1292,14 +1294,14 @@ an ``nnkArglist`` node containing:: Sym "x" Sym "-" -(Which is the reverse polish notation of ``x + y * z - x``.) +(Which is the reverse polish notation of `x + y * z - x`.) Parameters ---------- Parameters in a pattern are type checked in the matching process. If a -parameter is of the type ``varargs`` it is treated specially and it can match +parameter is of the type `varargs` it is treated specially and it can match 0 or more arguments in the AST to be matched against: .. code-block:: nim @@ -1341,9 +1343,9 @@ The following example shows how some form of hoisting can be implemented: echo match("(a b c)", peg"'(' @ ')'") echo match("W_HI_Le", peg"\y 'while'") -The ``optPeg`` template optimizes the case of a peg constructor with a string +The `optPeg` template optimizes the case of a peg constructor with a string literal, so that the pattern will only be parsed once at program startup and -stored in a global ``gl`` which is then re-used. This optimization is called +stored in a global `gl` which is then re-used. This optimization is called hoisting because it is comparable to classical loop hoisting. @@ -1369,7 +1371,7 @@ constraints affect ordinary overloading resolution then: optLit(constant) optLit(variable) -However, the constraints ``alias`` and ``noalias`` are not available in +However, the constraints `alias` and `noalias` are not available in ordinary routines. @@ -1377,26 +1379,26 @@ Parallel & Spawn ================ Nim has two flavors of parallelism: -1) `Structured`:idx: parallelism via the ``parallel`` statement. -2) `Unstructured`:idx: parallelism via the standalone ``spawn`` statement. +1) `Structured`:idx: parallelism via the `parallel` statement. +2) `Unstructured`:idx: parallelism via the standalone `spawn` statement. Nim has a builtin thread pool that can be used for CPU intensive tasks. For -IO intensive tasks the ``async`` and ``await`` features should be +IO intensive tasks the `async` and `await` features should be used instead. Both parallel and spawn need the `threadpool <threadpool.html>`_ module to work. -Somewhat confusingly, ``spawn`` is also used in the ``parallel`` statement -with slightly different semantics. ``spawn`` always takes a call expression of -the form ``f(a, ...)``. Let ``T`` be ``f``'s return type. If ``T`` is ``void`` -then ``spawn``'s return type is also ``void`` otherwise it is ``FlowVar[T]``. +Somewhat confusingly, `spawn` is also used in the `parallel` statement +with slightly different semantics. `spawn` always takes a call expression of +the form `f(a, ...)`. Let `T` be `f`'s return type. If `T` is `void` +then `spawn`'s return type is also `void` otherwise it is `FlowVar[T]`. -Within a ``parallel`` section sometimes the ``FlowVar[T]`` is eliminated -to ``T``. This happens when ``T`` does not contain any GC'ed memory. -The compiler can ensure the location in ``location = spawn f(...)`` is not -read prematurely within a ``parallel`` section and so there is no need for -the overhead of an indirection via ``FlowVar[T]`` to ensure correctness. +Within a `parallel` section sometimes the `FlowVar[T]` is eliminated +to `T`. This happens when `T` does not contain any GC'ed memory. +The compiler can ensure the location in `location = spawn f(...)` is not +read prematurely within a `parallel` section and so there is no need for +the overhead of an indirection via `FlowVar[T]` to ensure correctness. -**Note**: Currently exceptions are not propagated between ``spawn``'ed tasks! +**Note**: Currently exceptions are not propagated between `spawn`'ed tasks! Spawn statement @@ -1415,25 +1417,25 @@ Spawn statement sync() For reasons of type safety and implementation simplicity the expression -that ``spawn`` takes is restricted: +that `spawn` takes is restricted: -* It must be a call expression ``f(a, ...)``. -* ``f`` must be ``gcsafe``. -* ``f`` must not have the calling convention ``closure``. -* ``f``'s parameters may not be of type ``var``. - This means one has to use raw ``ptr``'s for data passing reminding the +* It must be a call expression `f(a, ...)`. +* `f` must be `gcsafe`. +* `f` must not have the calling convention `closure`. +* `f`'s parameters may not be of type `var`. + This means one has to use raw `ptr`'s for data passing reminding the programmer to be careful. -* ``ref`` parameters are deeply copied which is a subtle semantic change and +* `ref` parameters are deeply copied which is a subtle semantic change and can cause performance problems but ensures memory safety. This deep copy - is performed via ``system.deepCopy`` and so can be overridden. -* For *safe* data exchange between ``f`` and the caller a global ``TChannel`` + is performed via `system.deepCopy` and so can be overridden. +* For *safe* data exchange between `f` and the caller a global `TChannel` needs to be used. However, since spawn can return a result, often no further communication is required. -``spawn`` executes the passed expression on the thread pool and returns -a `data flow variable`:idx: ``FlowVar[T]`` that can be read from. The reading -with the ``^`` operator is **blocking**. However, one can use ``blockUntilAny`` to +`spawn` executes the passed expression on the thread pool and returns +a `data flow variable`:idx: `FlowVar[T]` that can be read from. The reading +with the `^` operator is **blocking**. However, one can use `blockUntilAny` to wait on multiple flow variables at the same time: .. code-block:: nim @@ -1450,8 +1452,8 @@ wait on multiple flow variables at the same time: discard blockUntilAny(responses) Data flow variables ensure that no data races -are possible. Due to technical limitations not every type ``T`` is possible in -a data flow variable: ``T`` has to be of the type ``ref``, ``string``, ``seq`` +are possible. Due to technical limitations not every type `T` is possible in +a data flow variable: `T` has to be of the type `ref`, `string`, `seq` or of a type that doesn't contain a type that is garbage collected. This restriction is not hard to work-around in practice. @@ -1483,7 +1485,7 @@ Example: The parallel statement is the preferred mechanism to introduce parallelism in a -Nim program. A subset of the Nim language is valid within a ``parallel`` +Nim program. A subset of the Nim language is valid within a `parallel` section. This subset is checked during semantic analysis to be free of data races. A sophisticated `disjoint checker`:idx: ensures that no data races are possible even though shared memory is extensively supported! @@ -1491,25 +1493,25 @@ possible even though shared memory is extensively supported! The subset is in fact the full language with the following restrictions / changes: -* ``spawn`` within a ``parallel`` section has special semantics. -* Every location of the form ``a[i]`` and ``a[i..j]`` and ``dest`` where - ``dest`` is part of the pattern ``dest = spawn f(...)`` has to be +* `spawn` within a `parallel` section has special semantics. +* Every location of the form `a[i]` and `a[i..j]` and `dest` where + `dest` is part of the pattern `dest = spawn f(...)` has to be provably disjoint. This is called the *disjoint check*. -* Every other complex location ``loc`` that is used in a spawned - proc (``spawn f(loc)``) has to be immutable for the duration of - the ``parallel`` section. This is called the *immutability check*. Currently +* Every other complex location `loc` that is used in a spawned + proc (`spawn f(loc)`) has to be immutable for the duration of + the `parallel` section. This is called the *immutability check*. Currently it is not specified what exactly "complex location" means. We need to make this an optimization! * Every array access has to be provably within bounds. This is called the *bounds check*. * Slices are optimized so that no copy is performed. This optimization is not - yet performed for ordinary slices outside of a ``parallel`` section. + yet performed for ordinary slices outside of a `parallel` section. Guards and locks ================ -Apart from ``spawn`` and ``parallel`` Nim also provides all the common low level +Apart from `spawn` and `parallel` Nim also provides all the common low level concurrency mechanisms like locks, atomic intrinsics or condition variables. Nim significantly improves on the safety of these features via additional @@ -1528,13 +1530,13 @@ Guards and the locks section Protecting global variables ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Object fields and global variables can be annotated via a ``guard`` pragma: +Object fields and global variables can be annotated via a `guard` pragma: .. code-block:: nim var glock: TLock var gdata {.guard: glock.}: int -The compiler then ensures that every access of ``gdata`` is within a ``locks`` +The compiler then ensures that every access of `gdata` is within a `locks` section: .. code-block:: nim @@ -1547,11 +1549,11 @@ section: {.locks: [glock].}: echo gdata -Top level accesses to ``gdata`` are always allowed so that it can be initialized +Top level accesses to `gdata` are always allowed so that it can be initialized conveniently. It is *assumed* (but not enforced) that every top level statement is executed before any concurrent action happens. -The ``locks`` section deliberately looks ugly because it has no runtime +The `locks` section deliberately looks ugly because it has no runtime semantics and should not be used directly! It should only be used in templates that also implement some form of locking at runtime: @@ -1580,7 +1582,7 @@ model low level lockfree mechanisms: echo atomicRead(atomicCounter) -The ``locks`` pragma takes a list of lock expressions ``locks: [a, b, ...]`` +The `locks` pragma takes a list of lock expressions `locks: [a, b, ...]` in order to support *multi lock* statements. Why these are essential is explained in the `lock levels <#guards-and-locks-lock-levels>`_ section. @@ -1588,7 +1590,7 @@ explained in the `lock levels <#guards-and-locks-lock-levels>`_ section. Protecting general locations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The ``guard`` annotation can also be used to protect fields within an object. +The `guard` annotation can also be used to protect fields within an object. The guard then needs to be another field within the same object or a global variable. @@ -1606,7 +1608,7 @@ expressivity of the language: lock counters[i].L: inc counters[i].v -The access to field ``x.v`` is allowed since its guard ``x.L`` is active. +The access to field `x.v` is allowed since its guard `x.L` is active. After template expansion, this amounts to: .. code-block:: nim @@ -1619,10 +1621,10 @@ After template expansion, this amounts to: finally: pthread_mutex_unlock(counters[i].L) -There is an analysis that checks that ``counters[i].L`` is the lock that -corresponds to the protected location ``counters[i].v``. This analysis is called +There is an analysis that checks that `counters[i].L` is the lock that +corresponds to the protected location `counters[i].v`. This analysis is called `path analysis`:idx: because it deals with paths to locations -like ``obj.field[i].fieldB[j]``. +like `obj.field[i].fieldB[j]`. The path analysis is **currently unsound**, but that doesn't make it useless. Two paths are considered equivalent if they are syntactically the same. @@ -1644,10 +1646,10 @@ potential deadlocks during semantic analysis. A lock level is an constant integer in the range 0..1_000. Lock level 0 means that no lock is acquired at all. -If a section of code holds a lock of level ``M`` than it can also acquire any -lock of level ``N < M``. Another lock of level ``M`` cannot be acquired. Locks +If a section of code holds a lock of level `M` than it can also acquire any +lock of level `N < M`. Another lock of level `M` cannot be acquired. Locks of the same level can only be acquired *at the same time* within a -single ``locks`` section: +single `locks` section: .. code-block:: nim var a, b: TLock[2] @@ -1672,8 +1674,8 @@ single ``locks`` section: Here is how a typical multilock statement can be implemented in Nim. Note how -the runtime check is required to ensure a global ordering for two locks ``a`` -and ``b`` of the same lock level: +the runtime check is required to ensure a global ordering for two locks `a` +and `b` of the same lock level: .. code-block:: nim template multilock(a, b: ptr TLock; body: untyped) = @@ -1691,9 +1693,9 @@ and ``b`` of the same lock level: pthread_mutex_unlock(b) -Whole routines can also be annotated with a ``locks`` pragma that takes a lock +Whole routines can also be annotated with a `locks` pragma that takes a lock level. This then means that the routine may acquire locks of up to this level. -This is essential so that procs can be called within a ``locks`` section: +This is essential so that procs can be called within a `locks` section: .. code-block:: nim proc p() {.locks: 3.} = discard @@ -1704,17 +1706,17 @@ This is essential so that procs can be called within a ``locks`` section: p() -As usual ``locks`` is an inferred effect and there is a subtype -relation: ``proc () {.locks: N.}`` is a subtype of ``proc () {.locks: M.}`` +As usual `locks` is an inferred effect and there is a subtype +relation: `proc () {.locks: N.}` is a subtype of `proc () {.locks: M.}` iff (M <= N). -The ``locks`` pragma can also take the special value ``"unknown"``. This +The `locks` pragma can also take the special value `"unknown"`. This is useful in the context of dynamic method dispatching. In the following -example, the compiler can infer a lock level of 0 for the ``base`` case. +example, the compiler can infer a lock level of 0 for the `base` case. However, one of the overloaded methods calls a procvar which is -potentially locking. Thus, the lock level of calling ``g.testMethod`` +potentially locking. Thus, the lock level of calling `g.testMethod` cannot be inferred statically, leading to compiler warnings. By using -``{.locks: "unknown".}``, the base method can be marked explicitly as +`{.locks: "unknown".}`, the base method can be marked explicitly as having unknown lock level as well: .. code-block:: nim @@ -1736,8 +1738,8 @@ they will rewrite as long as there is a match. There was no way to ensure some rewrite happens only once, e.g. when rewriting term to same term plus extra content. -``noRewrite`` pragma can actually prevent further rewriting on marked code, -e.g. with given example ``echo("ab")`` will be rewritten just once: +`noRewrite` pragma can actually prevent further rewriting on marked code, +e.g. with given example `echo("ab")` will be rewritten just once: .. code-block:: nim template pwnEcho{echo(x)}(x: untyped) = @@ -1745,7 +1747,7 @@ e.g. with given example ``echo("ab")`` will be rewritten just once: echo "ab" -``noRewrite`` pragma can be useful to control term-rewriting macros recursion. +`noRewrite` pragma can be useful to control term-rewriting macros recursion. Aliasing restrictions in parameter passing @@ -1755,8 +1757,8 @@ Aliasing restrictions in parameter passing implementation and need to be fleshed out further. "Aliasing" here means that the underlying storage locations overlap in memory -at runtime. An "output parameter" is a parameter of type ``var T``, -an input parameter is any parameter that is not of type ``var``. +at runtime. An "output parameter" is a parameter of type `var T`, +an input parameter is any parameter that is not of type `var`. 1. Two output parameters should never be aliased. 2. An input and an output parameter should not be aliased. @@ -1767,25 +1769,25 @@ an input parameter is any parameter that is not of type ``var``. One problem with rules 3 and 4 is that they affect specific global or thread local variables, but Nim's effect tracking only tracks "uses no global variable" -via ``.noSideEffect``. The rules 3 and 4 can also be approximated by a different rule: +via `.noSideEffect`. The rules 3 and 4 can also be approximated by a different rule: 5. A global or thread local variable (or a location derived from such a location) - can only passed to a parameter of a ``.noSideEffect`` proc. + can only passed to a parameter of a `.noSideEffect` proc. Noalias annotation ================== -Since version 1.4 of the Nim compiler, there is a ``.noalias`` annotation for variables -and parameters. It is mapped directly to C/C++'s ``restrict`` keyword and means that +Since version 1.4 of the Nim compiler, there is a `.noalias` annotation for variables +and parameters. It is mapped directly to C/C++'s `restrict` keyword and means that the underlying pointer is pointing to a unique location in memory, no other aliases to this location exist. It is *unchecked* that this alias restriction is followed, if the restriction is violated, the backend optimizer is free to miscompile the code. This is an **unsafe** language feature. Ideally in later versions of the language, the restriction will be enforced at -compile time. (Which is also why the name ``noalias`` was choosen instead of a more -verbose name like ``unsafeAssumeNoAlias``.) +compile time. (Which is also why the name `noalias` was choosen instead of a more +verbose name like `unsafeAssumeNoAlias`.) Strict funcs @@ -1796,7 +1798,7 @@ to the existing rule that a side effect is calling a function with side effects the following rule is also enforced: Any mutation to an object does count as a side effect if that object is reachable -via a parameter that is not declared as a ``var`` parameter. +via a parameter that is not declared as a `var` parameter. For example: @@ -1830,14 +1832,14 @@ the `view types section <#view-types-algorithm>`_. View types ========== -**Note**: ``--experimental:views`` is more effective -with ``--experimental:strictFuncs``. +**Note**: `--experimental:views` is more effective +with `--experimental:strictFuncs`. A view type is a type that is or contains one of the following types: -- ``var T`` (mutable view into ``T``) -- ``lent T`` (immutable view into ``T``) -- ``openArray[T]`` (pair of (pointer to array of ``T``, size)) +- `var T` (mutable view into `T`) +- `lent T` (immutable view into `T`) +- `openArray[T]` (pair of (pointer to array of `T`, size)) For example: @@ -1850,7 +1852,7 @@ For example: View4 = Table[openArray[char], int] -Exceptions to this rule are types constructed via ``ptr`` or ``proc``. +Exceptions to this rule are types constructed via `ptr` or `proc`. For example, the following types are **not** view types: .. code-block:: nim @@ -1861,13 +1863,13 @@ For example, the following types are **not** view types: NotView3 = ptr array[4, var int] -A *mutable* view type is a type that is or contains a ``var T`` type. +A *mutable* view type is a type that is or contains a `var T` type. An *immutable* view type is a view type that is not a mutable view type. A *view* is a symbol (a let, var, const, etc.) that has a view type. Since version 1.4 Nim allows view types to be used as local variables. -This feature needs to be enabled via ``{.experimental: "views".}``. +This feature needs to be enabled via `{.experimental: "views".}`. A local variable of a view type *borrows* from the locations and it is statically enforced that the view does not outlive the location @@ -1901,47 +1903,47 @@ For example: A local variable of a view type can borrow from a location -derived from a parameter, another local variable, a global ``const`` or ``let`` -symbol or a thread-local ``var`` or ``let``. +derived from a parameter, another local variable, a global `const` or `let` +symbol or a thread-local `var` or `let`. -Let ``p`` the proc that is analysed for the correctness of the borrow operation. +Let `p` the proc that is analysed for the correctness of the borrow operation. -Let ``source`` be one of: +Let `source` be one of: -- A formal parameter of ``p``. Note that this does not cover parameters of +- A formal parameter of `p`. Note that this does not cover parameters of inner procs. -- The ``result`` symbol of ``p``. -- A local ``var`` or ``let`` or ``const`` of ``p``. Note that this does +- The `result` symbol of `p`. +- A local `var` or `let` or `const` of `p`. Note that this does not cover locals of inner procs. -- A thread-local ``var`` or ``let``. -- A global ``let`` or ``const``. +- A thread-local `var` or `let`. +- A global `let` or `const`. - A constant array/seq/object/tuple constructor. Path expressions ---------------- -A location derived from ``source`` is then defined as a path expression that -has ``source`` as the owner. A path expression ``e`` is defined recursively: +A location derived from `source` is then defined as a path expression that +has `source` as the owner. A path expression `e` is defined recursively: -- ``source`` itself is a path expression. -- Container access like ``e[i]`` is a path expression. -- Tuple access ``e[0]`` is a path expression. -- Object field access ``e.field`` is a path expression. -- ``system.toOpenArray(e, ...)`` is a path expression. -- Pointer dereference ``e[]`` is a path expression. -- An address ``addr e``, ``unsafeAddr e`` is a path expression. -- A type conversion ``T(e)`` is a path expression. -- A cast expression ``cast[T](e)`` is a path expression. -- ``f(e, ...)`` is a path expression if ``f``'s return type is a view type. - Because the view can only have been borrowed from ``e``, we then know - that owner of ``f(e, ...)`` is ``e``. +- `source` itself is a path expression. +- Container access like `e[i]` is a path expression. +- Tuple access `e[0]` is a path expression. +- Object field access `e.field` is a path expression. +- `system.toOpenArray(e, ...)` is a path expression. +- Pointer dereference `e[]` is a path expression. +- An address `addr e`, `unsafeAddr e` is a path expression. +- A type conversion `T(e)` is a path expression. +- A cast expression `cast[T](e)` is a path expression. +- `f(e, ...)` is a path expression if `f`'s return type is a view type. + Because the view can only have been borrowed from `e`, we then know + that owner of `f(e, ...)` is `e`. If a view type is used as a return type, the location must borrow from a location that is derived from the first parameter that is passed to the proc. See https://nim-lang.org/docs/manual.html#procedures-var-return-type for -details about how this is done for ``var T``. +details about how this is done for `var T`. A mutable view can borrow from a mutable location, an immutable view can borrow from both a mutable or an immutable location. @@ -1979,8 +1981,8 @@ The scope of the view does not matter: The analysis requires as much precision about mutations as is reasonably obtainable, so it is more effective with the experimental `strict funcs <#strict-funcs>`_ -feature. In other words ``--experimental:views`` works better -with ``--experimental:strictFuncs``. +feature. In other words `--experimental:views` works better +with `--experimental:strictFuncs`. The analysis is currently control flow insensitive: @@ -1992,8 +1994,8 @@ The analysis is currently control flow insensitive: s.setLen 0 echo v.field -In this example, the compiler assumes that ``s.setLen 0`` invalidates the -borrow operation of ``v`` even though a human being can easily see that it +In this example, the compiler assumes that `s.setLen 0` invalidates the +borrow operation of `v` even though a human being can easily see that it will never do that at runtime. @@ -2016,9 +2018,9 @@ A borrow operation ends with the last usage of the view variable. Reborrows --------- -A view ``v`` can borrow from multiple different locations. However, the borrow -is always the full span of ``v``'s lifetime and every location that is borrowed -from is sealed during ``v``'s lifetime. +A view `v` can borrow from multiple different locations. However, the borrow +is always the full span of `v`'s lifetime and every location that is borrowed +from is sealed during `v`'s lifetime. Algorithm @@ -2034,41 +2036,41 @@ a notion of an "abstract time", in the implementation it's a simple integer that incremented for every visited node. In the second pass information about the underlying object "graphs" is computed. -Let ``v`` be a parameter or a local variable. Let ``G(v)`` be the graph -that ``v`` belongs to. A graph is defined by the set of variables that belong -to the graph. Initially for all ``v``: ``G(v) = {v}``. Every variable can only +Let `v` be a parameter or a local variable. Let `G(v)` be the graph +that `v` belongs to. A graph is defined by the set of variables that belong +to the graph. Initially for all `v`: `G(v) = {v}`. Every variable can only be part of a single graph. -Assignments like ``a = b`` "connect" two variables, both variables end up in the -same graph ``{a, b} = G(a) = G(b)``. Unfortunately, the pattern to look for is +Assignments like `a = b` "connect" two variables, both variables end up in the +same graph `{a, b} = G(a) = G(b)`. Unfortunately, the pattern to look for is much more complex than that and can involve multiple assignment targets and sources:: f(x, y) = g(a, b) -connects ``x`` and ``y`` to ``a`` and ``b``: ``G(x) = G(y) = G(a) = G(b) = {x, y, a, b}``. +connects `x` and `y` to `a` and `b`: `G(x) = G(y) = G(a) = G(b) = {x, y, a, b}`. A type based alias analysis rules out some of these combinations, for example -a ``string`` value cannot possibly be connected to a ``seq[int]``. +a `string` value cannot possibly be connected to a `seq[int]`. -A pattern like ``v[] = value`` or ``v.field = value`` marks ``G(v)`` as mutated. +A pattern like `v[] = value` or `v.field = value` marks `G(v)` as mutated. After the second pass a set of disjoint graphs was computed. For strict functions it is then enforced that there is no graph that is both mutated and has an element that is an immutable parameter (that is a parameter that is not -of type ``var T``). +of type `var T`). -For borrow checking a different set of checks is performed. Let ``v`` be the view -and ``b`` the location that is borrowed from. +For borrow checking a different set of checks is performed. Let `v` be the view +and `b` the location that is borrowed from. -- The lifetime of ``v`` must not exceed ``b``'s lifetime. Note: The lifetime of +- The lifetime of `v` must not exceed `b`'s lifetime. Note: The lifetime of a parameter is the complete proc body. -- If ``v`` is a mutable view and ``v`` is used to actually mutate the - borrowed location, then ``b`` has to be a mutable location. +- If `v` is a mutable view and `v` is used to actually mutate the + borrowed location, then `b` has to be a mutable location. Note: If it is not actually used for mutation, borrowing a mutable view from an immutable location is allowed! This allows for many important idioms and will be justified in an upcoming RFC. -- During ``v``'s lifetime, ``G(b)`` can only be modified by ``v`` (and only if - ``v`` is a mutable view). -- If ``v`` is ``result`` then ``b`` has to be a location derived from the first +- During `v`'s lifetime, `G(b)` can only be modified by `v` (and only if + `v` is a mutable view). +- If `v` is `result` then `b` has to be a location derived from the first formal parameter or from a constant location. - A view cannot be used for a read or a write access before it was assigned to. diff --git a/doc/manual_experimental_strictnotnil.rst b/doc/manual_experimental_strictnotnil.rst index 10b59a74e..c7c045683 100644 --- a/doc/manual_experimental_strictnotnil.rst +++ b/doc/manual_experimental_strictnotnil.rst @@ -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. diff --git a/doc/nep1.rst b/doc/nep1.rst index 4a31524f6..3bae6a00b 100644 --- a/doc/nep1.rst +++ b/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. diff --git a/doc/nimc.rst b/doc/nimc.rst index ea173691f..aad889591 100644 --- a/doc/nimc.rst +++ b/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:. diff --git a/doc/nimfix.rst b/doc/nimfix.rst index 62064fe69..d105346da 100644 --- a/doc/nimfix.rst +++ b/doc/nimfix.rst @@ -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. diff --git a/doc/nimgrep.rst b/doc/nimgrep.rst index 791ead162..5b0fe0dbb 100644 --- a/doc/nimgrep.rst +++ b/doc/nimgrep.rst @@ -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 diff --git a/doc/niminst.rst b/doc/niminst.rst index adb5e6f1f..3ccb47cc8 100644 --- a/doc/niminst.rst +++ b/doc/niminst.rst @@ -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"` ==================== ======================================================= diff --git a/doc/nims.rst b/doc/nims.rst index aa13d134a..f81637d73 100644 --- a/doc/nims.rst +++ b/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. diff --git a/doc/nimsuggest.rst b/doc/nimsuggest.rst index 8db7c233b..509f72e8a 100644 --- a/doc/nimsuggest.rst +++ b/doc/nimsuggest.rst @@ -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**. diff --git a/doc/testament.rst b/doc/testament.rst index 5db68bfa7..04c966ffe 100644 --- a/doc/testament.rst +++ b/doc/testament.rst @@ -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>`_ diff --git a/doc/tools.rst b/doc/tools.rst index f231cdc7d..e0044e1ca 100644 --- a/doc/tools.rst +++ b/doc/tools.rst @@ -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)>`_, diff --git a/doc/tut1.rst b/doc/tut1.rst index 171b2f918..d2d6f8fe7 100644 --- a/doc/tut1.rst +++ b/doc/tut1.rst @@ -1,3 +1,5 @@ +.. default-role:: code + ===================== Nim Tutorial (Part I) ===================== @@ -46,7 +48,7 @@ Save this code to the file "greetings.nim". Now compile and run it:: nim compile --run greetings.nim -With the ``--run`` `switch <nimc.html#compiler-usage-commandminusline-switches>`_ Nim +With the `--run` `switch <nimc.html#compiler-usage-commandminusline-switches>`_ Nim executes the file automatically after compilation. You can give your program command-line arguments by appending them after the filename:: @@ -61,7 +63,7 @@ To compile a release version use:: nim c -d:release greetings.nim By default, the Nim compiler generates a large number of runtime checks -aiming for your debugging pleasure. With ``-d:release`` some checks are +aiming for your debugging pleasure. With `-d:release` some checks are `turned off and optimizations are turned on <nimc.html#compiler-usage-compileminustime-symbols>`_. @@ -70,8 +72,8 @@ syntax: statements which are not indented are executed when the program starts. Indentation is Nim's way of grouping statements. Indentation is done with spaces only, tabulators are not allowed. -String literals are enclosed in double-quotes. The ``var`` statement declares -a new variable named ``name`` of type ``string`` with the value that is +String literals are enclosed in double-quotes. The `var` statement declares +a new variable named `name` of type `string` with the value that is returned by the `readLine <io.html#readLine,File>`_ procedure. Since the compiler knows that `readLine <io.html#readLine,File>`_ returns a string, you can leave out the type in the declaration (this is called `local type @@ -85,7 +87,7 @@ Note that this is basically the only form of type inference that exists in Nim: it is a good compromise between brevity and readability. The "hello world" program contains several identifiers that are already known -to the compiler: ``echo``, `readLine <io.html#readLine,File>`_, etc. +to the compiler: `echo`, `readLine <io.html#readLine,File>`_, etc. These built-ins are declared in the system_ module which is implicitly imported by any other module. @@ -102,7 +104,7 @@ String and character literals ----------------------------- String literals are enclosed in double-quotes; character literals in single -quotes. Special characters are escaped with ``\``: ``\n`` means newline, ``\t`` +quotes. Special characters are escaped with ``\\``: ``\n`` means newline, ``\t`` means tabulator, etc. There are also *raw* string literals: .. code-block:: Nim @@ -111,8 +113,8 @@ means tabulator, etc. There are also *raw* string literals: In raw literals, the backslash is not an escape character. The third and last way to write string literals is *long-string literals*. -They are written with three quotes: ``""" ... """``; they can span over -multiple lines and the ``\`` is not an escape character either. They are very +They are written with three quotes: `""" ... """`; they can span over +multiple lines and the ``\\`` is not an escape character either. They are very useful for embedding HTML code templates for example. @@ -120,7 +122,7 @@ Comments -------- Comments start anywhere outside a string or character literal with the -hash character ``#``. Documentation comments start with ``##``: +hash character `#`. Documentation comments start with `##`: .. code-block:: nim :test: "nim c $1" @@ -133,7 +135,7 @@ Documentation comments are tokens; they are only allowed at certain places in the input file as they belong to the syntax tree! This feature enables simpler documentation generators. -Multiline comments are started with ``#[`` and terminated with ``]#``. Multiline +Multiline comments are started with `#[` and terminated with `]#`. Multiline comments can also be nested. .. code-block:: nim @@ -152,10 +154,10 @@ Numbers ------- Numerical literals are written as in most other languages. As a special twist, -underscores are allowed for better readability: ``1_000_000`` (one million). +underscores are allowed for better readability: `1_000_000` (one million). A number that contains a dot (or 'e' or 'E') is a floating-point literal: -``1.0e9`` (one billion). Hexadecimal literals are prefixed with ``0x``, -binary literals with ``0b`` and octal literals with ``0o``. A leading zero +`1.0e9` (one billion). Hexadecimal literals are prefixed with `0x`, +binary literals with `0b` and octal literals with `0o`. A leading zero alone does not produce an octal. @@ -164,9 +166,9 @@ The var statement The var statement declares a new local or global variable: .. code-block:: - var x, y: int # declares x and y to have the type ``int`` + var x, y: int # declares x and y to have the type `int` -Indentation can be used after the ``var`` keyword to list a whole section of +Indentation can be used after the `var` keyword to list a whole section of variables: .. code-block:: @@ -187,7 +189,7 @@ to a storage location: var x = "abc" # introduces a new variable `x` and assigns a value to it x = "xyz" # assigns a new value to `x` -``=`` is the *assignment operator*. The assignment operator can be +`=` is the *assignment operator*. The assignment operator can be overloaded. You can declare multiple variables with a single assignment statement and all the variables will have the same value: @@ -219,7 +221,7 @@ constant declaration at compile time: :test: "nim c $1" const x = "abc" # the constant x contains the string "abc" -Indentation can be used after the ``const`` keyword to list a whole section of +Indentation can be used after the `const` keyword to list a whole section of constants: .. code-block:: @@ -233,7 +235,7 @@ constants: The let statement ================= -The ``let`` statement works like the ``var`` statement but the declared +The `let` statement works like the `var` statement but the declared symbols are *single assignment* variables: After the initialization their value cannot change: @@ -241,8 +243,8 @@ value cannot change: let x = "abc" # introduces a new variable `x` and binds a value to it x = "xyz" # Illegal: assignment to `x` -The difference between ``let`` and ``const`` is: ``let`` introduces a variable -that can not be re-assigned, ``const`` means "enforce compile time evaluation +The difference between `let` and `const` is: `let` introduces a variable +that can not be re-assigned, `const` means "enforce compile time evaluation and put it into a data section": .. code-block:: @@ -276,9 +278,9 @@ The if statement is one way to branch the control flow: else: echo "Hi, ", name, "!" -There can be zero or more ``elif`` parts, and the ``else`` part is optional. -The keyword ``elif`` is short for ``else if``, and is useful to avoid -excessive indentation. (The ``""`` is the empty string. It contains no +There can be zero or more `elif` parts, and the `else` part is optional. +The keyword `elif` is short for `else if`, and is useful to avoid +excessive indentation. (The `""` is the empty string. It contains no characters.) @@ -301,7 +303,7 @@ a multi-branch: else: echo "Hi, ", name, "!" -As it can be seen, for an ``of`` branch a comma-separated list of values is also +As it can be seen, for an `of` branch a comma-separated list of values is also allowed. The case statement can deal with integers, other ordinal types, and strings. @@ -319,8 +321,8 @@ For integers or other ordinal types value ranges are also possible: of 3, 8: echo "The number is 3 or 8" However, the above code does not compile: the reason is that you have to cover -every value that ``n`` may contain, but the code only handles the values -``0..8``. Since it is not very practical to list every other possible integer +every value that `n` may contain, but the code only handles the values +`0..8`. Since it is not very practical to list every other possible integer (though it is possible thanks to the range notation), we fix this by telling the compiler that for every other value nothing should be done: @@ -334,7 +336,7 @@ the compiler that for every other value nothing should be done: The empty `discard statement <#procedures-discard-statement>`_ is a *do nothing* statement. The compiler knows that a case statement with an else part cannot fail and thus the error disappears. Note that it is impossible to cover -all possible string values: that is why string cases always need an ``else`` +all possible string values: that is why string cases always need an `else` branch. In general, the case statement is used for subrange types or enumerations where @@ -355,7 +357,7 @@ The while statement is a simple looping construct: while name == "": echo "Please tell me your name: " name = readLine(stdin) - # no ``var``, because we do not declare a new variable here + # no `var`, because we do not declare a new variable here The example uses a while loop to keep asking the users for their name, as long as the user types in nothing (only presses RETURN). @@ -364,7 +366,7 @@ as the user types in nothing (only presses RETURN). For statement ------------- -The ``for`` statement is a construct to loop over any element an *iterator* +The `for` statement is a construct to loop over any element an *iterator* provides. The example uses the built-in `countup <system.html#countup.i,T,T,Positive>`_ iterator: @@ -375,10 +377,10 @@ provides. The example uses the built-in `countup echo i # --> Outputs 1 2 3 4 5 6 7 8 9 10 on different lines -The variable ``i`` is implicitly declared by the -``for`` loop and has the type ``int``, because that is what `countup -<system.html#countup.i,T,T,Positive>`_ returns. ``i`` runs through the values -1, 2, .., 10. Each value is ``echo``-ed. This code does the same: +The variable `i` is implicitly declared by the +`for` loop and has the type `int`, because that is what `countup +<system.html#countup.i,T,T,Positive>`_ returns. `i` runs through the values +1, 2, .., 10. Each value is `echo`-ed. This code does the same: .. code-block:: nim echo "Counting to 10: " @@ -403,7 +405,7 @@ Since counting up occurs so often in programs, Nim also has a `.. for i in 1 .. 10: ... -Zero-indexed counting has two shortcuts ``..<`` and ``.. ^1`` +Zero-indexed counting has two shortcuts `..<` and `.. ^1` (`backward index operator <system.html#^.t%2Cint>`_) to simplify counting to one less than the higher index: @@ -426,8 +428,8 @@ or ... Other useful iterators for collections (like arrays and sequences) are -* ``items`` and ``mitems``, which provides immutable and mutable elements respectively, and -* ``pairs`` and ``mpairs`` which provides the element and an index number (immutable and mutable respectively) +* `items` and `mitems`, which provides immutable and mutable elements respectively, and +* `pairs` and `mpairs` which provides the element and an index number (immutable and mutable respectively) .. code-block:: nim :test: "nim c $1" @@ -439,7 +441,7 @@ Other useful iterators for collections (like arrays and sequences) are Scopes and the block statement ------------------------------ Control flow statements have a feature not covered yet: they open a -new scope. This means that in the following example, ``x`` is not accessible +new scope. This means that in the following example, `x` is not accessible outside the loop: .. code-block:: nim @@ -450,7 +452,7 @@ outside the loop: echo x # does not work A while (for) statement introduces an implicit block. Identifiers -are only visible within the block they have been declared. The ``block`` +are only visible within the block they have been declared. The `block` statement can be used to open a new block explicitly: .. code-block:: nim @@ -460,13 +462,13 @@ statement can be used to open a new block explicitly: var x = "hi" echo x # does not work either -The block's *label* (``myblock`` in the example) is optional. +The block's *label* (`myblock` in the example) is optional. Break statement --------------- -A block can be left prematurely with a ``break`` statement. The break statement -can leave a ``while``, ``for``, or a ``block`` statement. It leaves the +A block can be left prematurely with a `break` statement. The break statement +can leave a `while`, `for`, or a `block` statement. It leaves the innermost construct, unless a label of a block is given: .. code-block:: nim @@ -490,7 +492,7 @@ innermost construct, unless a label of a block is given: Continue statement ------------------ -Like in many other programming languages, a ``continue`` statement starts +Like in many other programming languages, a `continue` statement starts the next iteration immediately: .. code-block:: nim @@ -518,17 +520,17 @@ Example: else: echo "unknown operating system" -The ``when`` statement is almost identical to the ``if`` statement, but with these +The `when` statement is almost identical to the `if` statement, but with these differences: * Each condition must be a constant expression since it is evaluated by the compiler. * The statements within a branch do not open a new scope. * The compiler checks the semantics and produces code *only* for the statements - that belong to the first condition that evaluates to ``true``. + that belong to the first condition that evaluates to `true`. -The ``when`` statement is useful for writing platform-specific code, similar to -the ``#ifdef`` construct in the C programming language. +The `when` statement is useful for writing platform-specific code, similar to +the `#ifdef` construct in the C programming language. Statements and indentation @@ -539,8 +541,8 @@ indentation rules. In Nim, there is a distinction between *simple statements* and *complex statements*. *Simple statements* cannot contain other statements: -Assignment, procedure calls, or the ``return`` statement are all simple -statements. *Complex statements* like ``if``, ``when``, ``for``, ``while`` can +Assignment, procedure calls, or the `return` statement are all simple +statements. *Complex statements* like `if`, `when`, `for`, `while` can contain other statements. To avoid ambiguities, complex statements must always be indented, but single simple statements do not: @@ -575,7 +577,7 @@ contain indentation at certain places for better readability: As a rule of thumb, indentation within expressions is allowed after operators, an open parenthesis and after commas. -With parenthesis and semicolons ``(;)`` you can use statements where only +With parenthesis and semicolons `(;)` you can use statements where only an expression is allowed: .. code-block:: nim @@ -590,7 +592,7 @@ Procedures To define new commands like `echo <system.html#echo,varargs[typed,]>`_ and `readLine <io.html#readLine,File>`_ in the examples, the concept of a `procedure` is needed. (Some languages call them *methods* or *functions*.) -In Nim new procedures are defined with the ``proc`` keyword: +In Nim new procedures are defined with the `proc` keyword: .. code-block:: nim :test: "nim c $1" @@ -607,26 +609,26 @@ In Nim new procedures are defined with the ``proc`` keyword: else: echo "I think you know what the problem is just as well as I do." -This example shows a procedure named ``yes`` that asks the user a ``question`` +This example shows a procedure named `yes` that asks the user a `question` and returns true if they answered "yes" (or something similar) and returns -false if they answered "no" (or something similar). A ``return`` statement +false if they answered "no" (or something similar). A `return` statement leaves the procedure (and therefore the while loop) immediately. The -``(question: string): bool`` syntax describes that the procedure expects a -parameter named ``question`` of type ``string`` and returns a value of type -``bool``. The ``bool`` type is built-in: the only valid values for ``bool`` are -``true`` and ``false``. -The conditions in if or while statements must be of type ``bool``. +`(question: string): bool` syntax describes that the procedure expects a +parameter named `question` of type `string` and returns a value of type +`bool`. The `bool` type is built-in: the only valid values for `bool` are +`true` and `false`. +The conditions in if or while statements must be of type `bool`. -Some terminology: in the example ``question`` is called a (formal) *parameter*, -``"Should I..."`` is called an *argument* that is passed to this parameter. +Some terminology: in the example `question` is called a (formal) *parameter*, +`"Should I..."` is called an *argument* that is passed to this parameter. Result variable --------------- -A procedure that returns a value has an implicit ``result`` variable declared -that represents the return value. A ``return`` statement with no expression is -shorthand for ``return result``. The ``result`` value is always returned -automatically at the end of a procedure if there is no ``return`` statement at +A procedure that returns a value has an implicit `result` variable declared +that represents the return value. A `return` statement with no expression is +shorthand for `return result`. The `result` value is always returned +automatically at the end of a procedure if there is no `return` statement at the exit. .. code-block:: nim @@ -641,15 +643,15 @@ the exit. echo sumTillNegative(3, 4, 5) # echos 12 echo sumTillNegative(3, 4 , -1 , 6) # echos 7 -The ``result`` variable is already implicitly declared at the start of the +The `result` variable is already implicitly declared at the start of the function, so declaring it again with 'var result', for example, would shadow it with a normal variable of the same name. The result variable is also already initialized with the type's default value. Note that referential data types will -be ``nil`` at the start of the procedure, and thus may require manual +be `nil` at the start of the procedure, and thus may require manual initialization. -A procedure that does not have any ``return`` statement and does not use the -special ``result`` variable returns the value of its last expression. For example, +A procedure that does not have any `return` statement and does not use the +special `result` variable returns the value of its last expression. For example, this procedure .. code-block:: nim @@ -664,7 +666,7 @@ Parameters Parameters are immutable in the procedure body. By default, their value cannot be changed because this allows the compiler to implement parameter passing in the most efficient way. If a mutable variable is needed inside the procedure, it has -to be declared with ``var`` in the procedure body. Shadowing the parameter name +to be declared with `var` in the procedure body. Shadowing the parameter name is possible, and actually an idiom: .. code-block:: nim @@ -675,7 +677,7 @@ is possible, and actually an idiom: echo s[i] If the procedure needs to modify the argument for the -caller, a ``var`` parameter can be used: +caller, a `var` parameter can be used: .. code-block:: nim :test: "nim c $1" @@ -689,7 +691,7 @@ caller, a ``var`` parameter can be used: echo x echo y -In the example, ``res`` and ``remainder`` are `var parameters`. +In the example, `res` and `remainder` are `var parameters`. Var parameters can be modified by the procedure and the changes are visible to the caller. Note that the above example would better make use of a tuple as a return value instead of using var parameters. @@ -698,7 +700,7 @@ a tuple as a return value instead of using var parameters. Discard statement ----------------- To call a procedure that returns a value just for its side effects and ignoring -its return value, a ``discard`` statement **must** be used. Nim does not +its return value, a `discard` statement **must** be used. Nim does not allow silently throwing away a return value: .. code-block:: nim @@ -706,7 +708,7 @@ allow silently throwing away a return value: The return value can be ignored implicitly if the called proc/iterator has -been declared with the ``discardable`` pragma: +been declared with the `discardable` pragma: .. code-block:: nim :test: "nim c $1" @@ -732,7 +734,7 @@ that it is clear which argument belongs to which parameter: var w = createWindow(show = true, title = "My Application", x = 0, y = 0, height = 600, width = 800) -Now that we use named arguments to call ``createWindow`` the argument order +Now that we use named arguments to call `createWindow` the argument order does not matter anymore. Mixing named arguments with ordered arguments is also possible, but not very readable: @@ -745,7 +747,7 @@ The compiler checks that each parameter receives exactly one argument. Default values -------------- -To make the ``createWindow`` proc easier to use it should provide `default +To make the `createWindow` proc easier to use it should provide `default values`; these are values that are used as arguments if the caller does not specify them: @@ -757,11 +759,11 @@ specify them: var w = createWindow(title = "My Application", height = 600, width = 800) -Now the call to ``createWindow`` only needs to set the values that differ +Now the call to `createWindow` only needs to set the values that differ from the defaults. Note that type inference works for parameters with default values; there is -no need to write ``title: string = "unknown"``, for example. +no need to write `title: string = "unknown"`, for example. Overloaded procedures @@ -783,8 +785,8 @@ Nim provides the ability to overload procedures similar to C++: assert toString(13) == "positive" # calls the toString(x: int) proc assert toString(true) == "yep" # calls the toString(x: bool) proc -(Note that ``toString`` is usually the `$ <dollars.html>`_ operator in -Nim.) The compiler chooses the most appropriate proc for the ``toString`` +(Note that `toString` is usually the `$ <dollars.html>`_ operator in +Nim.) The compiler chooses the most appropriate proc for the `toString` calls. How this overloading resolution algorithm works exactly is not discussed here (it will be specified in the manual soon). However, it does not lead to nasty surprises and is based on a quite simple unification @@ -794,31 +796,31 @@ algorithm. Ambiguous calls are reported as errors. Operators --------- The Nim library makes heavy use of overloading - one reason for this is that -each operator like ``+`` is just an overloaded proc. The parser lets you -use operators in `infix notation` (``a + b``) or `prefix notation` (``+ a``). +each operator like `+` is just an overloaded proc. The parser lets you +use operators in `infix notation` (`a + b`) or `prefix notation` (`+ a`). An infix operator always receives two arguments, a prefix operator always one. (Postfix operators are not possible, because this would be ambiguous: does -``a @ @ b`` mean ``(a) @ (@b)`` or ``(a@) @ (b)``? It always means -``(a) @ (@b)``, because there are no postfix operators in Nim.) +`a @ @ b` mean `(a) @ (@b)` or `(a@) @ (b)`? It always means +`(a) @ (@b)`, because there are no postfix operators in Nim.) -Apart from a few built-in keyword operators such as ``and``, ``or``, ``not``, +Apart from a few built-in keyword operators such as `and`, `or`, `not`, operators always consist of these characters: ``+ - * \ / < > = @ $ ~ & % ! ? ^ . |`` User-defined operators are allowed. Nothing stops you from defining your own -``@!?+~`` operator, but doing so may reduce readability. +`@!?+~` operator, but doing so may reduce readability. The operator's precedence is determined by its first character. The details can be found in the manual. -To define a new operator enclose the operator in backticks "``": +To define a new operator enclose the operator in backticks "`": .. code-block:: nim proc `$` (x: myDataType): string = ... # now the $ operator also works with myDataType, overloading resolution # ensures that $ works for built-in types just like before -The "``" notation can also be used to call an operator just like any other +The "`" notation can also be used to call an operator just like any other procedure: .. code-block:: nim @@ -851,10 +853,10 @@ However, this cannot be done for mutually recursive procedures: else: n == 0 or odd(n-1) -Here ``odd`` depends on ``even`` and vice versa. Thus ``even`` needs to be +Here `odd` depends on `even` and vice versa. Thus `even` needs to be introduced to the compiler before it is completely defined. The syntax for -such a forward declaration is simple: just omit the ``=`` and the -procedure's body. The ``assert`` just adds border conditions, and will be +such a forward declaration is simple: just omit the `=` and the +procedure's body. The `assert` just adds border conditions, and will be covered later in `Modules`_ section. Later versions of the language will weaken the requirements for forward @@ -886,9 +888,9 @@ supports this loop? Lets try: inc(res) However, this does not work. The problem is that the procedure should not -only ``return``, but return and **continue** after an iteration has +only `return`, but return and **continue** after an iteration has finished. This *return and continue* is called a `yield` statement. Now -the only thing left to do is to replace the ``proc`` keyword by ``iterator`` +the only thing left to do is to replace the `proc` keyword by `iterator` and here it is - our first iterator: .. code-block:: nim @@ -903,19 +905,19 @@ Iterators look very similar to procedures, but there are several important differences: * Iterators can only be called from for loops. -* Iterators cannot contain a ``return`` statement (and procs cannot contain a - ``yield`` statement). -* Iterators have no implicit ``result`` variable. +* Iterators cannot contain a `return` statement (and procs cannot contain a + `yield` statement). +* Iterators have no implicit `result` variable. * Iterators do not support recursion. * Iterators cannot be forward declared, because the compiler must be able to inline an iterator. (This restriction will be gone in a future version of the compiler.) -However, you can also use a ``closure`` iterator to get a different set of +However, you can also use a `closure` iterator to get a different set of restrictions. See `first-class iterators <manual.html#iterators-and-the-for-statement-firstminusclass-iterators>`_ for details. Iterators can have the same name and parameters as a proc since essentially they have their own namespaces. Therefore it is common practice to wrap iterators in procs of the same name which accumulate the result of the -iterator and return it as a sequence, like ``split`` from the `strutils module +iterator and return it as a sequence, like `split` from the `strutils module <strutils.html>`_. @@ -928,12 +930,12 @@ that are available for them in detail. Booleans -------- -Nim's boolean type is called ``bool`` and consists of the two -pre-defined values ``true`` and ``false``. Conditions in while, +Nim's boolean type is called `bool` and consists of the two +pre-defined values `true` and `false`. Conditions in while, if, elif, and when statements must be of type bool. -The operators ``not, and, or, xor, <, <=, >, >=, !=, ==`` are defined -for the bool type. The ``and`` and ``or`` operators perform short-circuit +The operators `not, and, or, xor, <, <=, >, >=, !=, ==` are defined +for the bool type. The `and` and `or` operators perform short-circuit evaluation. For example: .. code-block:: nim @@ -945,7 +947,7 @@ evaluation. For example: Characters ---------- -The `character type` is called ``char``. Its size is always one byte, so +The `character type` is called `char`. Its size is always one byte, so it cannot represent most UTF-8 characters, but it *can* represent one of the bytes that makes up a multi-byte UTF-8 character. The reason for this is efficiency: for the overwhelming majority of use-cases, @@ -953,57 +955,57 @@ the resulting programs will still handle UTF-8 properly as UTF-8 was especially designed for this. Character literals are enclosed in single quotes. -Chars can be compared with the ``==``, ``<``, ``<=``, ``>``, ``>=`` operators. -The ``$`` operator converts a ``char`` to a ``string``. Chars cannot be mixed -with integers; to get the ordinal value of a ``char`` use the ``ord`` proc. -Converting from an integer to a ``char`` is done with the ``chr`` proc. +Chars can be compared with the `==`, `<`, `<=`, `>`, `>=` operators. +The `$` operator converts a `char` to a `string`. Chars cannot be mixed +with integers; to get the ordinal value of a `char` use the `ord` proc. +Converting from an integer to a `char` is done with the `chr` proc. Strings ------- String variables are **mutable**, so appending to a string is possible, and quite efficient. Strings in Nim are both zero-terminated and have a -length field. A string's length can be retrieved with the builtin ``len`` +length field. A string's length can be retrieved with the builtin `len` procedure; the length never counts the terminating zero. Accessing the terminating zero is an error, it only exists so that a Nim string can be converted -to a ``cstring`` without doing a copy. +to a `cstring` without doing a copy. -The assignment operator for strings copies the string. You can use the ``&`` -operator to concatenate strings and ``add`` to append to a string. +The assignment operator for strings copies the string. You can use the `&` +operator to concatenate strings and `add` to append to a string. Strings are compared using their lexicographical order. All the comparison operators are supported. By convention, all strings are UTF-8 encoded, but this is not enforced. For example, when reading strings from binary files, they are merely -a sequence of bytes. The index operation ``s[i]`` means the i-th *char* of -``s``, not the i-th *unichar*. +a sequence of bytes. The index operation `s[i]` means the i-th *char* of +`s`, not the i-th *unichar*. -A string variable is initialized with the empty string ``""``. +A string variable is initialized with the empty string `""`. Integers -------- Nim has these integer types built-in: -``int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64``. +`int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64`. -The default integer type is ``int``. Integer literals can have a *type suffix* +The default integer type is `int`. Integer literals can have a *type suffix* to specify a non-default integer type: .. code-block:: nim :test: "nim c $1" let - x = 0 # x is of type ``int`` - y = 0'i8 # y is of type ``int8`` - z = 0'i64 # z is of type ``int64`` - u = 0'u # u is of type ``uint`` + x = 0 # x is of type `int` + y = 0'i8 # y is of type `int8` + z = 0'i64 # z is of type `int64` + u = 0'u # u is of type `uint` Most often integers are used for counting objects that reside in memory, so -``int`` has the same size as a pointer. +`int` has the same size as a pointer. -The common operators ``+ - * div mod < <= == != > >=`` are defined for -integers. The ``and or xor not`` operators are also defined for integers and -provide *bitwise* operations. Left bit shifting is done with the ``shl``, right -shifting with the ``shr`` operator. Bit shifting operators always treat their +The common operators `+ - * div mod < <= == != > >=` are defined for +integers. The `and or xor not` operators are also defined for integers and +provide *bitwise* operations. Left bit shifting is done with the `shl`, right +shifting with the `shr` operator. Bit shifting operators always treat their arguments as *unsigned*. For `arithmetic bit shifts`:idx: ordinary multiplication or division can be used. @@ -1018,10 +1020,10 @@ cannot be detected at compile time). Floats ------ -Nim has these floating-point types built-in: ``float float32 float64``. +Nim has these floating-point types built-in: `float float32 float64`. -The default float type is ``float``. In the current implementation, -``float`` is always 64-bits. +The default float type is `float`. In the current implementation, +`float` is always 64-bits. Float literals can have a *type suffix* to specify a non-default float type: @@ -1029,11 +1031,11 @@ type: .. code-block:: nim :test: "nim c $1" var - x = 0.0 # x is of type ``float`` - y = 0.0'f32 # y is of type ``float32`` - z = 0.0'f64 # z is of type ``float64`` + x = 0.0 # x is of type `float` + y = 0.0'f32 # y is of type `float32` + z = 0.0'f64 # z is of type `float64` -The common operators ``+ - * / < <= == != > >=`` are defined for +The common operators `+ - * / < <= == != > >=` are defined for floats and follow the IEEE-754 standard. Automatic type conversion in expressions with different kinds of floating-point types is performed: the smaller type is converted to the larger. Integer @@ -1061,13 +1063,13 @@ Internal type representation As mentioned earlier, the built-in `$ <dollars.html>`_ (stringify) operator turns any basic type into a string, which you can then print to the console -using the ``echo`` proc. However, advanced types, and your own custom types, -won't work with the ``$`` operator until you define it for them. +using the `echo` proc. However, advanced types, and your own custom types, +won't work with the `$` operator until you define it for them. Sometimes you just want to debug the current value of a complex type without -having to write its ``$`` operator. You can use then the `repr +having to write its `$` operator. You can use then the `repr <system.html#repr,T>`_ proc which works with any type and even complex data graphs with cycles. The following example shows that even for basic types -there is a difference between the ``$`` and ``repr`` outputs: +there is a difference between the `$` and `repr` outputs: .. code-block:: nim :test: "nim c $1" @@ -1092,7 +1094,7 @@ there is a difference between the ``$`` and ``repr`` outputs: Advanced types ============== -In Nim new types can be defined within a ``type`` statement: +In Nim new types can be defined within a `type` statement: .. code-block:: nim :test: "nim c $1" @@ -1101,7 +1103,7 @@ In Nim new types can be defined within a ``type`` statement: biggestFloat = float64 # biggest float type that is available Enumeration and object types may only be defined within a -``type`` statement. +`type` statement. Enumerations @@ -1124,9 +1126,9 @@ at runtime by 0, the second by 1, and so on. For example: All the comparison operators can be used with enumeration types. An enumeration's symbol can be qualified to avoid ambiguities: -``Direction.south``. +`Direction.south`. -The ``$`` operator can convert any enumeration value to its name, and the ``ord`` +The `$` operator can convert any enumeration value to its name, and the `ord` proc can convert it to its underlying integer value. For better interfacing to other programming languages, the symbols of enum @@ -1136,7 +1138,7 @@ must be in ascending order. Ordinal types ------------- -Enumerations, integer types, ``char`` and ``bool`` (and +Enumerations, integer types, `char` and `bool` (and subranges) are called ordinal types. Ordinal types have quite a few special operations: @@ -1144,16 +1146,16 @@ a few special operations: ----------------- -------------------------------------------------------- Operation Comment ----------------- -------------------------------------------------------- -``ord(x)`` returns the integer value that is used to +`ord(x)` returns the integer value that is used to represent `x`'s value -``inc(x)`` increments `x` by one -``inc(x, n)`` increments `x` by `n`; `n` is an integer -``dec(x)`` decrements `x` by one -``dec(x, n)`` decrements `x` by `n`; `n` is an integer -``succ(x)`` returns the successor of `x` -``succ(x, n)`` returns the `n`'th successor of `x` -``pred(x)`` returns the predecessor of `x` -``pred(x, n)`` returns the `n`'th predecessor of `x` +`inc(x)` increments `x` by one +`inc(x, n)` increments `x` by `n`; `n` is an integer +`dec(x)` decrements `x` by one +`dec(x, n)` decrements `x` by `n`; `n` is an integer +`succ(x)` returns the successor of `x` +`succ(x, n)` returns the `n`'th successor of `x` +`pred(x)` returns the predecessor of `x` +`pred(x, n)` returns the `n`'th predecessor of `x` ----------------- -------------------------------------------------------- @@ -1174,17 +1176,17 @@ A subrange type is a range of values from an integer or enumeration type MySubrange = range[0..5] -``MySubrange`` is a subrange of ``int`` which can only hold the values 0 -to 5. Assigning any other value to a variable of type ``MySubrange`` is a +`MySubrange` is a subrange of `int` which can only hold the values 0 +to 5. Assigning any other value to a variable of type `MySubrange` is a compile-time or runtime error. Assignments from the base type to one of its subrange types (and vice versa) are allowed. -The ``system`` module defines the important `Natural <system.html#Natural>`_ -type as ``range[0..high(int)]`` (`high <system.html#high,typedesc[T]>`_ returns +The `system` module defines the important `Natural <system.html#Natural>`_ +type as `range[0..high(int)]` (`high <system.html#high,typedesc[T]>`_ returns the maximal value). Other programming languages may suggest the use of unsigned integers for natural numbers. This is often **unwise**: you don't want unsigned arithmetic (which wraps around) just because the numbers cannot be negative. -Nim's ``Natural`` type helps to avoid this common programming error. +Nim's `Natural` type helps to avoid this common programming error. Sets @@ -1197,7 +1199,7 @@ Arrays An array is a simple fixed-length container. Each element in an array has the same type. The array's index type can be any ordinal type. -Arrays can be constructed using ``[]``: +Arrays can be constructed using `[]`: .. code-block:: nim :test: "nim c $1" @@ -1210,10 +1212,10 @@ Arrays can be constructed using ``[]``: for i in low(x)..high(x): echo x[i] -The notation ``x[i]`` is used to access the i-th element of ``x``. +The notation `x[i]` is used to access the i-th element of `x`. Array access is always bounds checked (at compile-time or at runtime). These checks can be disabled via pragmas or invoking the compiler with the -``--bound_checks:off`` command line switch. +`--bound_checks:off` command line switch. Arrays are value types, like any other Nim type. The assignment operator copies the whole array contents. @@ -1263,9 +1265,9 @@ subdivided into height levels accessed through their integer index: #tower[north][east] = on #tower[0][1] = on -Note how the built-in ``len`` proc returns only the array's first dimension -length. Another way of defining the ``LightTower`` to better illustrate its -nested nature would be to omit the previous definition of the ``LevelSetting`` +Note how the built-in `len` proc returns only the array's first dimension +length. Another way of defining the `LightTower` to better illustrate its +nested nature would be to omit the previous definition of the `LevelSetting` type and instead write it embedded directly as the type of the first dimension: .. code-block:: nim @@ -1295,13 +1297,13 @@ Sequences are similar to arrays but of dynamic length which may change during runtime (like strings). Since sequences are resizable they are always allocated on the heap and garbage collected. -Sequences are always indexed with an ``int`` starting at position 0. The `len +Sequences are always indexed with an `int` starting at position 0. The `len <system.html#len,seq[T]>`_, `low <system.html#low,openArray[T]>`_ and `high <system.html#high,openArray[T]>`_ operations are available for sequences too. -The notation ``x[i]`` can be used to access the i-th element of ``x``. +The notation `x[i]` can be used to access the i-th element of `x`. -Sequences can be constructed by the array constructor ``[]`` in conjunction -with the array to sequence operator ``@``. Another way to allocate space for +Sequences can be constructed by the array constructor `[]` in conjunction +with the array to sequence operator `@`. Another way to allocate space for a sequence is to call the built-in `newSeq <system.html#newSeq>`_ procedure. A sequence may be passed to an openarray parameter. @@ -1315,15 +1317,15 @@ Example: x: seq[int] # a reference to a sequence of integers x = @[1, 2, 3, 4, 5, 6] # the @ turns the array into a sequence allocated on the heap -Sequence variables are initialized with ``@[]``. +Sequence variables are initialized with `@[]`. -The ``for`` statement can be used with one or two variables when used with a +The `for` statement can be used with one or two variables when used with a sequence. When you use the one variable form, the variable will hold the value -provided by the sequence. The ``for`` statement is looping over the results +provided by the sequence. The `for` statement is looping over the results from the `items() <iterators.html#items.i,seq[T]>`_ iterator from the `system <system.html>`_ module. But if you use the two-variable form, the first variable will hold the index position and the second variable will hold the -value. Here the ``for`` statement is looping over the results from the +value. Here the `for` statement is looping over the results from the `pairs() <iterators.html#pairs.i,seq[T]>`_ iterator from the `system <system.html>`_ module. Examples: @@ -1348,7 +1350,7 @@ Open arrays Often fixed-size arrays turn out to be too inflexible; procedures should be able to deal with arrays of different sizes. The `openarray`:idx: type allows -this. Openarrays are always indexed with an ``int`` starting at position 0. +this. Openarrays are always indexed with an `int` starting at position 0. The `len <system.html#len,TOpenArray>`_, `low <system.html#low,openArray[T]>`_ and `high <system.html#high,openArray[T]>`_ operations are available for open arrays too. Any array with a compatible base type can be passed to an @@ -1377,7 +1379,7 @@ supported because this is seldom needed and cannot be done efficiently. Varargs ------- -A ``varargs`` parameter is like an openarray parameter. However, it is +A `varargs` parameter is like an openarray parameter. However, it is also a means to implement passing a variable number of arguments to a procedure. The compiler converts the list of arguments to an array automatically: @@ -1409,7 +1411,7 @@ type conversions in this context: myWriteln(stdout, [$123, $"abc", $4.0]) In this example `$ <dollars.html>`_ is applied to any argument that is passed -to the parameter ``a``. Note that `$ <dollars.html>`_ applied to strings is a +to the parameter `a`. Note that `$ <dollars.html>`_ applied to strings is a nop. @@ -1441,7 +1443,7 @@ To understand some of the different ways of specifying the indices of strings, arrays, sequences, etc., it must be remembered that Nim uses zero-based indices. -So the string ``b`` is of length 19, and two different ways of specifying the +So the string `b` is of length 19, and two different ways of specifying the indices are .. code-block:: nim @@ -1451,22 +1453,22 @@ indices are 0 11 17 using indices ^19 ^8 ^2 using ^ syntax -where ``b[0 .. ^1]`` is equivalent to ``b[0 .. b.len-1]`` and ``b[0 ..< b.len]``, and it -can be seen that the ``^1`` provides a short-hand way of specifying the ``b.len-1``. See +where `b[0 .. ^1]` is equivalent to `b[0 .. b.len-1]` and `b[0 ..< b.len]`, and it +can be seen that the `^1` provides a short-hand way of specifying the `b.len-1`. See the `backwards index operator <system.html#^.t%2Cint>`_. In the above example, because the string ends in a period, to get the portion of the string that is "useless" and replace it with "useful". -``b[11 .. ^2]`` is the portion "useless", and ``b[11 .. ^2] = "useful"`` replaces the +`b[11 .. ^2]` is the portion "useless", and `b[11 .. ^2] = "useful"` replaces the "useless" portion with "useful", giving the result "Slices are useful." -Note 1: alternate ways of writing this are ``b[^8 .. ^2] = "useful"`` or -as ``b[11 .. b.len-2] = "useful"`` or as ``b[11 ..< b.len-1] = "useful"``. +Note 1: alternate ways of writing this are `b[^8 .. ^2] = "useful"` or +as `b[11 .. b.len-2] = "useful"` or as `b[11 ..< b.len-1] = "useful"`. -Note 2: As the ``^`` template returns a `distinct int <manual.html#types-distinct-type>`_ -of type ``BackwardsIndex``, we can have a ``lastIndex`` constant defined as ``const lastIndex = ^1``, -and later used as ``b[0 .. lastIndex]``. +Note 2: As the `^` template returns a `distinct int <manual.html#types-distinct-type>`_ +of type `BackwardsIndex`, we can have a `lastIndex` constant defined as `const lastIndex = ^1`, +and later used as `b[0 .. lastIndex]`. Objects ------- @@ -1476,7 +1478,7 @@ structure with a name is the object type. An object is a value type, which means that when an object is assigned to a new variable all its components are copied as well. -Each object type ``Foo`` has a constructor ``Foo(field: value, ...)`` +Each object type `Foo` has a constructor `Foo(field: value, ...)` where all of its fields can be initialized. Unspecified fields will get their default value. @@ -1510,7 +1512,7 @@ get their default value. Object fields that should be visible from outside the defining module have to -be marked with ``*``. +be marked with `*`. .. code-block:: nim :test: "nim c $1" @@ -1529,15 +1531,15 @@ Unlike object types though, tuple types are structurally typed, meaning different tuple-types are *equivalent* if they specify fields of the same type and of the same name in the same order. -The constructor ``()`` can be used to construct tuples. The order of the +The constructor `()` can be used to construct tuples. The order of the fields in the constructor must match the order in the tuple's definition. But unlike objects, a name for the tuple type may not be used here. -Like the object type the notation ``t.field`` is used to access a +Like the object type the notation `t.field` is used to access a tuple's field. Another notation that is not available for objects is -``t[i]`` to access the ``i``'th field. Here ``i`` must be a constant +`t[i]` to access the `i`'th field. Here `i` must be a constant integer. .. code-block:: nim @@ -1641,9 +1643,9 @@ untraced references are *unsafe*. However, for certain low-level operations Traced references are declared with the **ref** keyword; untraced references are declared with the **ptr** keyword. -The empty ``[]`` subscript notation can be used to *de-refer* a reference, -meaning to retrieve the item the reference points to. The ``.`` (access a -tuple/object field operator) and ``[]`` (array/string/sequence index operator) +The empty `[]` subscript notation can be used to *de-refer* a reference, +meaning to retrieve the item the reference points to. The `.` (access a +tuple/object field operator) and `[]` (array/string/sequence index operator) operators perform implicit dereferencing operations for reference types: .. code-block:: nim @@ -1659,18 +1661,18 @@ operators perform implicit dereferencing operations for reference types: n.data = 9 # no need to write n[].data; in fact n[].data is highly discouraged! -To allocate a new traced object, the built-in procedure ``new`` must be used. -To deal with untraced memory, the procedures ``alloc``, ``dealloc`` and -``realloc`` can be used. The `system <system.html>`_ +To allocate a new traced object, the built-in procedure `new` must be used. +To deal with untraced memory, the procedures `alloc`, `dealloc` and +`realloc` can be used. The `system <system.html>`_ module's documentation contains further details. -If a reference points to *nothing*, it has the value ``nil``. +If a reference points to *nothing*, it has the value `nil`. Procedural type --------------- A procedural type is a (somewhat abstract) pointer to a procedure. -``nil`` is an allowed value for a variable of a procedural type. +`nil` is an allowed value for a variable of a procedural type. Nim uses procedural types to achieve `functional`:idx: programming techniques. @@ -1708,7 +1710,7 @@ Nim supports splitting a program into pieces with a module concept. Each module is in its own file. Modules enable `information hiding`:idx: and `separate compilation`:idx:. A module may gain access to the symbols of another module by using the `import`:idx: statement. Only top-level symbols that are marked -with an asterisk (``*``) are exported: +with an asterisk (`*`) are exported: .. code-block:: nim # Module A @@ -1722,19 +1724,19 @@ with an asterisk (``*``) are exported: for i in 0..len(a)-1: result[i] = a[i] * b[i] when isMainModule: - # test the new ``*`` operator for sequences: + # test the new `*` operator for sequences: assert(@[1, 2, 3] * @[1, 2, 3] == @[1, 4, 9]) -The above module exports ``x`` and ``*``, but not ``y``. +The above module exports `x` and `*`, but not `y`. A module's top-level statements are executed at the start of the program. This can be used to initialize complex data structures for example. -Each module has a special magic constant ``isMainModule`` that is true if the +Each module has a special magic constant `isMainModule` that is true if the module is compiled as the main file. This is very useful to embed tests within the module as shown by the above example. -A symbol of a module *can* be *qualified* with the ``module.symbol`` syntax. And if +A symbol of a module *can* be *qualified* with the `module.symbol` syntax. And if a symbol is ambiguous, it *must* be qualified. A symbol is ambiguous if it is defined in two (or more) different modules and both modules are imported by a third one: @@ -1781,9 +1783,9 @@ rules apply: Excluding symbols ----------------- -The normal ``import`` statement will bring in all exported symbols. +The normal `import` statement will bring in all exported symbols. These can be limited by naming symbols that should be excluded using -the ``except`` qualifier. +the `except` qualifier. .. code-block:: nim import mymodule except y @@ -1792,14 +1794,14 @@ the ``except`` qualifier. From statement -------------- -We have already seen the simple ``import`` statement that just imports all +We have already seen the simple `import` statement that just imports all exported symbols. An alternative that only imports listed symbols is the -``from import`` statement: +`from import` statement: .. code-block:: nim from mymodule import x, y, z -The ``from`` statement can also force namespace qualification on +The `from` statement can also force namespace qualification on symbols, thereby making symbols available, but needing to be qualified in order to be used. @@ -1826,8 +1828,8 @@ define a shorter alias to use when qualifying symbols. Include statement ----------------- -The ``include`` statement does something fundamentally different than -importing a module: it merely includes the contents of a file. The ``include`` +The `include` statement does something fundamentally different than +importing a module: it merely includes the contents of a file. The `include` statement is useful to split up a large module into several files: .. code-block:: nim diff --git a/doc/tut2.rst b/doc/tut2.rst index e0d1bdb32..3aef6bb0f 100644 --- a/doc/tut2.rst +++ b/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 diff --git a/doc/tut3.rst b/doc/tut3.rst index b0a3d8232..358a9b45e 100644 --- a/doc/tut3.rst +++ b/doc/tut3.rst @@ -1,3 +1,5 @@ +.. default-role:: code + ======================= Nim Tutorial (Part III) ======================= |