diff --git a/doc/backends.md b/doc/backends.md
index 1347314614..4f94e82b1e 100644
--- a/doc/backends.md
+++ b/doc/backends.md
@@ -198,8 +198,7 @@ static C library.
Create a ``host.html`` file with the following content:
-.. code-block::
-
+ ```
+ ```
Create a ``calculator.nim`` file with the following content (or reuse the one
from the previous section):
diff --git a/doc/docgen.md b/doc/docgen.md
index 5f5c4ecc0d..a651d0a10d 100644
--- a/doc/docgen.md
+++ b/doc/docgen.md
@@ -67,11 +67,12 @@ Basic Markdown syntax is also supported inside the doc comments.
Example:
-.. code-block:: nim
+ ```nim
type Person* = object
## This type contains a description of a person
name: string
age: int
+ ```
Outputs::
Person* = object
@@ -82,9 +83,10 @@ Outputs::
Field documentation comments can be added to fields like so:
-.. code-block:: nim
+ ```nim
var numValues: int ## \
## `numValues` stores the number of values
+ ```
Note that without the `*` following the name of the type, the documentation for
this type would not be generated. Documentation will only be generated for
@@ -102,12 +104,13 @@ won't influence RST formatting.
If you still need to add an additional indentation at the very beginning
(for RST block quote syntax) use backslash \\ before it:
- .. code-block:: nim
- ## \
- ##
- ## Block quote at the first line.
- ##
- ## Paragraph.
+ ```nim
+ ## \
+ ##
+ ## Block quote at the first line.
+ ##
+ ## Paragraph.
+ ```
Document Types
@@ -248,9 +251,9 @@ the anchor [*]_ of Nim symbol that corresponds to link text.
If you have a constant:
- ```Nim
- const pi* = 3.14
- ```
+ ```Nim
+ const pi* = 3.14
+ ```
then it should be referenced in one of the 2 forms:
@@ -261,9 +264,9 @@ B. qualified (with symbol kind specification)::
For routine kinds there are more options. Consider this definition:
- ```Nim
- proc foo*(a: int, b: float): string
- ```
+ ```Nim
+ proc foo*(a: int, b: float): string
+ ```
Generally following syntax is allowed for referencing `foo`:
diff --git a/doc/docstyle.md b/doc/docstyle.md
index 79f7b4e105..1651a6e03f 100644
--- a/doc/docstyle.md
+++ b/doc/docstyle.md
@@ -72,12 +72,12 @@ Whenever an example of usage would be helpful to the user, you should include on
## truncating the result.
##
## ```
- ## # things that aren't suitable for a `runnableExamples` go in code-block:
+ ## # things that aren't suitable for a `runnableExamples` go in code block:
## echo execCmdEx("git pull")
## drawOnScreen()
## ```
runnableExamples:
- # `runnableExamples` is usually preferred to ``code-block``, when possible.
+ # `runnableExamples` is usually preferred to code blocks, when possible.
doAssert addThree(3, 125, 6) == -122
result = x +% y +% z
````
diff --git a/doc/manual.md b/doc/manual.md
index 7605a8b823..44f6ff7cb7 100644
--- a/doc/manual.md
+++ b/doc/manual.md
@@ -5083,10 +5083,7 @@ exception tracking.
There is also a way which can be used to forbid certain effects:
-.. code-block:: nim
- :test: "nim c --warningAsError:Effect:on $1"
- :status: 1
-
+ ```nim test = "nim c --warningAsError:Effect:on $1" status = 1
type IO = object ## input/output effect
proc readLine(): string {.tags: [IO].} = discard
proc echoLine(): void = discard
@@ -5096,13 +5093,14 @@ There is also a way which can be used to forbid certain effects:
echoLine()
# the compiler prevents this:
let y = readLine()
+ ```
The `forbids` pragma defines a list of illegal effects - if any statement
invokes any of those effects, the compilation will fail.
Procedure types with any disallowed effect are the subtypes of equal
procedure types without such lists:
-.. code-block:: nim
+ ```nim
type MyEffect = object
type ProcType1 = proc (i: int): void {.forbids: [MyEffect].}
type ProcType2 = proc (i: int): void
@@ -5123,6 +5121,7 @@ procedure types without such lists:
## these are OK because ProcType2 doesn't have any effect requirement:
caller2(toBeCalled1)
caller2(toBeCalled2)
+ ```
`ProcType2` is a subtype of `ProcType1`. Unlike with tags, the parent context - the function which calls other functions with forbidden effects - doesn't inherit the forbidden list of effects.
@@ -8079,18 +8078,20 @@ from C. The optional argument is a string containing the C identifier. If
the argument is missing, the C name is the Nim identifier *exactly as
spelled*:
-.. code-block::
+ ```nim
proc printf(formatstr: cstring) {.header: "", importc: "printf", varargs.}
+ ```
When `importc` is applied to a `let` statement it can omit its value which
will then be expected to come from C. This can be used to import a C `const`:c:\:
-.. code-block::
+ ```nim
{.emit: "const int cconst = 42;".}
let cconst {.importc, nodecl.}: cint
assert cconst == 42
+ ```
Note that this pragma has been abused in the past to also work in the
JS backend for JS objects and functions. Other backends do provide
diff --git a/doc/manual/var_t_return.md b/doc/manual/var_t_return.md
index f5c5bc4c0b..15d908c74b 100644
--- a/doc/manual/var_t_return.md
+++ b/doc/manual/var_t_return.md
@@ -6,7 +6,7 @@ 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
+ ```nim
proc forward[T](x: var T): var T =
result = x # ok, derived from the first parameter.
@@ -17,6 +17,7 @@ then it has to be derived from the routine's first parameter:
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
lifetime of the first parameter and that is enough knowledge to verify
diff --git a/doc/manual_experimental_strictnotnil.md b/doc/manual_experimental_strictnotnil.md
index 047fc916f7..b6d8e796e2 100644
--- a/doc/manual_experimental_strictnotnil.md
+++ b/doc/manual_experimental_strictnotnil.md
@@ -6,13 +6,15 @@ Strict not nil checking
**Note:** This feature is experimental, you need to enable it with
-.. code-block:: nim
+ ```nim
{.experimental: "strictNotNil".}
+ ```
or
-.. code-block:: cmd
+ ```cmd
nim c --experimental:strictNotNil
+ ```
In the second case it would check builtin and imported modules as well.
@@ -39,7 +41,7 @@ not nil
You can annotate a type where nil isn't a valid value with `not nil`.
-.. code-block:: nim
+ ```nim
type
NilableObject = ref object
a: int
@@ -57,6 +59,7 @@ You can annotate a type where nil isn't a valid value with `not nil`.
p(x)
else:
p(x) # ok
+ ```
@@ -118,14 +121,16 @@ call args rules
When we call with arguments, we have two cases when we might change the nilability.
-.. code-block:: nim
+ ```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).
-.. code-block:: nim
+ ```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`. Dependants become `MaybeNil`.
@@ -141,13 +146,14 @@ When branches "join" we usually unify their expression maps or/and nilabilities.
Merging usually merges maps and alias sets: nilabilities are merged like this:
-.. code-block:: nim
+ ```nim
template union(l: Nilability, r: Nilability): Nilability =
## unify two states
if l == r:
l
else:
MaybeNil
+ ```
Special handling is for `.isNil` and `== nil`, also for `not`, `and` and `or`.
@@ -183,8 +189,9 @@ element tracking
When we assign an object construction, we should track the fields as well:
-.. code-block:: nim
+ ```nim
var a = Nilable(field: Nilable()) # a : Safe, a.field: Safe
+ ```
Usually we just track the result of an expression: probably this should apply for elements in other cases as well.
Also related to tracking initialization of expressions/fields.
@@ -195,12 +202,13 @@ 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 run 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
+ ```nim
for a in c:
if not a.isNil:
b()
break
code # here a: Nil , because if not, we would have breaked
+ ```
aliasing
@@ -214,17 +222,19 @@ Assignments and other changes to nilability can move / move out expressions of s
`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
+ ```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.
e.g.
-.. code-block:: nim
+ ```nim
var left = b
left = nil # moving out
+ ```
initialization of non nilable and nilable values
diff --git a/doc/nep1.md b/doc/nep1.md
index 9627071bf5..ea928b82e1 100644
--- a/doc/nep1.md
+++ b/doc/nep1.md
@@ -49,7 +49,7 @@ Spacing and Whitespace Conventions
Not all editors support automatic alignment of code sections, and re-aligning
long sections of code by hand can quickly become tedious.
- .. code-block:: nim
+ ```nim
# This is bad, as the next time someone comes
# to edit this code block, they
# must re-align all the assignments again:
@@ -60,6 +60,7 @@ Spacing and Whitespace Conventions
CalId* = int
LongLong* = int64
LongLongPtr* = ptr LongLong
+ ```
Naming Conventions
@@ -69,7 +70,7 @@ Naming Conventions
camelCase with the exception of constants which **may** use PascalCase but
are not required to.
- .. code-block:: nim
+ ```nim
# Constants can start with either a lower case or upper case letter.
const aConstant = 42
const FooBar = 4.2
@@ -79,6 +80,7 @@ Naming Conventions
# Types must start with an uppercase letter.
type
FooBar = object
+ ```
For constants coming from a C/C++ wrapper, ALL_UPPERCASE are allowed, but ugly.
(Why shout CONSTANT? Constants do no harm, variables do!)
@@ -89,41 +91,45 @@ Naming Conventions
that will be used the most, add the suffixes to the pointer variants only. The
same applies to C/C++ wrappers.
- .. code-block:: nim
+ ```nim
type
Handle = object # Will be used most often
fd: int64
HandleRef = ref Handle # Will be used less often
+ ```
- Exception and Error types should have the "Error" or "Defect" suffix.
- .. code-block:: nim
+ ```nim
type
ValueError = object of CatchableError
AssertionDefect = object of Defect
Foo = object of Exception # bad style, try to inherit CatchableError or Defect
+ ```
- Unless marked with the `{.pure.}` pragma, members of enums should have an
identifying prefix, such as an abbreviation of the enum's name.
- .. code-block:: nim
+ ```nim
type
PathComponent = enum
pcDir
pcLinkToDir
pcFile
pcLinkToFile
+ ```
- Non-pure enum values should use camelCase whereas pure enum values should use
PascalCase.
- .. code-block:: nim
+ ```nim
type
PathComponent {.pure.} = enum
Dir
LinkToDir
File
LinkToFile
+ ```
- 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
@@ -230,12 +236,13 @@ Coding Conventions
are required. Use a procedure's implicit `result` variable whenever possible.
This improves readability.
- .. code-block:: nim
+ ```nim
proc repeat(text: string, x: int): string =
result = ""
for i in 0..x:
result.add($i)
+ ```
- Use a proc when possible, only using the more powerful facilities of macros,
templates, iterators, and converters when necessary.
@@ -252,15 +259,16 @@ Conventions for multi-line statements and expressions
- Tuples which are longer than one line should indent their parameters to
align with the parameters above it.
- .. code-block:: nim
+ ```nim
type
LongTupleA = tuple[wordyTupleMemberOne: int, wordyTupleMemberTwo: string,
wordyTupleMemberThree: float]
+ ```
- Similarly, any procedure and procedure type declarations that are longer
than one line should do the same thing.
- .. code-block:: nim
+ ```nim
type
EventCallback = proc (timeReceived: Time, errorCode: int, event: Event,
output: var string)
@@ -268,13 +276,15 @@ Conventions for multi-line statements and expressions
proc lotsOfArguments(argOne: string, argTwo: int, argThree: float,
argFour: proc(), argFive: bool): int
{.heyLookALongPragma.} =
+ ```
- Multi-line procedure calls should continue on the same column as the opening
parenthesis (like multi-line procedure declarations).
- .. code-block:: nim
+ ```nim
startProcess(nimExecutable, currentDirectory, compilerArguments
environment, processOptions)
+ ```
Miscellaneous
-------------
@@ -290,18 +300,20 @@ Miscellaneous
use this:
- .. code-block:: nim
+ ```nim
let a = """
foo
bar
"""
+ ```
instead of:
- .. code-block:: nim
+ ```nim
let a = """foo
bar
"""
+ ```
- A getter API for a private field `foo` should preferably be named `foo`, not `getFoo`.
A getter-like API should preferably be named `getFoo`, not `foo` if:
diff --git a/doc/nimc.md b/doc/nimc.md
index 28a917d923..cd980a37bd 100644
--- a/doc/nimc.md
+++ b/doc/nimc.md
@@ -219,15 +219,15 @@ 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:
-.. code:: cmd
-
+ ```cmd
nim c -d:release myproject.nim
+ ```
To compile a `dangerous release build`:idx: define the `danger` symbol:
-.. code:: cmd
-
+ ```cmd
nim c -d:danger myproject.nim
+ ```
Search path handling
@@ -281,9 +281,9 @@ Compiler Selection
To change the compiler from the default compiler (at the command line):
-.. code:: cmd
-
+ ```cmd
nim c --cc:llvm_gcc --compile_only myfile.nim
+ ```
This uses the configuration defined in ``config\nim.cfg`` for `llvm_gcc`:cmd:.
@@ -303,18 +303,18 @@ Cross-compilation
To cross compile, use for example:
-.. code:: cmd
-
+ ```cmd
nim c --cpu:i386 --os:linux --compileOnly --genScript myproject.nim
+ ```
Then move the C code and the compile script `compile_myproject.sh`:cmd: to your
Linux i386 machine and run the script.
Another way is to make Nim invoke a cross compiler toolchain:
-.. code:: cmd
-
+ ```cmd
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
@@ -330,22 +330,22 @@ Cross-compilation for Windows
To cross-compile for Windows from Linux or macOS using the MinGW-w64 toolchain:
-.. code:: cmd
-
+ ```cmd
nim c -d:mingw myproject.nim
# `nim r` also works, running the binary via `wine` or `wine64`:
nim r -d:mingw --eval:'import os; echo "a" / "b"'
+ ```
Use `--cpu:i386`:option: or `--cpu:amd64`:option: to switch the CPU architecture.
The MinGW-w64 toolchain can be installed as follows:
-.. code:: cmd
-
+ ```cmd
apt install mingw-w64 # Ubuntu
yum install mingw32-gcc
yum install mingw64-gcc # CentOS - requires EPEL
brew install mingw-w64 # OSX
+ ```
Cross-compilation for Android
@@ -380,11 +380,11 @@ stuff is done, it's very important to call `NimMain()`:c: in order to
initialize Nim's garbage collector and to run the top level statements
of your program.
-.. code-block:: Nim
-
+ ```Nim
proc NimMain() {.importc.}
proc glfmMain*(display: ptr GLFMDisplay) {.exportc.} =
NimMain() # initialize garbage collector memory, types and stack
+ ```
The name `NimMain` can be influenced via the `--nimMainPrefix:prefix` switch.
@@ -410,11 +410,11 @@ the iOS setup is done, it's very important to call `NimMain()`:c: to
initialize Nim's garbage collector and to run the top-level statements
of your program.
-.. code-block:: Nim
-
+ ```Nim
proc NimMain() {.importc.}
proc glfmMain*(display: ptr GLFMDisplay) {.exportc.} =
NimMain() # initialize garbage collector memory, types and stack
+ ```
Note: XCode's "make clean" gets confused about the generated nim.c files,
so you need to clean those files manually to do a clean build.
@@ -430,9 +430,10 @@ Simply add `--os:nintendoswitch`:option:
to your usual `nim c`:cmd: or `nim cpp`:cmd: command and set the `passC`:option:
and `passL`:option: command line switches to something like:
-.. code-block:: cmd
+ ```cmd
nim c ... --d:nimAllocPagesViaMalloc --mm:orc --passC="-I$DEVKITPRO/libnx/include" ...
--passL="-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx"
+ ```
or setup a ``nim.cfg`` file like so::
@@ -448,9 +449,9 @@ The devkitPro setup must be the same as the default with their new installer
For example, with the above-mentioned config:
-.. code:: cmd
-
+ ```cmd
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`:cmd: tool in the devkitPro release. Examples can be found at
@@ -475,15 +476,15 @@ 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:
-.. code:: cmd
-
+ ```cmd
nim c -d:release lib/nimrtl.nim
+ ```
To link against ``nimrtl.dll`` use the command:
-.. code:: cmd
-
+ ```cmd
nim c -d:useNimRtl myprog.nim
+ ```
**Note**: Currently the creation of ``nimrtl.dll`` with thread support has
never been tested and is unlikely to work!
@@ -578,9 +579,9 @@ can be prevented and then via `--passL`:option: the static library can be linked
against. For instance, to link statically against Lua this command might work
on Linux:
-.. code:: cmd
-
+ ```cmd
nim c --dynlibOverride:lua --passL:liblua.lib program.nim
+ ```
Backend language options
@@ -635,9 +636,9 @@ 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:
-.. code:: cmd
-
- nim c --os:any --mm:arc -d:useMalloc [...] x.nim
+ ```cmd
+ nim c --os:any --mm:arc -d:useMalloc [...] x.nim
+ ```
- `--mm:arc`:option: will enable the reference counting memory management instead
of the default garbage collector. This enables Nim to use heap memory which
@@ -760,28 +761,32 @@ passed to subroutines. The compiler does not copy strings that are a result of
a procedure call, because the callee returns a new string anyway.
Thus it is efficient to do:
-.. code-block:: Nim
+ ```Nim
var s = procA() # assignment will not copy the string; procA allocates a new
# string already
+ ```
However, it is not efficient to do:
-.. code-block:: Nim
+ ```Nim
var s = varA # assignment has to copy the whole string into a new buffer!
+ ```
For `let` symbols a copy is not always necessary:
-.. code-block:: Nim
+ ```Nim
let s = varA # may only copy a pointer if it safe to do so
+ ```
If you know what you're doing, you can also mark single-string (or sequence)
objects as `shallow`:idx:\:
-.. code-block:: Nim
+ ```Nim
var s = "abc"
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
anymore, similar to Ruby's `freeze`:idx:.
@@ -791,7 +796,7 @@ The compiler optimizes string case statements: A hashing scheme is used for them
if several different string constants are used. So code like this is reasonably
efficient:
-.. code-block:: Nim
+ ```Nim
case normalize(k.key)
of "name": c.name = v
of "displayname": c.displayName = v
@@ -807,3 +812,4 @@ efficient:
else: quit(errorStr(p, "expected: console or gui"))
of "license": c.license = UnixToNativePath(k.value)
else: quit(errorStr(p, "unknown variable: " & k.key))
+ ```
diff --git a/doc/nimgrep.md b/doc/nimgrep.md
index ff2bf3a8d3..e000efb464 100644
--- a/doc/nimgrep.md
+++ b/doc/nimgrep.md
@@ -22,8 +22,9 @@ Installation
Compile nimgrep with the command:
-.. code:: cmd
+ ```cmd
nim c -d:release tools/nimgrep.nim
+ ```
And copy the executable somewhere in your ``$PATH``.
@@ -40,9 +41,10 @@ All examples below use default PCRE Regex patterns:
+ To search recursively in Nim files using style-insensitive identifiers:
- .. code:: cmd
+ ```cmd
nimgrep --recursive --ext:'nim|nims' --ignoreStyle
# short: -r --ext:'nim|nims' -y
+ ```
.. Note:: we used `'` quotes to avoid special treatment of `|` symbol
for shells like Bash
@@ -50,15 +52,17 @@ All examples below use default PCRE Regex patterns:
+ To exclude version control directories (Git, Mercurial=hg, Subversion=svn)
from the search:
- .. code:: cmd
+ ```cmd
nimgrep --excludeDir:'^\.git$' --excludeDir:'^\.hg$' --excludeDir:'^\.svn$'
# short: --ed:'^\.git$' --ed:'^\.hg$' --ed:'^\.svn$'
+ ```
+ To search only in paths containing the `tests` sub-directory recursively:
- .. code:: cmd
+ ```cmd
nimgrep --recursive --includeDir:'(^|/)tests($|/)'
# short: -r --id:'(^|/)tests($|/)'
+ ```
.. Attention:: note the subtle difference between `--excludeDir`:option: and
`--includeDir`:option:\: the former is applied to relative directory entries
diff --git a/doc/nims.md b/doc/nims.md
index 4141c3bdc0..5870f7bb61 100644
--- a/doc/nims.md
+++ b/doc/nims.md
@@ -118,22 +118,24 @@ NimScript. Similarly, command-line `--FOO:VAL`:option: translates to
Here are few examples of using the `switch` proc:
-.. code-block:: nim
+ ```nim
# command-line: --opt:size
switch("opt", "size")
# command-line: --define:release or -d:release
switch("define", "release")
# command-line: --forceBuild
switch("forceBuild")
+ ```
NimScripts also support `--`:option: templates for convenience, which look
like command-line switches written as-is in the NimScript file. So the
above example can be rewritten as:
-.. code-block:: nim
+ ```nim
--opt:size
--define:release
--forceBuild
+ ```
**Note**: In general, the *define* switches can also be set in
NimScripts using `switch` or `--`, as shown in above examples. Few
@@ -148,9 +150,10 @@ 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`:option: command:
-.. code-block:: nim
+ ```nim
task build, "builds an example":
setCommand "c"
+ ```
In fact, as a convention the following tasks should be available:
@@ -184,8 +187,7 @@ NimScript can also be used directly as a portable replacement for Bash and
Batch files. Use `nim myscript.nims`:cmd: to run ``myscript.nims``. For example,
installation of Nimble could be accomplished with this simple script:
-.. code-block:: nim
-
+ ```nim
mode = ScriptMode.Verbose
var id = 0
@@ -198,16 +200,17 @@ installation of Nimble could be accomplished with this simple script:
exec "nim c nimble"
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``:
-.. code-block:: nim
-
+ ```nim
#!/usr/bin/env nim
mode = ScriptMode.Silent
echo "hello world"
+ ```
Use `#!/usr/bin/env -S nim --hints:off` to disable hints.
@@ -229,8 +232,7 @@ allowing the same script to support a lot of systems.
See the following (incomplete) example:
-.. code-block:: nim
-
+ ```nim
import std/distros
# Architectures.
@@ -256,6 +258,7 @@ See the following (incomplete) example:
echo "Distro is ArchLinux"
elif detectOs(Debian):
echo "Distro is Debian"
+ ```
Uniform Syntax
@@ -277,21 +280,21 @@ making it ideal for functional scripting metaprogramming.
This is an example of a third party module that uses macros and templates to
translate text strings on unmodified NimScript:
-.. code-block:: nim
-
+ ```nim
import nimterlingua
nimterlingua("translations.cfg")
echo "cat" # Run with -d:RU becomes "kot", -d:ES becomes "gato", ...
+ ```
translations.cfg
-.. code-block:: none
-
+ ```none
[cat]
ES = gato
IT = gatto
RU = kot
FR = chat
+ ```
* `Nimterlingua `_
@@ -305,8 +308,7 @@ but often a graceful and seamless fallback degradation is used.
See the following NimScript:
-.. code-block:: nim
-
+ ```nim
if likely(true):
discard
elif unlikely(false):
@@ -316,6 +318,7 @@ See the following NimScript:
static:
echo CompileDate
+ ```
`likely()`, `unlikely()`, `static:` and `{.compiletime.}`
diff --git a/doc/nimsuggest.md b/doc/nimsuggest.md
index 82693da0eb..f542cab197 100644
--- a/doc/nimsuggest.md
+++ b/doc/nimsuggest.md
@@ -29,8 +29,9 @@ Installation
Nimsuggest is part of Nim's core. Build it via:
-.. code:: cmd
+ ```cmd
koch nimsuggest
+ ```
Nimsuggest invocation
diff --git a/doc/packaging.md b/doc/packaging.md
index 7976dfe92f..6445017271 100644
--- a/doc/packaging.md
+++ b/doc/packaging.md
@@ -48,24 +48,24 @@ The Debian package ships bash and ksh completion and manpages that can be reused
Hints on the build process:
-.. code:: cmd
+ ```cmd
+ # build from C sources and then using koch
+ make -j # supports parallel build
+ # alternatively: ./build.sh --os $os_type --cpu $cpu_arch
+ ./bin/nim c -d:release koch
+ ./koch boot -d:release
- # build from C sources and then using koch
- make -j # supports parallel build
- # alternatively: ./build.sh --os $os_type --cpu $cpu_arch
- ./bin/nim c -d:release koch
- ./koch boot -d:release
+ # optionally generate docs into doc/html
+ ./koch docs
- # optionally generate docs into doc/html
- ./koch docs
+ ./koch tools
- ./koch tools
+ # extract files to be really installed
+ ./install.sh
- # extract files to be really installed
- ./install.sh
-
- # also include the tools
- for fn in nimble nimsuggest nimgrep; do cp ./bin/$fn /nim/bin/; done
+ # also include the tools
+ for fn in nimble nimsuggest nimgrep; do cp ./bin/$fn /nim/bin/; done
+ ```
What to install:
diff --git a/doc/pegdocs.txt b/doc/pegdocs.txt
index 2ef4e2c152..99d9d784cf 100644
--- a/doc/pegdocs.txt
+++ b/doc/pegdocs.txt
@@ -175,8 +175,9 @@ The PEG parser implements this grammar (written in PEG syntax)::
expression, identifiers are not interpreted as non-terminals, but are
interpreted as verbatim string:
-.. code-block:: nim
+ ```nim
abc =~ peg"abc" # is true
+ ```
So it is not necessary to write ``peg" 'abc' "`` in the above example.
@@ -186,22 +187,25 @@ Examples
Check if `s` matches Nim's "while" keyword:
-.. code-block:: nim
+ ```nim
s =~ peg" y'while'"
+ ```
Exchange (key, val)-pairs:
-.. code-block:: nim
+ ```nim
"key: val; key2: val2".replacef(peg"{\ident} \s* ':' \s* {\ident}", "$2: $1")
+ ```
Determine the ``#include``'ed files of a C file:
-.. code-block:: nim
+ ```nim
for line in lines("myfile.c"):
if line =~ peg"""s <- ws '#include' ws '"' {[^"]+} '"' ws
comment <- '/*' @ '*/' / '//' .*
ws <- (comment / \s+)* """:
echo matches[0]
+ ```
PEG vs regular expression
-------------------------
diff --git a/doc/refc.md b/doc/refc.md
index 766097f23b..504ba386c8 100644
--- a/doc/refc.md
+++ b/doc/refc.md
@@ -16,9 +16,10 @@ defined via `--define:useRealtimeGC`:option: (you can put this into your config
file as well).
With this switch the garbage collector supports the following operations:
-.. code-block:: nim
+ ```nim
proc GC_setMaxPause*(maxPauseInUs: int)
proc GC_step*(us: int, strongAdvice = false, stackSize = -1)
+ ```
The unit of the parameters `maxPauseInUs` and `us` is microseconds.
@@ -98,9 +99,9 @@ As long as you don't use the threadvar emulation Nim uses native thread
variables, of which you get a fresh version whenever you create a thread. You
can then attach a GC to this thread via
-.. code-block:: nim
-
+ ```nim
system.setupForeignThreadGc()
+ ```
It is **not** safe to disable the garbage collector and enable it after the
call from your background thread even if the code you are calling is short
@@ -109,10 +110,9 @@ lived.
Before the thread exits, you should tear down the thread's GC to prevent memory
leaks by calling
-.. code-block:: nim
-
+ ```nim
system.tearDownForeignThreadGc()
-
+ ```
Keeping track of memory
diff --git a/doc/sets_fragment.txt b/doc/sets_fragment.txt
index 1929a7b919..bc81897322 100644
--- a/doc/sets_fragment.txt
+++ b/doc/sets_fragment.txt
@@ -13,9 +13,9 @@ range `0 .. MaxSetElements-1` where `MaxSetElements` is currently always
The reason is that sets are implemented as high performance bit vectors.
Attempting to declare a set with a larger type will result in an error:
-.. code-block:: nim
-
+ ```nim
var s: set[int64] # Error: set is too large
+ ```
**Note:** Nim also offers `hash sets `_ (which you need to import
with `import sets`), which have no such restrictions.
@@ -24,7 +24,7 @@ Sets can be constructed via the set constructor: `{}` is the empty set. The
empty set is type compatible with any concrete set type. The constructor
can also be used to include elements (and ranges of elements):
-.. code-block:: nim
+ ```nim
type
CharSet = set[char]
var
@@ -32,6 +32,7 @@ can also be used to include elements (and ranges of elements):
x = {'a'..'z', '0'..'9'} # This constructs a set that contains the
# letters from 'a' to 'z' and the digits
# from '0' to '9'
+ ```
These operations are supported by sets:
@@ -60,8 +61,7 @@ constants that have to be `or`'ed together.
Enum, sets and casting can be used together as in:
-.. code-block:: nim
-
+ ```nim
type
MyFlag* {.size: sizeof(cint).} = enum
A
@@ -79,6 +79,7 @@ Enum, sets and casting can be used together as in:
assert toNum({A, C}) == 5
assert toFlags(0) == {}
assert toFlags(7) == {A, B, C}
+ ```
Note how the set turns enum values into powers of 2.
diff --git a/doc/spawn.txt b/doc/spawn.txt
index c437e8aa32..6c80d292b2 100644
--- a/doc/spawn.txt
+++ b/doc/spawn.txt
@@ -28,7 +28,7 @@ the passed expression on the thread pool and returns a `data flow variable`:idx:
**blocking**. However, one can use ``blockUntilAny`` to wait on multiple flow
variables at the same time:
-.. code-block:: nim
+ ```nim
import std/threadpool, ...
# wait until 2 out of 3 servers received the update:
@@ -40,6 +40,7 @@ variables at the same time:
assert index >= 0
responses.del(index)
discard blockUntilAny(responses)
+ ```
Data flow variables ensure that no data races
are possible. Due to technical limitations not every type ``T`` is possible in
@@ -54,7 +55,7 @@ Parallel statement
Example:
-.. code-block:: nim
+ ```nim
# Compute PI in an inefficient way
import std/[strutils, math, threadpool]
@@ -69,6 +70,7 @@ Example:
result += ch[k]
echo formatFloat(pi(5000))
+ ```
The parallel statement is the preferred mechanism to introduce parallelism
diff --git a/doc/subexes.txt b/doc/subexes.txt
index 62ddd1ec8f..1bfd602131 100644
--- a/doc/subexes.txt
+++ b/doc/subexes.txt
@@ -47,8 +47,7 @@ Notation meaning
Examples
========
-.. code-block:: nim
-
+ ```nim
subex"$1($', '{2..})" % ["f", "a", "b", "c"] == "f(a, b, c)"
subex"$1 $[files|file|files]{1} copied" % ["1"] == "1 file copied"
@@ -57,5 +56,5 @@ Examples
subex("type\n TEnum = enum\n $', '40c'\n '{..}") % [
"fieldNameA", "fieldNameB", "fieldNameC", "fieldNameD"]
-
+ ```
diff --git a/doc/testament.md b/doc/testament.md
index 140e444421..89e3da44d6 100644
--- a/doc/testament.md
+++ b/doc/testament.md
@@ -53,29 +53,29 @@ Running a single test
This is a minimal example to understand the basics,
not very useful for production, but easy to understand:
-.. code:: console
-
+ ```console
$ mkdir tests
$ echo "assert 42 == 42" > tests/test0.nim
$ testament run test0.nim
PASS: tests/test0.nim C ( 0.2 sec)
$ testament r test0
PASS: tests/test0.nim C ( 0.2 sec)
+ ```
Running all tests from a directory
==================================
-.. code:: console
-
+ ```console
$ testament pattern "tests/*.nim"
+ ```
To search for tests deeper in a directory, use
-.. code:: console
-
+ ```console
$ testament pattern "tests/**/*.nim" # one level deeper
$ testament pattern "tests/**/**/*.nim" # two levels deeper
+ ```
HTML Reports
============
@@ -83,9 +83,9 @@ HTML Reports
Generate HTML Reports ``testresults.html`` from unittests,
you have to run at least 1 test *before* generating a report:
-.. code:: console
-
+ ```console
$ testament html
+ ```
Writing Unit tests
@@ -93,8 +93,7 @@ Writing Unit tests
Example "template" **to edit** and write a Testament unittest:
-.. code-block:: nim
-
+ ```nim
discard """
# What actions to expect completion on.
@@ -182,6 +181,7 @@ Example "template" **to edit** and write a Testament unittest:
"""
assert true
assert 42 == 42, "Assert error message"
+ ```
* As you can see the "Spec" is just a `discard """ """`.
@@ -197,26 +197,25 @@ Unit test Examples
Expected to fail:
-.. code-block:: nim
-
+ ```nim
discard """
errormsg: "undeclared identifier: 'not_defined'"
"""
assert not_defined == "not_defined", "not_defined is not defined"
+ ```
Non-Zero exit code:
-.. code-block:: nim
-
+ ```nim
discard """
exitcode: 1
"""
quit "Non-Zero exit code", 1
+ ```
Standard output checking:
-.. code-block:: nim
-
+ ```nim
discard """
output: '''
@@ -230,32 +229,33 @@ Standard output checking:
"""
for i in 0..5: echo i
+ ```
JavaScript tests:
-.. code-block:: nim
-
+ ```nim
discard """
targets: "js"
"""
when defined(js):
import std/jsconsole
console.log("My Frontend Project")
+ ```
Compile-time tests:
-.. code-block:: nim
-
+ ```nim
discard """
action: "compile"
"""
static: assert 9 == 9, "Compile time assert"
+ ```
Tests without Spec:
-.. code-block:: nim
-
+ ```nim
assert 1 == 1
+ ```
See also:
diff --git a/doc/tut1.md b/doc/tut1.md
index f3584a423b..de671577e0 100644
--- a/doc/tut1.md
+++ b/doc/tut1.md
@@ -12,10 +12,7 @@ Nim Tutorial (Part I)
Introduction
============
-.. raw:: html
-
- "Der Mensch ist doch ein Augentier -- schöne Dinge wünsch ich mir."
-
+> "Der Mensch ist doch ein Augentier -- Schöne Dinge wünsch' ich mir."
This document is a tutorial for the programming language *Nim*.
@@ -40,12 +37,12 @@ The first program
We start the tour with a modified "hello world" program:
-.. code-block:: Nim
- :test: "nim c $1"
+ ```Nim test = "nim c $1"
# This is a comment
echo "What's your name? "
var name: string = readLine(stdin)
echo "Hi, ", name, "!"
+ ```
Save this code to the file "greetings.nim". Now compile and run it::
@@ -89,9 +86,9 @@ compiler knows that `readLine `_ returns a string,
you can leave out the type in the declaration (this is called `local type
inference`:idx:). So this will work too:
-.. code-block:: Nim
- :test: "nim c $1"
+ ```Nim test = "nim c $1"
var name = readLine(stdin)
+ ```
Note that this is basically the only form of type inference that exists in
Nim: it is a good compromise between brevity and readability.
@@ -117,8 +114,9 @@ String literals are enclosed in double-quotes; character literals in single
quotes. Special characters are escaped with ``\``: ``\n`` means newline, ``\t``
means tabulator, etc. There are also *raw* string literals:
-.. code-block:: Nim
+ ```Nim
r"C:\program files\nim"
+ ```
In raw literals, the backslash is not an escape character.
@@ -134,11 +132,11 @@ Comments
Comments start anywhere outside a string or character literal with the
hash character `#`. Documentation comments start with `##`:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
# A comment.
var myVariable: int ## a documentation comment
+ ```
Documentation comments are tokens; they are only allowed at certain places in
@@ -148,8 +146,7 @@ documentation generators.
Multiline comments are started with `#[` and terminated with `]#`. Multiline
comments can also be nested.
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
#[
You can have any Nim code text commented
out inside this with no indentation restrictions.
@@ -158,6 +155,7 @@ comments can also be nested.
Note: these can be nested!!
]#
]#
+ ```
Numbers
@@ -175,18 +173,19 @@ The var statement
=================
The var statement declares a new local or global variable:
-.. code-block::
+ ```nim
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
variables:
-.. code-block::
- :test: "nim c $1"
+ ```nim test = "nim c $1"
var
x, y: int
# a comment can occur here too
a, b, c: string
+ ```
Constants
@@ -196,20 +195,20 @@ Constants are symbols which are bound to a value. The constant's value
cannot change. The compiler must be able to evaluate the expression in a
constant declaration at compile time:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim 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
constants:
-.. code-block::
- :test: "nim c $1"
+ ```nim test = "nim c $1"
const
x = 1
# a comment can occur here too
y = 2
z = y + 5 # computations are possible
+ ```
The let statement
@@ -218,20 +217,22 @@ The `let` statement works like the `var` statement but the declared
symbols are *single assignment* variables: After the initialization their
value cannot change:
-.. code-block::
+ ```nim
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
and put it into a data section":
-.. code-block::
+ ```nim
const input = readLine(stdin) # Error: constant expression expected
+ ```
-.. code-block::
- :test: "nim c $1"
+ ```nim test = "nim c $1"
let input = readLine(stdin) # works
+ ```
The assignment statement
@@ -240,22 +241,23 @@ The assignment statement
The assignment statement assigns a new value to a variable or more generally
to a storage location:
-.. code-block::
+ ```nim
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
overloaded. You can declare multiple variables with a single assignment
statement and all the variables will have the same value:
-.. code-block::
- :test: "nim c $1"
+ ```nim test = "nim c $1"
var x, y = 3 # assigns 3 to the variables `x` and `y`
echo "x ", x # outputs "x 3"
echo "y ", y # outputs "y 3"
x = 42 # changes `x` to 42 without changing `y`
echo "x ", x # outputs "x 42"
echo "y ", y # outputs "y 3"
+ ```
Control flow statements
@@ -271,8 +273,7 @@ If statement
The if statement is one way to branch the control flow:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
let name = readLine(stdin)
if name == "":
echo "Poor soul, you lost your name?"
@@ -280,6 +281,7 @@ The if statement is one way to branch the control flow:
echo "Very funny, your name is name."
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
@@ -293,8 +295,7 @@ Case statement
Another way to branch is provided by the case statement. A case statement allows
for multiple branches:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
let name = readLine(stdin)
case name
of "":
@@ -305,6 +306,7 @@ for multiple branches:
echo "Cool name!"
else:
echo "Hi, ", name, "!"
+ ```
As it can be seen, for an `of` branch a comma-separated list of values is also
allowed.
@@ -313,7 +315,7 @@ The case statement can deal with integers, other ordinal types, and strings.
(What an ordinal type is will be explained soon.)
For integers or other ordinal types value ranges are also possible:
-.. code-block:: nim
+ ```nim
# this statement will be explained later:
from std/strutils import parseInt
@@ -322,6 +324,7 @@ For integers or other ordinal types value ranges are also possible:
case n
of 0..2, 4..7: echo "The number is in the set: {0, 1, 2, 4, 5, 6, 7}"
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
@@ -329,12 +332,13 @@ every value that `n` may contain, but the code only handles the values
(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:
-.. code-block:: nim
+ ```nim
...
case n
of 0..2, 4..7: echo "The number is in the set: {0, 1, 2, 4, 5, 6, 7}"
of 3, 8: echo "The number is 3 or 8"
else: discard
+ ```
The empty `discard statement <#procedures-discard-statement>`_ is a *do
nothing* statement. The compiler knows that a case statement with an else part
@@ -352,14 +356,13 @@ While statement
The while statement is a simple looping construct:
-.. code-block:: nim
- :test: "nim c $1"
-
+ ```nim test = "nim c $1"
echo "What's your name? "
var name = readLine(stdin)
while name == "":
echo "Please tell me your name: "
name = readLine(stdin) # 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).
@@ -372,73 +375,79 @@ The `for` statement is a construct to loop over any element an *iterator*
provides. The example uses the built-in `countup
`_ iterator:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
echo "Counting to ten: "
for i in countup(1, 10):
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
`_ returns. `i` runs through the values
1, 2, .., 10. Each value is `echo`-ed. This code does the same:
-.. code-block:: nim
+ ```nim
echo "Counting to 10: "
var i = 1
while i <= 10:
echo i
inc i # increment i by 1
# --> Outputs 1 2 3 4 5 6 7 8 9 10 on different lines
+ ```
Since counting up occurs so often in programs, Nim also has a `..
`_ iterator that does the same:
-.. code-block:: nim
+ ```nim
for i in 1 .. 10:
...
+ ```
Counting down can be achieved as easily (but is less often needed):
-.. code-block:: nim
+ ```nim
echo "Counting down from 10 to 1: "
for i in countdown(10, 1):
echo i
# --> Outputs 10 9 8 7 6 5 4 3 2 1 on different lines
+ ```
Zero-indexed counting has two shortcuts `..<` and `.. ^1`
(`backward index operator `_) to simplify
counting to one less than the higher index:
-.. code-block:: nim
+ ```nim
for i in 0 ..< 10:
... # the same as 0 .. 9
+ ```
or
-.. code-block:: nim
+ ```nim
var s = "some string"
for i in 0 ..< s.len:
...
+ ```
or
-.. code-block:: nim
+ ```nim
var s = "some string"
for idx, c in s[0 .. ^1]:
... # ^1 is the last element, ^2 would be one before it, and so on
+ ```
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)
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
for index, item in ["a","b"].pairs:
echo item, " at index ", index
# => a at index 0
# => b at index 1
+ ```
Scopes and the block statement
------------------------------
@@ -447,23 +456,21 @@ 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
outside the loop:
-.. code-block:: nim
- :test: "nim c $1"
- :status: 1
+ ```nim test = "nim c $1" status = 1
while false:
var x = "hi"
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`
statement can be used to open a new block explicitly:
-.. code-block:: nim
- :test: "nim c $1"
- :status: 1
+ ```nim test = "nim c $1" status = 1
block myblock:
var x = "hi"
echo x # does not work either
+ ```
The block's *label* (`myblock` in the example) is optional.
@@ -475,8 +482,7 @@ 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
- :test: "nim c $1"
+ ```nim test = "nim c $1"
block myblock:
echo "entering block"
while true:
@@ -492,6 +498,7 @@ innermost construct, unless a label of a block is given:
break myblock2 # leaves the block (and the loop)
echo "still in block" # it won't be printed
echo "outside the block"
+ ```
Continue statement
@@ -500,11 +507,11 @@ Continue statement
Like in many other programming languages, a `continue` statement starts
the next iteration immediately:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
for i in 1 .. 5:
if i <= 3: continue
echo i # will only print 4 and 5
+ ```
When statement
@@ -512,9 +519,7 @@ When statement
Example:
-.. code-block:: nim
- :test: "nim c $1"
-
+ ```nim test = "nim c $1"
when system.hostOS == "windows":
echo "running on Windows!"
elif system.hostOS == "linux":
@@ -523,6 +528,7 @@ Example:
echo "running on Mac OS X!"
else:
echo "unknown operating system"
+ ```
The `when` statement is almost identical to the `if` statement, but with these
differences:
@@ -550,7 +556,7 @@ 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:
-.. code-block:: nim
+ ```nim
# no indentation needed for single-assignment statement:
if x: x = false
@@ -565,18 +571,19 @@ be indented, but single simple statements do not:
if x:
x = false
y = false
+ ```
*Expressions* are parts of a statement that usually result in a value. The
condition in an if statement is an example of an expression. Expressions can
contain indentation at certain places for better readability:
-.. code-block:: nim
-
+ ```nim
if thisIsaLongCondition() and
thisIsAnotherLongCondition(1,
2, 3, 4):
x = true
+ ```
As a rule of thumb, indentation within expressions is allowed after operators,
an open parenthesis and after commas.
@@ -584,10 +591,10 @@ an open parenthesis and after commas.
With parenthesis and semicolons `(;)` you can use statements where only
an expression is allowed:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
# computes fac(4) at compile time:
const fac4 = (var x = 1; for i in 1..4: x *= i; x)
+ ```
Procedures
@@ -600,8 +607,7 @@ and `readLine `_ in the examples, the concept of a
`differentiates these concepts `_. In
Nim, new procedures are defined with the `proc` keyword:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
proc yes(question: string): bool =
echo question, " (y/n)"
while true:
@@ -614,6 +620,7 @@ Nim, new procedures are defined with the `proc` keyword:
echo "I'm sorry Dave, I'm afraid I can't do that."
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`
and returns true if they answered "yes" (or something similar) and returns
@@ -638,8 +645,7 @@ 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
- :test: "nim c $1"
+ ```nim test = "nim c $1"
proc sumTillNegative(x: varargs[int]): int =
for i in x:
if i < 0:
@@ -649,6 +655,7 @@ the exit.
echo sumTillNegative() # echoes 0
echo sumTillNegative(3, 4, 5) # echoes 12
echo sumTillNegative(3, 4 , -1 , 6) # echoes 7
+ ```
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
@@ -661,10 +668,10 @@ 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
- :test: "nim c $1"
+ ```nim test = "nim c $1"
proc helloWorld(): string =
"Hello, World!"
+ ```
returns the string "Hello, World!".
@@ -677,18 +684,17 @@ 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
is possible, and actually an idiom:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
proc printSeq(s: seq, nprinted: int = -1) =
var nprinted = if nprinted == -1: s.len else: min(nprinted, s.len)
for i in 0 ..< nprinted:
echo s[i]
+ ```
If the procedure needs to modify the argument for the
caller, a `var` parameter can be used:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
proc divmod(a, b: int; res, remainder: var int) =
res = a div b # integer division
remainder = a mod b # integer modulo operation
@@ -698,6 +704,7 @@ caller, a `var` parameter can be used:
divmod(8, 5, x, y) # modifies x and y
echo x
echo y
+ ```
In the example, `res` and `remainder` are `var parameters`.
Var parameters can be modified by the procedure and the changes are
@@ -712,19 +719,20 @@ 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
allow silently throwing away a return value:
-.. code-block:: nim
+ ```nim
discard yes("May I ask a pointless question?")
+ ```
The return value can be ignored implicitly if the called proc/iterator has
been declared with the `discardable` pragma:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
proc p(x, y: int): int {.discardable.} =
return x + y
p(3, 4) # now valid
+ ```
Named arguments
@@ -735,21 +743,23 @@ parameters appear. This is especially true for procedures that construct a
complex data type. Therefore, the arguments to a procedure can be named, so
that it is clear which argument belongs to which parameter:
-.. code-block:: nim
+ ```nim
proc createWindow(x, y, width, height: int; title: string;
show: bool): Window =
...
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
does not matter anymore. Mixing named arguments with ordered arguments is
also possible, but not very readable:
-.. code-block:: nim
+ ```nim
var w = createWindow(0, 0, title = "My Application",
height = 600, width = 800, true)
+ ```
The compiler checks that each parameter receives exactly one argument.
@@ -761,13 +771,14 @@ 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:
-.. code-block:: nim
+ ```nim
proc createWindow(x = 0, y = 0, width = 500, height = 700,
title = "unknown",
show = true): Window =
...
var w = createWindow(title = "My Application", height = 600, width = 800)
+ ```
Now the call to `createWindow` only needs to set the values that differ
from the defaults.
@@ -781,7 +792,7 @@ Overloaded procedures
Nim provides the ability to overload procedures similar to C++:
-.. code-block:: nim
+ ```nim
proc toString(x: int): string =
result =
if x < 0: "negative"
@@ -795,6 +806,7 @@ 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 `$ `_ operator in
Nim.) The compiler chooses the most appropriate proc for the `toString`
@@ -825,17 +837,18 @@ can be `found in the manual `_.
To define a new operator enclose the operator in backticks "`":
-.. code-block:: nim
+ ```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
procedure:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
if `==`( `+`(3, 4), 7): echo "true"
+ ```
Forward declarations
@@ -846,11 +859,12 @@ Every variable, procedure, etc. needs to be declared before it can be used.
language that supports metaprogramming as extensively as Nim does.)
However, this cannot be done for mutually recursive procedures:
-.. code-block:: nim
+ ```nim
# forward declaration:
proc even(n: int): bool
+ ```
-.. code-block:: nim
+ ```nim
proc odd(n: int): bool =
assert(n >= 0) # makes sure we don't run into negative recursion
if n == 0: false
@@ -862,6 +876,7 @@ However, this cannot be done for mutually recursive procedures:
if n == 1: false
else:
n == 0 or odd(n-1)
+ ```
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
@@ -906,21 +921,22 @@ Iterators
Let's return to the simple counting example:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
echo "Counting to ten: "
for i in countup(1, 10):
echo i
+ ```
Can a `countup `_ proc be written that
supports this loop? Let's try:
-.. code-block:: nim
+ ```nim
proc countup(a, b: int): int =
var res = a
while res <= b:
return res
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
@@ -928,13 +944,13 @@ 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`
and here it is -- our first iterator:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
iterator countup(a, b: int): int =
var res = a
while res <= b:
yield res
inc(res)
+ ```
Iterators look very similar to procedures, but there are several
important differences:
@@ -973,11 +989,11 @@ 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
-
+ ```nim
while p != nil and p.name != "xyz":
# p.name is not evaluated if p == nil
p = p.next
+ ```
Characters
@@ -1029,13 +1045,13 @@ 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"
+ ```nim test = "nim c $1"
let
x = 0 # x is of type `int`
y = 0'i8 # y is of type `int8`
z = 0'i32 # z is of type `int32`
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.
@@ -1067,12 +1083,12 @@ The default float type is `float`. In the current implementation,
Float literals can have a *type suffix* to specify a non-default float
type:
-.. code-block:: nim
- :test: "nim c $1"
+ ```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`
+ ```
The common operators `+ - * / < <= == != > >=` are defined for
floats and follow the IEEE-754 standard.
@@ -1089,13 +1105,13 @@ Type Conversion
Conversion between numerical types is performed by using the
type as a function:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
var
x: int32 = 1.int32 # same as calling int32(1)
y: int8 = int8('a') # 'a' == 97'i8
z: float = 2.5 # int(2.5) rounds down to 2
sum: int = int(x) + int(y) + int(z) # sum == 100
+ ```
Internal type representation
@@ -1111,8 +1127,7 @@ having to write its `$` operator. You can use then the `repr
graphs with cycles. The following example shows that even for basic types
there is a difference between the `$` and `repr` outputs:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
var
myBool = true
myCharacter = 'n'
@@ -1129,6 +1144,7 @@ there is a difference between the `$` and `repr` outputs:
# --> 42:42
echo myFloat, ":", repr(myFloat)
# --> 3.14:3.14
+ ```
Advanced types
@@ -1136,11 +1152,11 @@ Advanced types
In Nim new types can be defined within a `type` statement:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
type
biggestInt = int64 # biggest integer type that is available
biggestFloat = float64 # biggest float type that is available
+ ```
Enumeration and object types may only be defined within a
`type` statement.
@@ -1154,15 +1170,14 @@ These values are a set of ordered symbols. Each symbol is mapped
to an integer value internally. The first symbol is represented
at runtime by 0, the second by 1, and so on. For example:
-.. code-block:: nim
- :test: "nim c $1"
-
+ ```nim test = "nim c $1"
type
Direction = enum
north, east, south, west
var x = south # `x` is of type `Direction`; its value is `south`
echo x # prints "south"
+ ```
All the comparison operators can be used with enumeration types.
@@ -1213,10 +1228,10 @@ Subranges
A subrange type is a range of values from an integer or enumeration type
(the base type). Example:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
type
MySubrange = range[0..5]
+ ```
`MySubrange` is a subrange of `int` which can only hold the values 0
@@ -1245,9 +1260,7 @@ an array has the same type. The array's index type can be any ordinal type.
Arrays can be constructed using `[]`:
-.. code-block:: nim
- :test: "nim c $1"
-
+ ```nim test = "nim c $1"
type
IntArray = array[0..5, int] # an array that is indexed with 0..5
var
@@ -1255,6 +1268,7 @@ Arrays can be constructed using `[]`:
x = [1, 2, 3, 4, 5, 6]
for i in low(x) .. high(x):
echo x[i]
+ ```
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
@@ -1269,8 +1283,7 @@ length. `low(a) `_ returns the lowest valid index
for the array `a` and `high(a) `_ the highest
valid index.
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
type
Direction = enum
north, east, south, west
@@ -1286,6 +1299,7 @@ valid index.
echo low(level) # --> north
echo len(level) # --> 4
echo high(level) # --> west
+ ```
The syntax for nested arrays (multidimensional) in other languages is a matter
of appending more brackets because usually each dimension is restricted to the
@@ -1295,7 +1309,7 @@ the previous example where a level is defined as an array of enums indexed by
yet another enum, we can add the following lines to add a light tower type
subdivided into height levels accessed through their integer index:
-.. code-block:: nim
+ ```nim
type
LightTower = array[1..10, LevelSetting]
var
@@ -1308,21 +1322,22 @@ subdivided into height levels accessed through their integer index:
# The following lines don't compile due to type mismatch errors
#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`
type and instead write it embedded directly as the type of the first dimension:
-.. code-block:: nim
+ ```nim
type
LightTower = array[1..10, array[north..west, BlinkLights]]
+ ```
It is quite common to have arrays start at zero, so there's a shortcut syntax
to specify a range from zero to the specified index minus one:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
type
IntArray = array[0..5, int] # an array that is indexed with 0..5
QuickArray = array[6, int] # an array that is indexed with 0..5
@@ -1333,6 +1348,7 @@ to specify a range from zero to the specified index minus one:
y = x
for i in low(x) .. high(x):
echo x[i], y[i]
+ ```
Sequences
@@ -1355,12 +1371,11 @@ A sequence may be passed to an openarray parameter.
Example:
-.. code-block:: nim
- :test: "nim c $1"
-
+ ```nim test = "nim c $1"
var
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 `@[]`.
@@ -1374,8 +1389,7 @@ value. Here the `for` statement is looping over the results from the
`pairs() `_ iterator from the `system
`_ module. Examples:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
for value in @[3, 4, 5]:
echo value
# --> 3
@@ -1387,6 +1401,7 @@ value. Here the `for` statement is looping over the results from the
# --> index: 0, value:3
# --> index: 1, value:4
# --> index: 2, value:5
+ ```
Open arrays
@@ -1402,8 +1417,7 @@ and `high `_ operations are available for open
arrays too. Any array with a compatible base type can be passed to an
openarray parameter, the index type does not matter.
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
var
fruits: seq[string] # reference to a sequence of strings that is initialized with '@[]'
capitals: array[3, string] # array of strings with a fixed size
@@ -1417,6 +1431,7 @@ openarray parameter, the index type does not matter.
assert openArraySize(fruits) == 2 # procedure accepts a sequence as parameter
assert openArraySize(capitals) == 3 # but also an array type
+ ```
The openarray type cannot be nested: multidimensional openarrays are not
supported because this is seldom needed and cannot be done efficiently.
@@ -1430,8 +1445,7 @@ 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:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
proc myWriteln(f: File, a: varargs[string]) =
for s in items(a):
write(f, s)
@@ -1440,13 +1454,13 @@ to an array automatically:
myWriteln(stdout, "abc", "def", "xyz")
# is transformed by the compiler to:
myWriteln(stdout, ["abc", "def", "xyz"])
+ ```
This transformation is only done if the varargs parameter is the
last parameter in the procedure header. It is also possible to perform
type conversions in this context:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
proc myWriteln(f: File, a: varargs[string, `$`]) =
for s in items(a):
write(f, s)
@@ -1455,6 +1469,7 @@ type conversions in this context:
myWriteln(stdout, 123, "abc", 4.0)
# is transformed by the compiler to:
myWriteln(stdout, [$123, $"abc", $4.0])
+ ```
In this example `$ `_ is applied to any argument that is passed
to the parameter `a`. Note that `$ `_ applied to strings is a
@@ -1469,9 +1484,7 @@ context. A slice is just an object of type Slice which contains two bounds,
`a` and `b`. By itself a slice is not very useful, but other collection types
define operators which accept Slice objects to define ranges.
-.. code-block:: nim
- :test: "nim c $1"
-
+ ```nim test = "nim c $1"
var
a = "Nim is a programming language"
b = "Slices are useless."
@@ -1479,6 +1492,7 @@ define operators which accept Slice objects to define ranges.
echo a[7 .. 12] # --> 'a prog'
b[11 .. ^2] = "useful"
echo b # --> 'Slices are useful.'
+ ```
In the previous example slices are used to modify a part of a string. The
slice's bounds can hold any value supported by
@@ -1492,12 +1506,12 @@ zero-based indices.
So the string `b` is of length 19, and two different ways of specifying the
indices are
-.. code-block:: nim
-
+ ```nim
"Slices are useless."
| | |
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 shorthand way of specifying the `b.len-1`. See
@@ -1528,7 +1542,7 @@ 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.
-.. code-block:: nim
+ ```nim
type
Person = object
name: string
@@ -1555,18 +1569,18 @@ get their default value.
# unspecified members will be initialized with their default
# values. In this case it is the empty string.
doAssert person4.name == ""
+ ```
Object fields that should be visible from outside the defining module have to
be marked with `*`.
-.. code-block:: nim
- :test: "nim c $1"
-
+ ```nim test = "nim c $1"
type
Person* = object # the type is visible from other modules
name*: string # the field of this type is visible from other modules
age*: int
+ ```
Tuples
------
@@ -1588,8 +1602,7 @@ 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
integer.
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
type
# type representing a person:
# A person consists of a name and an age.
@@ -1638,6 +1651,7 @@ integer.
#person = building
# --> Error: type mismatch: got (tuple[street: string, number: int])
# but expected 'Person'
+ ```
Even though you don't need to declare a type for a tuple to use it, tuples
created with different field names will be considered different objects despite
@@ -1652,9 +1666,7 @@ use parentheses around the values you want to assign the unpacking to,
otherwise, you will be assigning the same value to all the individual
variables! For example:
-.. code-block:: nim
- :test: "nim c $1"
-
+ ```nim test = "nim c $1"
import std/os
let
@@ -1669,11 +1681,11 @@ variables! For example:
echo baddir
echo badname
echo badext
+ ```
Tuple unpacking is also supported in for-loops:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
let a = [(10, 'a'), (20, 'b'), (30, 'c')]
for (x, c) in a:
@@ -1684,6 +1696,7 @@ Tuple unpacking is also supported in for-loops:
for i, (x, c) in a:
echo i, c
# This will output: 0a; 1b; 2c
+ ```
Fields of tuples are always public, they don't need to be explicitly
marked to be exported, unlike for example fields in an object type.
@@ -1711,9 +1724,7 @@ 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
- :test: "nim c $1"
-
+ ```nim test = "nim c $1"
type
Node = ref object
le, ri: Node
@@ -1722,13 +1733,14 @@ operators perform implicit dereferencing operations for reference types:
var n = Node(data: 9)
echo n.data
# no need to write n[].data; in fact n[].data is highly discouraged!
+ ```
To allocate a new traced object, the built-in procedure `new` can be used:
-.. code-block:: nim
-
- var n: Node
- new(n)
+ ```nim
+ var n: Node
+ new(n)
+ ```
To deal with untraced memory, the procedures `alloc`, `dealloc` and
`realloc` can be used. The `system `_
@@ -1747,8 +1759,7 @@ techniques.
Example:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
proc greet(name: string): string =
"Hello, " & name & "!"
@@ -1760,6 +1771,7 @@ Example:
communicate(greet, "John")
communicate(bye, "Mary")
+ ```
A subtle issue with procedural types is that the calling convention of the
procedure influences the type compatibility: procedural types are only compatible
@@ -1785,7 +1797,7 @@ Each module is in its own file. Modules enable `information hiding`:idx: and
module by using the `import`:idx: statement. Only top-level symbols that are marked
with an asterisk (`*`) are exported:
-.. code-block:: nim
+ ```nim
# Module A
var
x*, y: int
@@ -1799,6 +1811,7 @@ with an asterisk (`*`) are exported:
when isMainModule:
# 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`.
@@ -1814,15 +1827,17 @@ 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:
-.. code-block:: nim
+ ```nim
# Module A
var x*: string
+ ```
-.. code-block:: nim
+ ```nim
# Module B
var x*: int
+ ```
-.. code-block:: nim
+ ```nim
# Module C
import A, B
write(stdout, x) # error: x is ambiguous
@@ -1830,20 +1845,23 @@ imported by a third one:
var x = 4
write(stdout, x) # not ambiguous: uses the module C's x
+ ```
But this rule does not apply to procedures or iterators. Here the overloading
rules apply:
-.. code-block:: nim
+ ```nim
# Module A
proc x*(a: int): string = $a
+ ```
-.. code-block:: nim
+ ```nim
# Module B
proc x*(a: string): string = $a
+ ```
-.. code-block:: nim
+ ```nim
# Module C
import A, B
write(stdout, x(3)) # no error: A.x is called
@@ -1851,6 +1869,7 @@ rules apply:
proc x*(a: int): string = discard
write(stdout, x(3)) # ambiguous: which `x` is to call?
+ ```
Excluding symbols
@@ -1860,8 +1879,9 @@ 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.
-.. code-block:: nim
+ ```nim
import mymodule except y
+ ```
From statement
@@ -1871,32 +1891,36 @@ 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:
-.. code-block:: nim
+ ```nim
from mymodule import x, y, z
+ ```
The `from` statement can also force namespace qualification on
symbols, thereby making symbols available, but needing to be qualified
in order to be used.
-.. code-block:: nim
+ ```nim
from mymodule import x, y, z
x() # use x without any qualification
+ ```
-.. code-block:: nim
+ ```nim
from mymodule import nil
mymodule.x() # must qualify x with the module name as prefix
x() # using x here without qualification is a compile error
+ ```
Since module names are generally long to be descriptive, you can also
define a shorter alias to use when qualifying symbols.
-.. code-block:: nim
+ ```nim
from mymodule as m import nil
m.x() # m is aliasing mymodule
+ ```
Include statement
@@ -1906,8 +1930,9 @@ 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
+ ```nim
include fileA, fileB, fileC
+ ```
diff --git a/doc/tut2.md b/doc/tut2.md
index d37d6a16a0..762d1cef56 100644
--- a/doc/tut2.md
+++ b/doc/tut2.md
@@ -53,8 +53,7 @@ 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.
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
type
Person = ref object of RootObj
name*: string # the * means that `name` is accessible from other modules
@@ -70,6 +69,7 @@ type, the `of` operator can be used.
# object construction:
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`
@@ -97,8 +97,7 @@ would require arbitrary symbol lookahead which slows down compilation.)
Example:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
type
Node = ref object # a reference to an object with the following field:
le, ri: Node # left and right subtrees
@@ -108,6 +107,7 @@ Example:
name: string # the symbol's name
line: int # the line the symbol was declared in
code: Node # the symbol's abstract syntax tree
+ ```
Type conversions
@@ -124,9 +124,10 @@ raised.
The syntax for type conversions is `destination_type(expression_to_convert)`
(like an ordinary call):
-.. code-block:: nim
+ ```nim
proc getID(x: Person): int =
Student(x).id
+ ```
The `InvalidObjectConversionDefect` exception is raised if `x` is not a
`Student`.
@@ -139,9 +140,7 @@ variant types are needed.
An example:
-.. code-block:: nim
- :test: "nim c $1"
-
+ ```nim test = "nim c $1"
# This is an example how an abstract syntax tree could be modelled in Nim
type
NodeKind = enum # the different node types
@@ -165,6 +164,7 @@ An example:
# the following statement raises an `FieldDefect` exception, because
# n.kind's value does not fit:
n.strVal = ""
+ ```
As can been seen from the example, an advantage to an object hierarchy is that
no conversion between different object types is needed. Yet, access to invalid
@@ -183,27 +183,27 @@ If there are no remaining arguments, the parentheses can be omitted:
This method call syntax is not restricted to objects, it can be used
for any type:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
import std/strutils
echo "abc".len # is the same as echo len("abc")
echo "abc".toUpperAscii()
echo({'a', 'b', 'c'}.card)
stdout.writeLine("Hallo") # the same as writeLine(stdout, "Hallo")
+ ```
(Another way to look at the method call syntax is that it provides the missing
postfix notation.)
So "pure object oriented" code is easy to write:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
import std/[strutils, sequtils]
stdout.writeLine("Give a list of numbers (separated by spaces): ")
stdout.write(stdin.readLine.splitWhitespace.map(parseInt).max.`$`)
stdout.writeLine(" is the maximum!")
+ ```
Properties
@@ -213,9 +213,7 @@ Ordinary get-procedures that are called with the *method call syntax* achieve
the same. But setting a value is different; for this a special setter syntax
is needed:
-.. code-block:: nim
- :test: "nim c $1"
-
+ ```nim test = "nim c $1"
type
Socket* = ref object of RootObj
h: int # cannot be accessed from the outside of the module due to missing star
@@ -231,6 +229,7 @@ is needed:
var s: Socket
new s
s.host = 34 # same as `host=`(s, 34)
+ ```
(The example also shows `inline` procedures.)
@@ -238,8 +237,7 @@ is needed:
The `[]` array access operator can be overloaded to provide
`array properties`:idx:\ :
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
type
Vector* = object
x, y, z: float
@@ -259,6 +257,7 @@ The `[]` array access operator can be overloaded to provide
of 1: result = v.y
of 2: result = v.z
else: assert(false)
+ ```
The example is silly, since a vector is better modelled by a tuple which
already provides `v[]` access.
@@ -270,8 +269,7 @@ Dynamic dispatch
Procedures always use static dispatch. For dynamic dispatch replace the
`proc` keyword by `method`:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
type
Expression = ref object of RootObj ## abstract base class for an expression
Literal = ref object of Expression
@@ -291,6 +289,7 @@ Procedures always use static dispatch. For dynamic dispatch replace the
proc newPlus(a, b: Expression): PlusExpr = PlusExpr(a: a, b: b)
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
@@ -302,9 +301,7 @@ method because it requires dynamic binding.
In a multi-method all parameters that have an object type are used for the
dispatching:
-.. code-block:: nim
- :test: "nim c --multiMethods:on $1"
-
+ ```nim test = "nim c --multiMethods:on $1"
type
Thing = ref object of RootObj
Unit = ref object of Thing
@@ -323,6 +320,7 @@ dispatching:
new a
new b
collide(a, b) # output: 2
+ ```
As the example demonstrates, invocation of a multi-method cannot be ambiguous:
@@ -355,20 +353,21 @@ Raise statement
---------------
Raising an exception is done with the `raise` statement:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
var
e: ref OSError
new(e)
e.msg = "the request to the OS failed"
raise e
+ ```
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:
-.. code-block:: nim
+ ```nim
raise newException(OSError, "the request to the OS failed")
+ ```
Try statement
@@ -376,8 +375,7 @@ Try statement
The `try` statement handles exceptions:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
from std/strutils import parseInt
# read the first two lines of a text file that should contain numbers
@@ -401,6 +399,7 @@ The `try` statement handles exceptions:
raise
finally:
close(f)
+ ```
The statements after the `try` are executed unless an exception is
raised. Then the appropriate `except` part is executed.
@@ -423,7 +422,7 @@ If you need to *access* the actual exception object or message inside an
`_ procs from the `system `_
module. Example:
-.. code-block:: nim
+ ```nim
try:
doSomethingHere()
except:
@@ -431,6 +430,7 @@ module. Example:
e = getCurrentException()
msg = getCurrentExceptionMsg()
echo "Got exception ", repr(e), " with message ", msg
+ ```
Annotating procs with raised exceptions
@@ -443,12 +443,13 @@ 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:
-.. code-block:: nim
+ ```nim
proc complexProc() {.raises: [IOError, ArithmeticDefect].} =
...
proc simpleProc() {.raises: [].} =
...
+ ```
Once you have code like this in place, if the list of raised exception changes
the compiler will stop with an error specifying the line of the proc which
@@ -474,8 +475,7 @@ with `type parameters`:idx:. Generic parameters are written within square
brackets, for example `Foo[T]`. They are most useful for efficient type safe
containers:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
type
BinaryTree*[T] = ref object # BinaryTree is a generic type with
# generic param `T`
@@ -530,6 +530,7 @@ containers:
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,
@@ -539,8 +540,7 @@ is not hidden and is used in the `preorder` iterator.
There is a special `[:T]` syntax when using generics with the method call syntax:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
proc foo[T](i: T) =
discard
@@ -549,6 +549,7 @@ There is a special `[:T]` syntax when using generics with the method call syntax
# i.foo[int]() # Error: expression 'foo(i)' has no type (or is ambiguous)
i.foo[:int]() # Success
+ ```
Templates
@@ -563,12 +564,13 @@ To *invoke* a template, call it like a procedure.
Example:
-.. code-block:: nim
+ ```nim
template `!=` (a, b: untyped): untyped =
# this definition exists in the System module
not (a == b)
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,
@@ -582,8 +584,7 @@ for IEEE floating point numbers - NaN breaks basic boolean logic.)
Templates are especially useful for lazy evaluation purposes. Consider a
simple proc for logging:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
const
debug = true
@@ -593,6 +594,7 @@ simple proc for logging:
var
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
@@ -600,8 +602,7 @@ evaluation for procedures is *eager*).
Turning the `log` proc into a template solves this problem:
-.. code-block:: nim
- :test: "nim c $1"
+ ```nim test = "nim c $1"
const
debug = true
@@ -611,6 +612,7 @@ Turning the `log` proc into a template solves this problem:
var
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
@@ -622,9 +624,7 @@ If the template has no explicit return type,
To pass a block of statements to a template, use `untyped` for the last parameter:
-.. code-block:: nim
- :test: "nim c $1"
-
+ ```nim test = "nim c $1"
template withFile(f: untyped, filename: string, mode: FileMode,
body: untyped) =
let fn = filename
@@ -640,6 +640,7 @@ To pass a block of statements to a template, use `untyped` for the last paramete
withFile(txt, "ttempl3.txt", fmWrite):
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
@@ -650,8 +651,7 @@ once.
Example: Lifting Procs
----------------------
-.. code-block:: nim
- :test: "nim c $1"
+ `````nim test = "nim c $1"
import std/math
template liftScalarProc(fname) =
@@ -660,9 +660,10 @@ Example: Lifting Procs
## to provide templated procs that can handle a single
## parameter of seq[T] or nested seq[seq[]] or the same type
##
- ## .. code-block:: Nim
- ## liftScalarProc(abs)
- ## # now abs(@[@[1,-2], @[-2,-3]]) == @[@[1,2], @[2,3]]
+ ## ```Nim
+ ## liftScalarProc(abs)
+ ## # now abs(@[@[1,-2], @[-2,-3]]) == @[@[1,2], @[2,3]]
+ ## ```
proc fname[T](x: openarray[T]): auto =
var temp: T
type outType = typeof(fname(temp))
@@ -672,6 +673,7 @@ Example: Lifting Procs
liftScalarProc(sqrt) # make sqrt() work for sequences
echo sqrt(@[4.0, 16.0, 25.0, 36.0]) # => @[2.0, 4.0, 5.0, 6.0]
+ `````
Compilation to JavaScript
=========================
diff --git a/doc/tut3.md b/doc/tut3.md
index 2fcfd4220c..4c9b359b8c 100644
--- a/doc/tut3.md
+++ b/doc/tut3.md
@@ -91,14 +91,14 @@ in the expression `foo(x)`, `x` needs to be an integer constant,
but in the macro body `arg` is just like a normal parameter of type
`int`.
-.. code-block:: nim
-
+ ```nim
import std/macros
macro myMacro(arg: static[int]): untyped =
echo arg # just an int (7), not `NimNode`
myMacro(1 + 2 * 3)
+ ```
Code Blocks as Arguments
@@ -108,12 +108,12 @@ It is possible to pass the last argument of a call expression in a
separate code block with indentation. For example, the following code
example is a valid (but not a recommended) way to call `echo`:
-.. code-block:: nim
-
+ ```nim
echo "Hello ":
let a = "Wor"
let b = "ld!"
a & b
+ ```
For macros this way of calling is very useful; syntax trees of arbitrary
complexity can be passed to macros with this notation.
@@ -134,8 +134,7 @@ and for debug printing of generated syntax tree. `dumpTree` is a
predefined macro that just prints its argument in a tree representation,
but does nothing else. Here is an example of such a tree representation:
-.. code-block:: nim
-
+ ```nim
dumpTree:
var mt: MyType = MyType(a:123.456, b:"abcdef")
@@ -153,6 +152,7 @@ but does nothing else. Here is an example of such a tree representation:
# ExprColonExpr
# Ident "b"
# StrLit "abcdef"
+ ```
Custom Semantic Checking
@@ -166,10 +166,10 @@ macro evaluation should be caught and create a nice error message.
the checks need to be more complex, arbitrary error messages can
be created with the `macros.error` proc.
-.. code-block:: nim
-
+ ```nim
macro myAssert(arg: untyped): untyped =
arg.expectKind nnkInfix
+ ```
Generating Code
@@ -187,36 +187,36 @@ tree with calls to `newTree` and `newLit` the macro
Backticks are used to insert code from `NimNode` symbols into the
generated expression.
-.. code-block:: nim
- :test: "nim c $1"
- import std/macros
- macro a(i) = quote do:
- let `i` = 0
+ ```nim test = "nim c $1"
+ import std/macros
+ macro a(i) = quote do:
+ let `i` = 0
- a b
- doAssert b == 0
+ a b
+ doAssert b == 0
+ ```
A custom prefix operator can be defined whenever backticks are needed.
-.. code-block:: nim
- :test: "nim c $1"
- import std/macros
- macro a(i) = quote("@") do:
- assert @i == 0
+ ```nim test = "nim c $1"
+ import std/macros
+ macro a(i) = quote("@") do:
+ assert @i == 0
- let b = 0
- a b
+ let b = 0
+ a b
+ ```
The injected symbol needs accent quoted when it resolves to a symbol.
-.. code-block:: nim
- :test: "nim c $1"
- import std/macros
- macro a(i) = quote("@") do:
- let `@i` = 0
+ ```nim test = "nim c $1"
+ import std/macros
+ macro a(i) = quote("@") do:
+ let `@i` = 0
- a b
- doAssert b == 0
+ a b
+ doAssert b == 0
+ ```
Make sure to inject only symbols of type `NimNode` into the generated syntax
tree. You can use `newLit` to convert arbitrary values into
@@ -224,9 +224,7 @@ expressions trees of type `NimNode` so that it is safe to inject
them into the tree.
-.. code-block:: nim
- :test: "nim c $1"
-
+ ```nim test = "nim c $1"
import std/macros
type
@@ -246,12 +244,14 @@ them into the tree.
echo `mtLit`
myMacro("Hallo")
+ ```
The call to `myMacro` will generate the following code:
-.. code-block:: nim
+ ```nim
echo "Hallo"
echo MyType(a: 123.456'f64, b: "abcdef")
+ ```
Building Your First Macro
@@ -263,9 +263,7 @@ do is to build a simple example of the macro usage, and then just
print the argument. This way it is possible to get an idea of what a
correct argument should look like.
-.. code-block:: nim
- :test: "nim c $1"
-
+ ```nim test = "nim c $1"
import std/macros
macro myAssert(arg: untyped): untyped =
@@ -275,13 +273,14 @@ correct argument should look like.
let b = 2
myAssert(a != b)
+ ```
-.. code-block::
-
+ ```
Infix
Ident "!="
Ident "a"
Ident "b"
+ ```
From the output, it is possible to see that the argument is an infix
@@ -289,9 +288,7 @@ operator (node kind is "Infix"), as well as that the two operands are
at index 1 and 2. With this information, the actual macro can be
written.
-.. code-block:: nim
- :test: "nim c $1"
-
+ ```nim test = "nim c $1"
import std/macros
macro myAssert(arg: untyped): untyped =
@@ -312,6 +309,7 @@ written.
myAssert(a != b)
myAssert(a == b)
+ ```
This is the code that will be generated. To debug what the macro
@@ -319,9 +317,10 @@ actually generated, the statement `echo result.repr` can be used, in
the last line of the macro. It is also the statement that has been
used to get this output.
-.. code-block:: nim
+ ```nim
if not (a != b):
raise newException(AssertionDefect, $a & " != " & $b)
+ ```
With Power Comes Responsibility
-------------------------------