fixes #277; documentation improvements

This commit is contained in:
Araq 2012-12-17 19:30:43 +01:00
commit 3be576222a
5 changed files with 198 additions and 115 deletions

View file

@ -124,6 +124,7 @@ proc genBreakState(p: BProc, n: PNode) =
lineF(p, cpsStmts, "if ((((NI*) $1.ClEnv)[0]) < 0) break;$n", [rdLoc(a)]) lineF(p, cpsStmts, "if ((((NI*) $1.ClEnv)[0]) < 0) break;$n", [rdLoc(a)])
# lineF(p, cpsStmts, "if (($1) < 0) break;$n", [rdLoc(a)]) # lineF(p, cpsStmts, "if (($1) < 0) break;$n", [rdLoc(a)])
proc genVarPrototypeAux(m: BModule, sym: PSym)
proc genSingleVar(p: BProc, a: PNode) = proc genSingleVar(p: BProc, a: PNode) =
var v = a.sons[0].sym var v = a.sons[0].sym
if sfCompileTime in v.flags: return if sfCompileTime in v.flags: return
@ -142,6 +143,9 @@ proc genSingleVar(p: BProc, a: PNode) =
genObjectInit(p.module.preInitProc, cpsInit, v.typ, v.loc, true) genObjectInit(p.module.preInitProc, cpsInit, v.typ, v.loc, true)
# Alternative construction using default constructor (which may zeromem): # Alternative construction using default constructor (which may zeromem):
# if sfImportc notin v.flags: constructLoc(p.module.preInitProc, v.loc) # if sfImportc notin v.flags: constructLoc(p.module.preInitProc, v.loc)
if sfExportc in v.flags and generatedHeader != nil:
genVarPrototypeAux(generatedHeader, v)
else: else:
assignLocalVar(p, v) assignLocalVar(p, v)
initLocalVar(p, v, immediateAsgn) initLocalVar(p, v, immediateAsgn)

View file

