fixes #277; documentation improvements
This commit is contained in:
parent
e516571b47
commit
3be576222a
5 changed files with 198 additions and 115 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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", [
|
||||||
|
|
|
||||||
299
doc/manual.txt
299
doc/manual.txt
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
===========
|
===========
|
||||||
|
|
|
||||||
1
todo.txt
1
todo.txt
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue