tut1.rst makes use of the new ':test:' feature

This commit is contained in:
Araq 2017-11-28 01:13:25 +01:00
commit 21ffb3a706

View file

@ -30,6 +30,7 @@ The first program
We start the tour with a modified "hello world" program: We start the tour with a modified "hello world" program:
.. code-block:: Nim .. code-block:: Nim
:test: "nim c $1"
# This is a comment # This is a comment
echo "What's your name? " echo "What's your name? "
var name: string = readLine(stdin) var name: string = readLine(stdin)
@ -72,6 +73,7 @@ you can leave out the type in the declaration (this is called `local type
inference`:idx:). So this will work too: inference`:idx:). So this will work too:
.. code-block:: Nim .. code-block:: Nim
:test: "nim c $1"
var name = readLine(stdin) var name = readLine(stdin)
Note that this is basically the only form of type inference that exists in Note that this is basically the only form of type inference that exists in
@ -116,6 +118,7 @@ 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 .. code-block:: nim
:test: "nim c $1"
# A comment. # A comment.
var myVariable: int ## a documentation comment var myVariable: int ## a documentation comment
@ -129,6 +132,7 @@ Multiline comments are started with ``#[`` and terminated with ``]#``. Multilin
comments can also be nested. comments can also be nested.
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
#[ #[
You can have any Nim code text commented You can have any Nim code text commented
out inside this with no indentation restrictions. out inside this with no indentation restrictions.
@ -142,6 +146,7 @@ You can also use the `discard statement <#procedures-discard-statement>`_ togeth
literals* to create block comments: literals* to create block comments:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
discard """ You can have any Nim code text commented discard """ You can have any Nim code text commented
out inside this with no indentation restrictions. out inside this with no indentation restrictions.
yes("May I ask a pointless question?") """ yes("May I ask a pointless question?") """
@ -169,6 +174,7 @@ Indentation can be used after the ``var`` keyword to list a whole section of
variables: variables:
.. code-block:: .. code-block::
:test: "nim c $1"
var var
x, y: int x, y: int
# a comment can occur here too # a comment can occur here too
@ -190,6 +196,7 @@ overloaded. You can declare multiple variables with a single assignment
statement and all the variables will have the same value: statement and all the variables will have the same value:
.. code-block:: .. code-block::
:test: "nim c $1"
var x, y = 3 # assigns 3 to the variables `x` and `y` var x, y = 3 # assigns 3 to the variables `x` and `y`
echo "x ", x # outputs "x 3" echo "x ", x # outputs "x 3"
echo "y ", y # outputs "y 3" echo "y ", y # outputs "y 3"
@ -212,12 +219,14 @@ cannot change. The compiler must be able to evaluate the expression in a
constant declaration at compile time: constant declaration at compile time:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
const x = "abc" # the constant x contains the string "abc" 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: constants:
.. code-block:: .. code-block::
:test: "nim c $1"
const const
x = 1 x = 1
# a comment can occur here too # a comment can occur here too
@ -243,6 +252,7 @@ and put it into a data section":
const input = readLine(stdin) # Error: constant expression expected const input = readLine(stdin) # Error: constant expression expected
.. code-block:: .. code-block::
:test: "nim c $1"
let input = readLine(stdin) # works let input = readLine(stdin) # works
@ -260,6 +270,7 @@ If statement
The if statement is one way to branch the control flow: The if statement is one way to branch the control flow:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
let name = readLine(stdin) let name = readLine(stdin)
if name == "": if name == "":
echo "Poor soul, you lost your name?" echo "Poor soul, you lost your name?"
@ -281,6 +292,7 @@ Another way to branch is provided by the case statement. A case statement is
a multi-branch: a multi-branch:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
let name = readLine(stdin) let name = readLine(stdin)
case name case name
of "": of "":
@ -338,6 +350,7 @@ While statement
The while statement is a simple looping construct: The while statement is a simple looping construct:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
echo "What's your name? " echo "What's your name? "
var name = readLine(stdin) var name = readLine(stdin)
@ -358,6 +371,7 @@ provides. The example uses the built-in `countup <system.html#countup>`_
iterator: iterator:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
echo "Counting to ten: " echo "Counting to ten: "
for i in countup(1, 10): for i in countup(1, 10):
echo i echo i
@ -409,6 +423,7 @@ Other useful iterators for collections (like arrays and sequences) are
* ``pairs`` and ``mpairs`` which provides the element and an index number (immutable and mutable respectively) * ``pairs`` and ``mpairs`` which provides the element and an index number (immutable and mutable respectively)
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
for index, item in ["a","b"].pairs: for index, item in ["a","b"].pairs:
echo item, " at index ", index echo item, " at index ", index
# => a at index 0 # => a at index 0
@ -421,6 +436,8 @@ new scope. This means that in the following example, ``x`` is not accessible
outside the loop: outside the loop:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
:status: 1
while false: while false:
var x = "hi" var x = "hi"
echo x # does not work echo x # does not work
@ -430,6 +447,8 @@ are only visible within the block they have been declared. The ``block``
statement can be used to open a new block explicitly: statement can be used to open a new block explicitly:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
:status: 1
block myblock: block myblock:
var x = "hi" var x = "hi"
echo x # does not work either echo x # does not work either
@ -444,6 +463,7 @@ can leave a ``while``, ``for``, or a ``block`` statement. It leaves the
innermost construct, unless a label of a block is given: innermost construct, unless a label of a block is given:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
block myblock: block myblock:
echo "entering block" echo "entering block"
while true: while true:
@ -465,6 +485,7 @@ Like in many other programming languages, a ``continue`` statement starts
the next iteration immediately: the next iteration immediately:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
while true: while true:
let x = readLine(stdin) let x = readLine(stdin)
if x == "": continue if x == "": continue
@ -477,6 +498,7 @@ When statement
Example: Example:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
when system.hostOS == "windows": when system.hostOS == "windows":
echo "running on Windows!" echo "running on Windows!"
@ -549,6 +571,7 @@ an expression is allowed:
.. code-block:: nim .. code-block:: nim
# computes fac(4) at compile time: # computes fac(4) at compile time:
:test: "nim c $1"
const fac4 = (var x = 1; for i in 1..4: x *= i; x) const fac4 = (var x = 1; for i in 1..4: x *= i; x)
@ -561,6 +584,7 @@ is needed. (Some languages call them *methods* or *functions*.) In Nim new
procedures are defined with the ``proc`` keyword: procedures are defined with the ``proc`` keyword:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
proc yes(question: string): bool = proc yes(question: string): bool =
echo question, " (y/n)" echo question, " (y/n)"
while true: while true:
@ -597,6 +621,7 @@ automatically at the end of a procedure if there is no ``return`` statement at
the exit. the exit.
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
proc sumTillNegative(x: varargs[int]): int = proc sumTillNegative(x: varargs[int]): int =
for i in x: for i in x:
if i < 0: if i < 0:
@ -624,6 +649,7 @@ to be declared with ``var`` in the procedure body. Shadowing the parameter name
is possible, and actually an idiom: is possible, and actually an idiom:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
proc printSeq(s: seq, nprinted: int = -1) = proc printSeq(s: seq, nprinted: int = -1) =
var nprinted = if nprinted == -1: s.len else: min(nprinted, s.len) var nprinted = if nprinted == -1: s.len else: min(nprinted, s.len)
for i in 0 .. <nprinted: for i in 0 .. <nprinted:
@ -633,6 +659,7 @@ 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 .. code-block:: nim
:test: "nim c $1"
proc divmod(a, b: int; res, remainder: var int) = proc divmod(a, b: int; res, remainder: var int) =
res = a div b # integer division res = a div b # integer division
remainder = a mod b # integer modulo operation remainder = a mod b # integer modulo operation
@ -663,6 +690,7 @@ 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 .. code-block:: nim
:test: "nim c $1"
proc p(x, y: int): int {.discardable.} = proc p(x, y: int): int {.discardable.} =
return x + y return x + y
@ -772,6 +800,7 @@ The "``" notation can also be used to call an operator just like any other
procedure: procedure:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
if `==`( `+`(3, 4), 7): echo "True" if `==`( `+`(3, 4), 7): echo "True"
@ -819,6 +848,7 @@ Iterators
Let's return to the simple counting example: Let's return to the simple counting example:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
echo "Counting to ten: " echo "Counting to ten: "
for i in countup(1, 10): for i in countup(1, 10):
echo i echo i
@ -840,6 +870,7 @@ the only thing left to do is to replace the ``proc`` keyword by ``iterator``
and here it is - our first iterator: and here it is - our first iterator:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
iterator countup(a, b: int): int = iterator countup(a, b: int): int =
var res = a var res = a
while res <= b: while res <= b:
@ -894,7 +925,8 @@ evaluation. For example:
Characters 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. 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, The reason for this is efficiency: for the overwhelming majority of use-cases,
the resulting programs will still handle UTF-8 properly as UTF-8 was specially the resulting programs will still handle UTF-8 properly as UTF-8 was specially
designed for this. designed for this.
@ -945,6 +977,7 @@ to specify a non-default integer type:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
let let
x = 0 # x is of type ``int`` x = 0 # x is of type ``int``
y = 0'i8 # y is of type ``int8`` y = 0'i8 # y is of type ``int8``
@ -981,6 +1014,7 @@ Float literals can have a *type suffix* to specify a non-default float
type: type:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
var var
x = 0.0 # x is of type ``float`` x = 0.0 # x is of type ``float``
y = 0.0'f32 # y is of type ``float32`` y = 0.0'f32 # y is of type ``float32``
@ -1002,6 +1036,7 @@ Conversion between basic types is performed by using the
type as a function: type as a function:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
var var
x: int32 = 1.int32 # same as calling int32(1) x: int32 = 1.int32 # same as calling int32(1)
y: int8 = int8('a') # 'a' == 97'i8 y: int8 = int8('a') # 'a' == 97'i8
@ -1023,6 +1058,7 @@ 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 .. code-block:: nim
:test: "nim c $1"
var var
myBool = true myBool = true
myCharacter = 'n' myCharacter = 'n'
@ -1047,6 +1083,7 @@ 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 .. code-block:: nim
:test: "nim c $1"
type type
biggestInt = int64 # biggest integer type that is available biggestInt = int64 # biggest integer type that is available
biggestFloat = float64 # biggest float type that is available biggestFloat = float64 # biggest float type that is available
@ -1063,6 +1100,7 @@ to an integer value internally. The first symbol is represented
at runtime by 0, the second by 1 and so on. For example: at runtime by 0, the second by 1 and so on. For example:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
type type
Direction = enum Direction = enum
@ -1087,6 +1125,7 @@ explicitly given is assigned the value of the previous symbol + 1.
An explicit ordered enum can have *holes*: An explicit ordered enum can have *holes*:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
type type
MyEnum = enum MyEnum = enum
a = 2, b = 4, c = 89 a = 2, b = 4, c = 89
@ -1125,6 +1164,7 @@ A subrange type is a range of values from an integer or enumeration type
(the base type). Example: (the base type). Example:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
type type
MySubrange = range[0..5] MySubrange = range[0..5]
@ -1155,6 +1195,7 @@ 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 .. code-block:: nim
:test: "nim c $1"
type type
IntArray = array[0..5, int] # an array that is indexed with 0..5 IntArray = array[0..5, int] # an array that is indexed with 0..5
@ -1177,6 +1218,7 @@ length. `low(a) <system.html#low>`_ returns the lowest valid index for the
array `a` and `high(a) <system.html#high>`_ the highest valid index. array `a` and `high(a) <system.html#high>`_ the highest valid index.
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
type type
Direction = enum Direction = enum
north, east, south, west north, east, south, west
@ -1228,6 +1270,7 @@ 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: to specify a range from zero to the specified index minus one:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
type type
IntArray = array[0..5, int] # an array that is indexed with 0..5 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 QuickArray = array[6, int] # an array that is indexed with 0..5
@ -1260,6 +1303,7 @@ A sequence may be passed to an openarray parameter.
Example: Example:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
var var
x: seq[int] # a reference to a sequence of integers x: seq[int] # a reference to a sequence of integers
@ -1282,6 +1326,7 @@ value. Here the ``for`` statement is looping over the results from the
<system.html>`_ module. Examples: <system.html>`_ module. Examples:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
for value in @[3, 4, 5]: for value in @[3, 4, 5]:
echo value echo value
# --> 3 # --> 3
@ -1308,6 +1353,7 @@ with a compatible base type can be passed to an openarray parameter, the index
type does not matter. type does not matter.
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
var var
fruits: seq[string] # reference to a sequence of strings that is initialized with 'nil' fruits: seq[string] # reference to a sequence of strings that is initialized with 'nil'
capitals: array[3, string] # array of strings with a fixed size capitals: array[3, string] # array of strings with a fixed size
@ -1337,6 +1383,7 @@ arguments to a procedure. The compiler converts the list of arguments
to an array automatically: to an array automatically:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
proc myWriteln(f: File, a: varargs[string]) = proc myWriteln(f: File, a: varargs[string]) =
for s in items(a): for s in items(a):
write(f, s) write(f, s)
@ -1351,6 +1398,7 @@ last parameter in the procedure header. It is also possible to perform
type conversions in this context: type conversions in this context:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
proc myWriteln(f: File, a: varargs[string, `$`]) = proc myWriteln(f: File, a: varargs[string, `$`]) =
for s in items(a): for s in items(a):
write(f, s) write(f, s)
@ -1374,6 +1422,7 @@ context. A slice is just an object of type Slice which contains two bounds,
define operators which accept Slice objects to define ranges. define operators which accept Slice objects to define ranges.
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
var var
a = "Nim is a progamming language" a = "Nim is a progamming language"
@ -1429,6 +1478,7 @@ The assignment operator for tuples copies each component. The notation
integer. integer.
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
type type
Person = tuple[name: string, age: int] # type representing a person: Person = tuple[name: string, age: int] # type representing a person:
@ -1474,6 +1524,7 @@ otherwise you will be assigning the same value to all the individual
variables! For example: variables! For example:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
import os import os
@ -1513,6 +1564,7 @@ tuple/object field operator) and ``[]`` (array/string/sequence index operator)
operators perform implicit dereferencing operations for reference types: operators perform implicit dereferencing operations for reference types:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
type type
Node = ref object Node = ref object
@ -1542,6 +1594,7 @@ techniques.
Example: Example:
.. code-block:: nim .. code-block:: nim
:test: "nim c $1"
proc echoItem(x: int) = echo x proc echoItem(x: int) = echo x
proc forEach(action: proc (x: int)) = proc forEach(action: proc (x: int)) =