@ -799,8 +799,6 @@ proc genVarPrototypeAux(m: BModule, sym: PSym) =
proc genVarPrototype(m: BModule, sym: PSym) = proc genVarPrototype(m: BModule, sym: PSym) =
genVarPrototypeAux(m, sym) genVarPrototypeAux(m, sym)
if sfExportc in sym.flags and generatedHeader != nil:
genVarPrototypeAux(generatedHeader, sym)
proc addIntTypes(result: var PRope) {.inline.} = proc addIntTypes(result: var PRope) {.inline.} =
appf(result, "#define NIM_INTBITS $1", [ appf(result, "#define NIM_INTBITS $1", [

View file

@ -479,11 +479,8 @@ The grammar's start symbol is ``module``.
Semantics
=========
Types Types
----- =====
All expressions have a `type`:idx: which is known at compile time. Nimrod All expressions have a `type`:idx: which is known at compile time. Nimrod
is statically typed. One can declare new types, which is in essence defining is statically typed. One can declare new types, which is in essence defining
@ -502,7 +499,7 @@ These are the major type classes:
Ordinal types Ordinal types
~~~~~~~~~~~~~ -------------
`Ordinal types`:idx: have the following characteristics: `Ordinal types`:idx: have the following characteristics:
- Ordinal types are countable and ordered. This property allows - Ordinal types are countable and ordered. This property allows
@ -519,7 +516,7 @@ the types ``uint`` and ``uint64`` are no ordinal types.
Pre-defined integer types Pre-defined integer types
~~~~~~~~~~~~~~~~~~~~~~~~~ -------------------------
These integer types are pre-defined: These integer types are pre-defined:
``int`` ``int``
@ -602,7 +599,7 @@ For further details, see `Convertible relation`_.
Subrange types Subrange types
~~~~~~~~~~~~~~ --------------
A `subrange`:idx: type is a range of values from an ordinal type (the base A `subrange`:idx: type is a range of values from an ordinal type (the base
type). To define a subrange type, one must specify it's limiting values: the type). To define a subrange type, one must specify it's limiting values: the
lowest and highest value of the type: lowest and highest value of the type:
@ -642,7 +639,7 @@ This means that the following code is accepted:
Pre-defined floating point types Pre-defined floating point types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --------------------------------
The following floating point types are pre-defined: The following floating point types are pre-defined:
@ -703,7 +700,7 @@ the ``+``, ``-``, ``*``, ``/`` operators for floating point types.
Boolean type Boolean type
~~~~~~~~~~~~ ------------
The `boolean`:idx: type is named `bool`:idx: in Nimrod and can be one of the two The `boolean`:idx: type is named `bool`:idx: in Nimrod and can be one of the two
pre-defined values ``true`` and ``false``. Conditions in while, pre-defined values ``true`` and ``false``. Conditions in while,
if, elif, when statements need to be of type bool. if, elif, when statements need to be of type bool.
@ -727,7 +724,7 @@ The size of the bool type is one byte.
Character type Character type
~~~~~~~~~~~~~~ --------------
The `character type`:idx: is named ``char`` in Nimrod. Its size is one byte. The `character type`:idx: is named ``char`` in Nimrod. Its size is one byte.
Thus it cannot represent an UTF-8 character, but a part of it. Thus it cannot represent an UTF-8 character, but a part of it.
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,
@ -741,7 +738,7 @@ character. ``TRune`` is declared in the ``unicode`` module.
Enumeration types Enumeration types
~~~~~~~~~~~~~~~~~ -----------------
`Enumeration`:idx: types define a new type whose values consist of the ones `Enumeration`:idx: types define a new type whose values consist of the ones
specified. The values are ordered. Example: specified. The values are ordered. Example:
@ -811,7 +808,7 @@ via ``TMyEnum.value``:
String type String type
~~~~~~~~~~~ -----------
All string literals are of the type `string`:idx:. A string in Nimrod is very All string literals are of the type `string`:idx:. A string in Nimrod is very
similar to a sequence of characters. However, strings in Nimrod are both similar to a sequence of characters. However, strings in Nimrod are both
zero-terminated and have a length field. One can retrieve the length with the zero-terminated and have a length field. One can retrieve the length with the
@ -838,7 +835,7 @@ module can be used for iteration over all Unicode characters.
CString type CString type
~~~~~~~~~~~~ ------------
The `cstring`:idx: type represents a pointer to a zero-terminated char array The `cstring`:idx: type represents a pointer to a zero-terminated char array
compatible to the type ``char*`` in Ansi C. Its primary purpose lies in easy compatible to the type ``char*`` in Ansi C. Its primary purpose lies in easy
interfacing with C. The index operation ``s[i]`` means the i-th *char* of interfacing with C. The index operation ``s[i]`` means the i-th *char* of
@ -864,13 +861,13 @@ not work.
Structured types Structured types
~~~~~~~~~~~~~~~~ ----------------
A variable of a `structured type`:idx: can hold multiple values at the same A variable of a `structured type`:idx: can hold multiple values at the same
time. Structured types can be nested to unlimited levels. Arrays, sequences, time. Structured types can be nested to unlimited levels. Arrays, sequences,
tuples, objects and sets belong to the structured types. tuples, objects and sets belong to the structured types.
Array and sequence types Array and sequence types
~~~~~~~~~~~~~~~~~~~~~~~~ ------------------------
`Arrays`:idx: are a homogeneous type, meaning that each element in the array `Arrays`:idx: are a homogeneous type, meaning that each element in the array
has the same type. Arrays always have a fixed length which is specified at has the same type. Arrays always have a fixed length which is specified at
compile time (except for open arrays). They can be indexed by any ordinal type. compile time (except for open arrays). They can be indexed by any ordinal type.
@ -918,7 +915,7 @@ The current implementation does not support nested open arrays.
Varargs Varargs
~~~~~~~ -------
A `varargs`:idx: parameter is an openarray parameter that additionally A `varargs`:idx: parameter is an openarray parameter that additionally
allows to pass a variable number of arguments to a procedure. The compiler allows to pass a variable number of arguments to a procedure. The compiler
@ -954,7 +951,7 @@ parameter ``a``. (Note that ``$`` applied to strings is a nop.)
Tuples and object types Tuples and object types
~~~~~~~~~~~~~~~~~~~~~~~ -----------------------
A variable of a `tuple`:idx: or `object`:idx: type is a heterogeneous storage A variable of a `tuple`:idx: or `object`:idx: type is a heterogeneous storage
container. container.
A tuple or object defines various named *fields* of a type. A tuple also A tuple or object defines various named *fields* of a type. A tuple also
@ -1022,7 +1019,7 @@ introduce new object roots apart from ``system.TObject``.
Object variants Object variants
~~~~~~~~~~~~~~~ ---------------
Often an object hierarchy is overkill in certain situations where simple Often an object hierarchy is overkill in certain situations where simple
`variant`:idx: types are needed. `variant`:idx: types are needed.
@ -1069,7 +1066,7 @@ the ``case`` statement: The branches in a ``case`` section may be indented too.
Set type Set type
~~~~~~~~ --------
The `set type`:idx: models the mathematical notion of a set. The set's The `set type`:idx: models the mathematical notion of a set. The set's
basetype can only be an ordinal type. The reason is that sets are implemented basetype can only be an ordinal type. The reason is that sets are implemented
as high performance bit vectors. as high performance bit vectors.
@ -1104,7 +1101,7 @@ operation meaning
Reference and pointer types Reference and pointer types
~~~~~~~~~~~~~~~~~~~~~~~~~~~ ---------------------------
References (similar to `pointers`:idx: in other programming languages) are a References (similar to `pointers`:idx: in other programming languages) are a
way to introduce many-to-one relationships. This means different references can way to introduce many-to-one relationships. This means different references can
point to and modify the same location in memory (also called `aliasing`:idx:). point to and modify the same location in memory (also called `aliasing`:idx:).
@ -1193,14 +1190,14 @@ mysterious crashes.
**Note**: The example only works because the memory is initialized to zero **Note**: The example only works because the memory is initialized to zero
(``alloc0`` instead of ``alloc`` does this): ``d.s`` is thus initialized to (``alloc0`` instead of ``alloc`` does this): ``d.s`` is thus initialized to
``nil`` which the string assignment can handle. You need to know low level ``nil`` which the string assignment can handle. One needs to know low level
details like this when mixing garbage collected data with unmanaged memory. details like this when mixing garbage collected data with unmanaged memory.
.. XXX finalizers for traced objects .. XXX finalizers for traced objects
Not nil annotation Not nil annotation
~~~~~~~~~~~~~~~~~~ ------------------
All types for that ``nil`` is a valid value can be annotated to All types for that ``nil`` is a valid value can be annotated to
exclude ``nil`` as a valid value with the `not nil`:idx: annotation: exclude ``nil`` as a valid value with the `not nil`:idx: annotation:
@ -1225,7 +1222,7 @@ for now the compiler can only catch the most trivial type violations.
Procedural type Procedural type
~~~~~~~~~~~~~~~ ---------------
A `procedural type`:idx: is internally a pointer to a procedure. ``nil`` is A `procedural type`:idx: is internally a pointer to a procedure. ``nil`` is
an allowed value for variables of a procedural type. Nimrod uses procedural an allowed value for variables of a procedural type. Nimrod uses procedural
types to achieve `functional`:idx: programming techniques. types to achieve `functional`:idx: programming techniques.
@ -1335,7 +1332,7 @@ accesses its environment. If it does so, it has the calling convention
Distinct type Distinct type
~~~~~~~~~~~~~ -------------
A distinct type is new type derived from a `base type`:idx: that is A distinct type is new type derived from a `base type`:idx: that is
incompatible with its base type. In particular, it is an essential property incompatible with its base type. In particular, it is an essential property
@ -1431,9 +1428,9 @@ currency. This can be solved with templates_.
Void type Void type
~~~~~~~~~ ---------
The `void`:idx: type denotes the absence of any type. Parameters of The `void`:idx: type denotes the absense of any type. Parameters of
type ``void`` are treated as non-existent, ``void`` as a return type means that type ``void`` are treated as non-existent, ``void`` as a return type means that
the procedure does not return a value: the procedure does not return a value:
@ -1471,14 +1468,14 @@ cannot have the type ``void``.
Type relations Type relations
-------------- ==============
The following section defines several relations on types that are needed to The following section defines several relations on types that are needed to
describe the type checking done by the compiler. describe the type checking done by the compiler.
Type equality Type equality
~~~~~~~~~~~~~ -------------
Nimrod uses structural type equivalence for most types. Only for objects, Nimrod uses structural type equivalence for most types. Only for objects,
enumerations and distinct types name equivalence is used. The following enumerations and distinct types name equivalence is used. The following
algorithm (in pseudo-code) determines type equality: algorithm (in pseudo-code) determines type equality:
@ -1523,7 +1520,7 @@ auxiliary set ``s`` to detect this case.
Type equality modulo type distinction Type equality modulo type distinction
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -------------------------------------
The following algorithm (in pseudo-code) determines whether two types The following algorithm (in pseudo-code) determines whether two types
are equal with no respect to ``distinct`` types. For brevity the cycle check are equal with no respect to ``distinct`` types. For brevity the cycle check
@ -1565,7 +1562,7 @@ with an auxiliary set ``s`` is omitted:
Subtype relation Subtype relation
~~~~~~~~~~~~~~~~ ----------------
If object ``a`` inherits from ``b``, ``a`` is a subtype of ``b``. This subtype If object ``a`` inherits from ``b``, ``a`` is a subtype of ``b``. This subtype
relation is extended to the types ``var``, ``ref``, ``ptr``: relation is extended to the types ``var``, ``ref``, ``ptr``:
@ -1584,7 +1581,7 @@ relation is extended to the types ``var``, ``ref``, ``ptr``:
Convertible relation Convertible relation
~~~~~~~~~~~~~~~~~~~~ --------------------
A type ``a`` is **implicitly** convertible to type ``b`` iff the following A type ``a`` is **implicitly** convertible to type ``b`` iff the following
algorithm returns true: algorithm returns true:
@ -1651,20 +1648,21 @@ The type conversion ``T(a)`` is an L-value if ``a`` is an L-value and
Assignment compatibility Assignment compatibility
~~~~~~~~~~~~~~~~~~~~~~~~ ------------------------
An expression ``b`` can be assigned to an expression ``a`` iff ``a`` is an An expression ``b`` can be assigned to an expression ``a`` iff ``a`` is an
`l-value` and ``isImplicitlyConvertible(b.typ, a.typ)`` holds. `l-value` and ``isImplicitlyConvertible(b.typ, a.typ)`` holds.
Overloading resolution Overloading resolution
~~~~~~~~~~~~~~~~~~~~~~ ----------------------
To be written. To be written.
Statements and expressions Statements and expressions
-------------------------- ==========================
Nimrod uses the common statement/expression paradigm: `Statements`:idx: do not Nimrod uses the common statement/expression paradigm: `Statements`:idx: do not
produce a value in contrast to expressions. Call expressions are statements. produce a value in contrast to expressions. Call expressions are statements.
If the called procedure returns a value, it is not a valid statement If the called procedure returns a value, it is not a valid statement
@ -1698,7 +1696,7 @@ statements always have to be intended::
Discard statement Discard statement
~~~~~~~~~~~~~~~~~ -----------------
Syntax:: Syntax::
@ -1729,7 +1727,7 @@ been declared with the `discardable`:idx: pragma:
Var statement Var statement
~~~~~~~~~~~~~ -------------
Syntax:: Syntax::
@ -1790,7 +1788,7 @@ If a proc is annotated with the ``noinit`` pragma this refers to its implicit
let statement let statement
~~~~~~~~~~~~~ -------------
A `Let`:idx: statement declares new local and global `single assignment`:idx: A `Let`:idx: statement declares new local and global `single assignment`:idx:
variables and binds a value to them. The syntax is the of the ``var`` variables and binds a value to them. The syntax is the of the ``var``
@ -1802,7 +1800,7 @@ For let variables the same pragmas are available as for ordinary variables.
Const section Const section
~~~~~~~~~~~~~ -------------
Syntax:: Syntax::
@ -1840,7 +1838,7 @@ they contain such a type.
Static statement/expression Static statement/expression
~~~~~~~~~~~~~~~~~~~~~~~~~~~ ---------------------------
Syntax:: Syntax::
staticExpr ::= 'static' '(' optInd expr optPar ')' staticExpr ::= 'static' '(' optInd expr optPar ')'
@ -1865,7 +1863,7 @@ support the FFI at compile time.
If statement If statement
~~~~~~~~~~~~ ------------
Syntax:: Syntax::
@ -1895,7 +1893,7 @@ part, execution continues with the statement after the ``if`` statement.
Case statement Case statement
~~~~~~~~~~~~~~ --------------
Syntax:: Syntax::
@ -1961,7 +1959,7 @@ a list of its elements:
When statement When statement
~~~~~~~~~~~~~~ --------------
Syntax:: Syntax::
@ -1995,7 +1993,7 @@ within ``object`` definitions.
Return statement Return statement
~~~~~~~~~~~~~~~~ ----------------
Syntax:: Syntax::
@ -2026,7 +2024,7 @@ variables, ``result`` is initialized to (binary) zero:
Yield statement Yield statement
~~~~~~~~~~~~~~~ ---------------
Syntax:: Syntax::
@ -2046,7 +2044,7 @@ for further information.
Block statement Block statement
~~~~~~~~~~~~~~~ ---------------
Syntax:: Syntax::
@ -2071,7 +2069,7 @@ block to specify which block is to leave.
Break statement Break statement
~~~~~~~~~~~~~~~ ---------------
Syntax:: Syntax::
@ -2088,7 +2086,7 @@ absent, the innermost block is left.
While statement While statement
~~~~~~~~~~~~~~~ ---------------
Syntax:: Syntax::
@ -2110,7 +2108,7 @@ so that they can be left with a ``break`` statement.
Continue statement Continue statement
~~~~~~~~~~~~~~~~~~ ------------------
Syntax:: Syntax::
@ -2137,7 +2135,7 @@ Is equivalent to:
Assembler statement Assembler statement
~~~~~~~~~~~~~~~~~~~ -------------------
Syntax:: Syntax::
asmStmt ::= 'asm' [pragma] (STR_LIT | RSTR_LIT | TRIPLESTR_LIT) asmStmt ::= 'asm' [pragma] (STR_LIT | RSTR_LIT | TRIPLESTR_LIT)
@ -2159,7 +2157,7 @@ specified in the statement's pragmas. The default special character is ``'`'``:
""" """
If expression If expression
~~~~~~~~~~~~~ -------------
An `if expression` is almost like an if statement, but it is an expression. An `if expression` is almost like an if statement, but it is an expression.
Example: Example:
@ -2172,12 +2170,12 @@ required. ``Elif`` parts are also allowed (but unlikely to be good
style). style).
When expression When expression
~~~~~~~~~~~~~~~ ---------------
Just like an `if expression`, but corresponding to the when statement. Just like an `if expression`, but corresponding to the when statement.
Case expression Case expression
~~~~~~~~~~~~~~~ ---------------
The `case expression` is again very similar to the case statement: The `case expression` is again very similar to the case statement:
@ -2195,7 +2193,7 @@ effects. When multiple statements are given for a branch, Nimrod will use
the last expression as the result value, much like in an `expr` template. the last expression as the result value, much like in an `expr` template.
Table constructor Table constructor
~~~~~~~~~~~~~~~~~ -----------------
A `table constructor`:idx: is syntactic sugar for an array constructor: A `table constructor`:idx: is syntactic sugar for an array constructor:
@ -2223,7 +2221,7 @@ has lots of advantages:
Type conversions Type conversions
~~~~~~~~~~~~~~~~ ----------------
Syntactically a `type conversion` is like a procedure call, but a Syntactically a `type conversion` is like a procedure call, but a
type name replaces the procedure name. A type conversion is always type name replaces the procedure name. A type conversion is always
safe in the sense that a failure to convert a type to another safe in the sense that a failure to convert a type to another
@ -2231,7 +2229,7 @@ results in an exception (if it cannot be determined statically).
Type casts Type casts
~~~~~~~~~~ ----------
Example: Example:
@ -2244,7 +2242,7 @@ only needed for low-level programming and are inherently unsafe.
The addr operator The addr operator
~~~~~~~~~~~~~~~~~ -----------------
The `addr` operator returns the address of an l-value. If the The `addr` operator returns the address of an l-value. If the
type of the location is ``T``, the `addr` operator result is type of the location is ``T``, the `addr` operator result is
of the type ``ptr T``. Taking the address of an object that resides of the type ``ptr T``. Taking the address of an object that resides
@ -2253,7 +2251,8 @@ object on the stack and can thus reference a non-existing object.
Procedures Procedures
~~~~~~~~~~ ==========
What most programming languages call `methods`:idx: or `functions`:idx: are What most programming languages call `methods`:idx: or `functions`:idx: are
called `procedures`:idx: in Nimrod (which is the correct terminology). A called `procedures`:idx: in Nimrod (which is the correct terminology). A
procedure declaration defines an identifier and associates it with a block procedure declaration defines an identifier and associates it with a block
@ -2332,7 +2331,7 @@ notation. (Thus an operator can have more than two parameters):
assert `*+`(3, 4, 6) == `*`(a, `+`(b, c)) assert `*+`(3, 4, 6) == `*`(a, `+`(b, c))
Closures Closures
~~~~~~~~ --------
Procedures can appear at the top level in a module as well as inside other Procedures can appear at the top level in a module as well as inside other
scopes, in which case they are called nested procs. A nested proc can access scopes, in which case they are called nested procs. A nested proc can access
@ -2344,7 +2343,7 @@ visible in both places). The closure environment may be allocated on the heap
or on the stack if the compiler determines that this would be safe. or on the stack if the compiler determines that this would be safe.
Anonymous Procs Anonymous Procs
~~~~~~~~~~~~~~~ ---------------
Procs can also be treated as expressions, in which case it's allowed to omit Procs can also be treated as expressions, in which case it's allowed to omit
the proc's name. the proc's name.
@ -2360,7 +2359,7 @@ Procs as expressions can appear both as nested procs and inside top level
executable code. executable code.
Do notation Do notation
~~~~~~~~~~~ -----------
As a special more convenient notation, proc expressions involved in procedure As a special more convenient notation, proc expressions involved in procedure
calls can use the ``do`` keyword: calls can use the ``do`` keyword:
@ -2399,7 +2398,7 @@ The compatibility works in the other direction too as the ``do`` syntax can be
used with macros and templates expecting ``stmt`` blocks. used with macros and templates expecting ``stmt`` blocks.
Nonoverloadable builtins Nonoverloadable builtins
~~~~~~~~~~~~~~~~~~~~~~~~ ------------------------
The following builtin procs cannot be overloaded for reasons of implementation The following builtin procs cannot be overloaded for reasons of implementation
simplicity (they require specialized semantic checking):: simplicity (they require specialized semantic checking)::
@ -2413,7 +2412,7 @@ the ``system`` module.
Var parameters Var parameters
~~~~~~~~~~~~~~ --------------
The type of a parameter may be prefixed with the ``var`` keyword: The type of a parameter may be prefixed with the ``var`` keyword:
.. code-block:: nimrod .. code-block:: nimrod
@ -2465,7 +2464,7 @@ One can use `tuple unpacking`:idx: to access the tuple's fields:
Var return type Var return type
~~~~~~~~~~~~~~~ ---------------
A proc, converter or iterator may return a ``var`` type which means that the A proc, converter or iterator may return a ``var`` type which means that the
returned value is an l-value and can be modified by the caller: returned value is an l-value and can be modified by the caller:
@ -2499,7 +2498,7 @@ starts with the prefix ``m`` per convention.
Overloading of the subscript operator Overloading of the subscript operator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -------------------------------------
The ``[]`` subscript operator for arrays/openarrays/sequences can be overloaded. The ``[]`` subscript operator for arrays/openarrays/sequences can be overloaded.
Overloading support is only possible if the first parameter has no type that Overloading support is only possible if the first parameter has no type that
@ -2508,7 +2507,7 @@ does not check this restriction.
Multi-methods Multi-methods
~~~~~~~~~~~~~ =============
Procedures always use static dispatch. `Multi-methods`:idx: use dynamic Procedures always use static dispatch. `Multi-methods`:idx: use dynamic
dispatch. dispatch.
@ -2580,7 +2579,7 @@ evaluation or dead code elimination do not work with methods.
Iterators and the for statement Iterators and the for statement
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===============================
Syntax:: Syntax::
@ -2598,8 +2597,9 @@ Syntax::
The `for`:idx: statement is an abstract mechanism to iterate over the elements The `for`:idx: statement is an abstract mechanism to iterate over the elements
of a container. It relies on an `iterator`:idx: to do so. Like ``while`` of a container. It relies on an `iterator`:idx: to do so. Like ``while``
statements, ``for`` statements open an `implicit block`:idx:, so that they statements, ``for`` statements open an `implicit block`:idx:, so that they
can be left with a ``break`` statement. The ``for`` loop declares can be left with a ``break`` statement.
The ``for`` loop declares
iteration variables (``x`` in the example) - their scope reaches until the iteration variables (``x`` in the example) - their scope reaches until the
end of the loop body. The iteration variables' types are inferred by the end of the loop body. The iteration variables' types are inferred by the
return type of the iterator. return type of the iterator.
@ -2632,18 +2632,13 @@ The compiler generates code as if the programmer would have written this:
echo(ch) echo(ch)
inc(i) inc(i)
The current implementation always inlines the iterator code leading to zero
overhead for the abstraction. But this may increase the code size. Later
versions of the compiler will only inline iterators which have the calling
convention ``inline``.
If the iterator yields a tuple, there have to be as many iteration variables If the iterator yields a tuple, there have to be as many iteration variables
as there are components in the tuple. The i'th iteration variable's type is as there are components in the tuple. The i'th iteration variable's type is
the type of the i'th component. the type of the i'th component.
Implict items/pairs invocations Implict items/pairs invocations
+++++++++++++++++++++++++++++++ -------------------------------
If the for loop expression ``e`` does not denote an iterator and the for loop If the for loop expression ``e`` does not denote an iterator and the for loop
has exactly 1 variable, the for loop expression is rewritten to ``items(e)``; has exactly 1 variable, the for loop expression is rewritten to ``items(e)``;
@ -2660,8 +2655,90 @@ the rewriting step, so that all overloadings of ``items``/``pairs`` are taken
into account. into account.
First class iterators
---------------------
There are 2 kinds of iterators in Nimrod: *inline* and *closure* iterators.
An `inline iterator`:idx: is an iterator that's always inlined by the compiler
leading to zero overhead for the abstraction, but may result in a heavy
increasee in code size. Inline iterators are second class
citizens; one cannot pass them around like first class procs.
In contrast to that, a `closure iterator`:idx: can be passed around:
.. code-block:: nimrod
iterator count0(): int {.closure.} =
yield 0
iterator count2(): int {.closure.} =
var x = 1
yield x
inc x
yield x
proc invoke(iter: iterator(): int {.closure.}) =
for x in iter(): echo x
invoke(count0)
invoke(count2)
Closure iterators have other restrictions than inline iterators:
1.) ``yield`` in a closure iterator can not occur in a ``try`` statement.
2.) For now, a closure iterator cannot be evaluated at compile time.
3.) ``return`` is allowed in a closure iterator (but rarely useful).
4.) Since closure iterators can be used as a collaborative tasking
system, ``void`` is a valid return type for them.
5.) Both inline and closure iterators cannot be recursive.
Iterators that are neither marked ``{.closure.}`` nor ``{.inline.}`` explicitly
default to being inline, but that this may change in future versions of the
implementation.
The ``iterator`` type is always of the calling convention ``closure``
implicitly; the following example shows how to use iterators to implement
a `collaborative tasking`:idx: system:
.. code-block:: nimrod
# simple tasking:
type
TTask = iterator (ticker: int)
iterator a1(ticker: int) {.closure.} =
echo "a1: A"
yield
echo "a1: B"
yield
echo "a1: C"
yield
echo "a1: D"
iterator a2(ticker: int) {.closure.} =
echo "a2: A"
yield
echo "a2: B"
yield
echo "a2: C"
proc runTasks(t: varargs[TTask]) =
var ticker = 0
while true:
let x = t[ticker mod t.len]
if finished(x): break
x(ticker)
inc ticker
runTasks(a1, a2)
The builtin ``system.finished`` can be used to determine if an iterator has
finished its operation; no exception is raised on an attempt to invoke an
iterator that has already finished its work.
Type sections Type sections
~~~~~~~~~~~~~ =============
Syntax:: Syntax::
@ -2697,10 +2774,10 @@ possible within a single ``type`` section.
Exception handling Exception handling
------------------ ==================
Try statement Try statement
~~~~~~~~~~~~~ -------------
Syntax:: Syntax::
@ -2755,7 +2832,7 @@ is not executed (if an exception occurs).
Except and finally statements Except and finally statements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -----------------------------
`except`:idx: and `finally`:idx: can also be used as a stand-alone statements. `except`:idx: and `finally`:idx: can also be used as a stand-alone statements.
Any statements following them in the current block will be considered to be Any statements following them in the current block will be considered to be
@ -2768,7 +2845,7 @@ in an implicit try block:
Raise statement Raise statement
~~~~~~~~~~~~~~~ ---------------
Syntax:: Syntax::
@ -2791,7 +2868,7 @@ exception (unless a raise hook has been provided).
OnRaise builtin OnRaise builtin
~~~~~~~~~~~~~~~ ---------------
``system.onRaise`` can be used to override the behaviour of ``raise`` for a ``system.onRaise`` can be used to override the behaviour of ``raise`` for a
single ``try`` statement. `onRaise`:idx: has to be called within the ``try`` single ``try`` statement. `onRaise`:idx: has to be called within the ``try``
@ -2815,10 +2892,10 @@ This allows for a Lisp-like `condition system`:idx:\:
Effect system Effect system
------------- =============
Exception tracking Exception tracking
~~~~~~~~~~~~~~~~~~ ------------------
Nimrod supports `exception tracking`:idx:. The `raises`:idx: pragma can used to Nimrod supports `exception tracking`:idx:. The `raises`:idx: pragma can used to
explicitly define which exceptions a proc/iterator/method/converter is allowed explicitly define which exceptions a proc/iterator/method/converter is allowed
@ -2873,7 +2950,7 @@ possibly raised exceptions; the algorithm operates on ``p``'s call graph:
Tag tracking Tag tracking
~~~~~~~~~~~~ ------------
The exception tracking is part of Nimrod's `effect system`:idx:. Raising an The exception tracking is part of Nimrod's `effect system`:idx:. Raising an
exception is an *effect*. Other effects can also be defined. A user defined exception is an *effect*. Other effects can also be defined. A user defined
@ -2895,7 +2972,7 @@ exception tracking.
Read/Write tracking Read/Write tracking
~~~~~~~~~~~~~~~~~~~ -------------------
**Note**: Read/write tracking is not yet implemented! **Note**: Read/write tracking is not yet implemented!
@ -2904,7 +2981,7 @@ exception tracking.
Effects pragma Effects pragma
~~~~~~~~~~~~~~ --------------
The `effects`:idx: pragma has been designed to assist the programmer with the The `effects`:idx: pragma has been designed to assist the programmer with the
effects analysis. It is a statement that makes the compiler output all inferred effects analysis. It is a statement that makes the compiler output all inferred
@ -2923,7 +3000,7 @@ listed as it cannot be raised in the branch the ``effects`` pragma appears in.
Generics Generics
-------- ========
Example: Example:
@ -2981,7 +3058,7 @@ introduce type parameters or to instantiate a generic proc, iterator or type.
Is operator Is operator
~~~~~~~~~~~ -----------
The `is`:idx: operator checks for type equivalence at compile time. It is The `is`:idx: operator checks for type equivalence at compile time. It is
therefore very useful for type specialization within generic code: therefore very useful for type specialization within generic code:
@ -2996,7 +3073,7 @@ therefore very useful for type specialization within generic code:
Type operator Type operator
~~~~~~~~~~~~~ -------------
The `type`:idx: (in many other languages called `typeof`:idx:) operator can The `type`:idx: (in many other languages called `typeof`:idx:) operator can
be used to get the type of an expression: be used to get the type of an expression:
@ -3019,7 +3096,7 @@ other interpretations:
Type Classes Type Classes
~~~~~~~~~~~~ ------------
A `type class`:idx: is a special pseudo-type that can be used to match against A `type class`:idx: is a special pseudo-type that can be used to match against
types in the context of overload resolution or the ``is`` operator. types in the context of overload resolution or the ``is`` operator.
@ -3108,13 +3185,15 @@ the dot syntax:
If anonymous type classes are used, the ``type`` operator can be used to If anonymous type classes are used, the ``type`` operator can be used to
discover the instantiated type of each param. discover the instantiated type of each param.
User defined type classes User defined type classes
~~~~~~~~~~~~~~~~~~~~~~~~~ -------------------------
To be written. To be written.
Return Type Inference Return Type Inference
~~~~~~~~~~~~~~~~~~~~~ ---------------------
If a type class is used as the return type of a proc and it won't be bound to If a type class is used as the return type of a proc and it won't be bound to
a concrete type by some of the proc params, Nimrod will infer the return type a concrete type by some of the proc params, Nimrod will infer the return type
@ -3132,7 +3211,7 @@ also influence the inferred return type.
Symbol lookup in generics Symbol lookup in generics
~~~~~~~~~~~~~~~~~~~~~~~~~ -------------------------
The symbol binding rules in generics are slightly subtle: There are "open" and The symbol binding rules in generics are slightly subtle: There are "open" and
"closed" symbols. A "closed" symbol cannot be re-bound in the instantiation "closed" symbols. A "closed" symbol cannot be re-bound in the instantiation
@ -3171,7 +3250,7 @@ A symbol can be forced to be open by a `mixin`:idx: declaration:
Templates Templates
--------- =========
A `template`:idx: is a simple form of a macro: It is a simple substitution A `template`:idx: is a simple form of a macro: It is a simple substitution
mechanism that operates on Nimrod's abstract syntax trees. It is processed in mechanism that operates on Nimrod's abstract syntax trees. It is processed in
@ -3202,7 +3281,7 @@ Real types can be used too; this implies that expressions are expected.
Ordinary vs immediate templates Ordinary vs immediate templates
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -------------------------------
There are two different kinds of templates: `immediate`:idx: templates and There are two different kinds of templates: `immediate`:idx: templates and
ordinary templates. Ordinary templates take part in overloading resolution. As ordinary templates. Ordinary templates take part in overloading resolution. As
@ -3229,7 +3308,7 @@ receive undeclared identifiers:
Scoping in templates Scoping in templates
~~~~~~~~~~~~~~~~~~~~ --------------------
The template body does not open a new scope. To open a new scope a ``block`` The template body does not open a new scope. To open a new scope a ``block``
statement can be used: statement can be used:
@ -3251,7 +3330,7 @@ statement can be used:
Passing a code block to a template Passing a code block to a template
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ----------------------------------
If there is a ``stmt`` parameter it should be the last in the template If there is a ``stmt`` parameter it should be the last in the template
declaration, because statements are passed to a template via a declaration, because statements are passed to a template via a
@ -3298,7 +3377,7 @@ Symbol binding within templates happens after template instantiation:
Bind statement Bind statement
~~~~~~~~~~~~~~ --------------
Syntax:: Syntax::
@ -3329,7 +3408,7 @@ A ``bind`` statement can also be used in generics for the same purpose.
Identifier construction Identifier construction
~~~~~~~~~~~~~~~~~~~~~~~ -----------------------
In templates identifiers can be constructed with the backticks notation: In templates identifiers can be constructed with the backticks notation:
@ -3348,7 +3427,7 @@ In the example ``name`` is instantiated with ``myint``, so \`T name\` becomes
Lookup rules for template parameters Lookup rules for template parameters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ------------------------------------
A parameter ``p`` in a template is even substituted in the expression ``x.p``. A parameter ``p`` in a template is even substituted in the expression ``x.p``.
Thus template arguments can be used as field names and a global symbol can be Thus template arguments can be used as field names and a global symbol can be
@ -3389,7 +3468,7 @@ But the global symbol can properly be captured by a ``bind`` statement:
Hygiene in templates Hygiene in templates
~~~~~~~~~~~~~~~~~~~~ --------------------
Per default templates are `hygienic`:idx:\: Local identifiers declared in a Per default templates are `hygienic`:idx:\: Local identifiers declared in a
template cannot be accessed in the instantiation context: template cannot be accessed in the instantiation context:
@ -3444,7 +3523,7 @@ a template. ``inject`` and ``gensym`` have no effect in ``dirty`` templates.
Macros Macros
------ ======
A `macro`:idx: is a special kind of low level template. Macros can be used A `macro`:idx: is a special kind of low level template. Macros can be used
to implement `domain specific languages`:idx:. Like templates, macros come in to implement `domain specific languages`:idx:. Like templates, macros come in
@ -3463,7 +3542,7 @@ There are two ways to invoke a macro:
Expression Macros Expression Macros
~~~~~~~~~~~~~~~~~ -----------------
The following example implements a powerful ``debug`` command that accepts a The following example implements a powerful ``debug`` command that accepts a
variable number of arguments: variable number of arguments:
@ -3517,7 +3596,7 @@ children.
BindSym BindSym
~~~~~~~ -------
The above ``debug`` macro relies on the fact that ``write``, ``writeln`` and The above ``debug`` macro relies on the fact that ``write``, ``writeln`` and
``stdout`` are declared in the system module and thus visible in the ``stdout`` are declared in the system module and thus visible in the
@ -3565,7 +3644,7 @@ overloaded symbols implicitly.
Statement Macros Statement Macros
~~~~~~~~~~~~~~~~ ----------------
Statement macros are defined just as expression macros. However, they are Statement macros are defined just as expression macros. However, they are
invoked by an expression following a colon:: invoked by an expression following a colon::
@ -3609,7 +3688,7 @@ powerful programming construct that still suffices. So the "check list" is:
Macros as pragmas Macros as pragmas
~~~~~~~~~~~~~~~~~ -----------------
Whole routines (procs, iterators etc.) can also be passed to a template or Whole routines (procs, iterators etc.) can also be passed to a template or
a macro via the pragma notation: a macro via the pragma notation:
@ -3629,17 +3708,17 @@ This is a simple syntactic transformation into:
Special Types Special Types
------------- =============
typedesc typedesc
~~~~~~~~ --------
`typedesc` is a special type allowing you to treat types as compile-time values `typedesc` is a special type allowing one to treat types as compile-time values
(i.e. if types are compile-time values and all values have a type, then (i.e. if types are compile-time values and all values have a type, then
typedesc must be their type). typedesc must be their type).
When used as a regular proc param, typedesc acts as a type class. The proc When used as a regular proc param, typedesc acts as a type class. The proc
will be instantiated for each unique type parameter and you can refer to the will be instantiated for each unique type parameter and one can refer to the
instantiation type using the param name: instantiation type using the param name:
.. code-block:: nimrod .. code-block:: nimrod
@ -3654,8 +3733,8 @@ instantiation type using the param name:
When used with macros and .compileTime. procs on the other hand, the compiler When used with macros and .compileTime. procs on the other hand, the compiler
don't need to instantiate the code multiple times, because types then can be don't need to instantiate the code multiple times, because types then can be
manipulated using the unified internal symbol representation. In such context manipulated using the unified internal symbol representation. In such context
typedesc acts as any other type. You can create variables, store typedesc typedesc acts as any other type. One can create variables, store typedesc
values inside containers and so on. For example, here is how we can create values inside containers and so on. For example, here is how one can create
a type-safe wrapper for the unsafe `printf` function from C: a type-safe wrapper for the unsafe `printf` function from C:
.. code-block:: nimrod .. code-block:: nimrod

View file

@ -780,12 +780,15 @@ important differences:
* Iterators cannot contain a ``return`` statement and procs cannot contain a * Iterators cannot contain a ``return`` statement and procs cannot contain a
``yield`` statement. ``yield`` statement.
* Iterators have no implicit ``result`` variable. * Iterators have no implicit ``result`` variable.
* Iterators do not support recursion. (This restriction will be gone in a * Iterators do not support recursion.
future version of the compiler.)
* Iterators cannot be forward declared, because the compiler must be able * Iterators cannot be forward declared, because the compiler must be able
to inline an iterator. (This restriction will be gone in a to inline an iterator. (This restriction will be gone in a
future version of the compiler.) future version of the compiler.)
However, you can also use a ``closure`` iterator to get a different set of
restrictions. See `first class iterators <manual.html#first-class-iterators>`_
for details.
Basic types Basic types
=========== ===========

View file

@ -4,7 +4,6 @@ version 0.9.2
- fix closure bug finally - fix closure bug finally
- test&finish first class iterators: - test&finish first class iterators:
* nested iterators * nested iterators
* document them
- fix marshal bug - fix marshal bug
- investigate nimgame bug - investigate nimgame bug