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

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

View File

@@ -30,6 +30,7 @@ The first program
We start the tour with a modified "hello world" program:
.. code-block:: Nim
:test: "nim c $1"
# This is a comment
echo "What's your name? "
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:
.. code-block:: Nim
:test: "nim c $1"
var name = readLine(stdin)
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 ``##``:
.. code-block:: nim
:test: "nim c $1"
# A 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.
.. code-block:: nim
:test: "nim c $1"
#[
You can have any Nim code text commented
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:
.. code-block:: nim
:test: "nim c $1"
discard """ You can have any Nim code text commented
out inside this with no indentation restrictions.
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:
.. code-block::
:test: "nim c $1"
var
x, y: int
# a comment can occur here too
@@ -186,10 +192,11 @@ to a storage location:
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
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"
var x, y = 3 # assigns 3 to the variables `x` and `y`
echo "x ", x # outputs "x 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:
.. code-block:: 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"
const
x = 1
# 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
.. code-block::
:test: "nim c $1"
let input = readLine(stdin) # works
@@ -260,6 +270,7 @@ If statement
The if statement is one way to branch the control flow:
.. code-block:: nim
:test: "nim c $1"
let name = readLine(stdin)
if 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:
.. code-block:: nim
:test: "nim c $1"
let name = readLine(stdin)
case name
of "":
@@ -338,6 +350,7 @@ While statement
The while statement is a simple looping construct:
.. code-block:: nim
:test: "nim c $1"
echo "What's your name? "
var name = readLine(stdin)
@@ -358,6 +371,7 @@ provides. The example uses the built-in `countup <system.html#countup>`_
iterator:
.. code-block:: nim
:test: "nim c $1"
echo "Counting to ten: "
for i in countup(1, 10):
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)
.. code-block:: nim
:test: "nim c $1"
for index, item in ["a","b"].pairs:
echo item, " at index ", index
# => a at index 0
@@ -421,6 +436,8 @@ 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
while false:
var x = "hi"
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:
.. code-block:: nim
:test: "nim c $1"
:status: 1
block myblock:
var x = "hi"
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:
.. code-block:: nim
:test: "nim c $1"
block myblock:
echo "entering block"
while true:
@@ -465,6 +485,7 @@ Like in many other programming languages, a ``continue`` statement starts
the next iteration immediately:
.. code-block:: nim
:test: "nim c $1"
while true:
let x = readLine(stdin)
if x == "": continue
@@ -477,6 +498,7 @@ When statement
Example:
.. code-block:: nim
:test: "nim c $1"
when system.hostOS == "windows":
echo "running on Windows!"
@@ -549,6 +571,7 @@ an expression is allowed:
.. code-block:: nim
# computes fac(4) at compile time:
:test: "nim c $1"
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:
.. code-block:: nim
:test: "nim c $1"
proc yes(question: string): bool =
echo question, " (y/n)"
while true:
@@ -597,6 +621,7 @@ automatically at the end of a procedure if there is no ``return`` statement at
the exit.
.. code-block:: nim
:test: "nim c $1"
proc sumTillNegative(x: varargs[int]): int =
for i in x:
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:
.. code-block:: 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:
@@ -633,6 +659,7 @@ If the procedure needs to modify the argument for the
caller, a ``var`` parameter can be used:
.. code-block:: 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
@@ -663,6 +690,7 @@ 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"
proc p(x, y: int): int {.discardable.} =
return x + y
@@ -772,6 +800,7 @@ The "``" notation can also be used to call an operator just like any other
procedure:
.. code-block:: nim
:test: "nim c $1"
if `==`( `+`(3, 4), 7): echo "True"
@@ -819,6 +848,7 @@ Iterators
Let's return to the simple counting example:
.. code-block:: nim
:test: "nim c $1"
echo "Counting to ten: "
for i in countup(1, 10):
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:
.. code-block:: nim
:test: "nim c $1"
iterator countup(a, b: int): int =
var res = a
while res <= b:
@@ -894,7 +925,8 @@ evaluation. For example:
Characters
----------
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 resulting programs will still handle UTF-8 properly as UTF-8 was specially
designed for this.
@@ -945,6 +977,7 @@ to specify a non-default integer type:
.. code-block:: nim
:test: "nim c $1"
let
x = 0 # x is of type ``int``
y = 0'i8 # y is of type ``int8``
@@ -981,6 +1014,7 @@ Float literals can have a *type suffix* to specify a non-default float
type:
.. code-block:: nim
:test: "nim c $1"
var
x = 0.0 # x is of type ``float``
y = 0.0'f32 # y is of type ``float32``
@@ -1002,6 +1036,7 @@ Conversion between basic types is performed by using the
type as a function:
.. code-block:: nim
:test: "nim c $1"
var
x: int32 = 1.int32 # same as calling int32(1)
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:
.. code-block:: nim
:test: "nim c $1"
var
myBool = true
myCharacter = 'n'
@@ -1047,6 +1083,7 @@ Advanced types
In Nim new types can be defined within a ``type`` statement:
.. code-block:: nim
:test: "nim c $1"
type
biggestInt = int64 # biggest integer 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:
.. code-block:: nim
:test: "nim c $1"
type
Direction = enum
@@ -1087,6 +1125,7 @@ explicitly given is assigned the value of the previous symbol + 1.
An explicit ordered enum can have *holes*:
.. code-block:: nim
:test: "nim c $1"
type
MyEnum = enum
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:
.. code-block:: nim
:test: "nim c $1"
type
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 ``[]``:
.. code-block:: nim
:test: "nim c $1"
type
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.
.. code-block:: nim
:test: "nim c $1"
type
Direction = enum
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:
.. code-block:: 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
@@ -1260,6 +1303,7 @@ A sequence may be passed to an openarray parameter.
Example:
.. code-block:: nim
:test: "nim c $1"
var
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:
.. code-block:: nim
:test: "nim c $1"
for value in @[3, 4, 5]:
echo value
# --> 3
@@ -1308,6 +1353,7 @@ 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"
var
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
@@ -1337,6 +1383,7 @@ arguments to a procedure. The compiler converts the list of arguments
to an array automatically:
.. code-block:: nim
:test: "nim c $1"
proc myWriteln(f: File, a: varargs[string]) =
for s in items(a):
write(f, s)
@@ -1351,6 +1398,7 @@ last parameter in the procedure header. It is also possible to perform
type conversions in this context:
.. code-block:: nim
:test: "nim c $1"
proc myWriteln(f: File, a: varargs[string, `$`]) =
for s in items(a):
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.
.. code-block:: nim
:test: "nim c $1"
var
a = "Nim is a progamming language"
@@ -1429,6 +1478,7 @@ The assignment operator for tuples copies each component. The notation
integer.
.. code-block:: nim
:test: "nim c $1"
type
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:
.. code-block:: nim
:test: "nim c $1"
import os
@@ -1513,6 +1564,7 @@ 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"
type
Node = ref object
@@ -1542,6 +1594,7 @@ techniques.
Example:
.. code-block:: nim
:test: "nim c $1"
proc echoItem(x: int) = echo x
proc forEach(action: proc (x: int)) =