documented object constrs; endb works again

This commit is contained in:
Araq 2013-03-09 20:43:56 +01:00
commit a64d4dc35c
11 changed files with 152 additions and 143 deletions

View file

@ -984,7 +984,7 @@ in future versions of the compiler.
.. code-block:: nimrod
type
TPerson = tuple[name: string, age: int] # type representing a person
TPerson = tuple[name: string, age: int] # type representing a person:
# a person consists of a name
# and an age
var
@ -1000,7 +1000,6 @@ For consistency with ``object`` declarations, tuples in a ``type`` section
can also be defined with indentation instead of ``[]``:
.. code-block:: nimrod
type
TPerson = tuple # type representing a person
name: string # a person consists of a name
@ -1011,7 +1010,6 @@ and information hiding. Objects have access to their type at runtime, so that
the ``of`` operator can be used to determine the object's type.
.. code-block:: nimrod
type
TPerson {.inheritable.} = object
name*: string # the * means that `name` is accessible from other modules
@ -1032,6 +1030,19 @@ and thus have no hidden type field. One can use the ``inheritable`` pragma to
introduce new object roots apart from ``system.TObject``.
Object construction
-------------------
Objects can also be created with an `object construction expression`:idx: that
has the syntax ``T(fieldA: valueA, fieldB: valueB, ...)`` where ``T`` is
an ``object`` type or a ``ref object`` type:
.. code-block:: nimrod
var student = TStudent(name: "Anton", age: 5, id: 3)
For a ``ref object`` type ``new`` is invoked implicitly.
Object variants
---------------
Often an object hierarchy is overkill in certain situations where simple
@ -1061,15 +1072,22 @@ An example:
of nkIf:
condition, thenPart, elsePart: PNode
var
n: PNode
new(n) # creates a new node
n.kind = nkFloat
n.floatVal = 0.0 # valid, because ``n.kind==nkFloat``, so that it fits
# create a new case object:
var n = PNode(kind: nkIf, condition: nil)
# accessing n.thenPart is valid because the ``nkIf`` branch is active:
n.thenPart = PNode(kind: nkFloat, floatVal: 2.0)
# the following statement raises an `EInvalidField` exception, because
# n.kind's value does not fit:
# n.kind's value does not fit and the ``nkString`` branch is not active:
n.strVal = ""
# invalid: would change the active object branch:
n.kind = nkInt
var x = PNode(kind: nkAdd, leftOp: PNode(kind: nkInt, intVal: 4),
rightOp: PNode(kind: nkInt, intVal: 2))
# valid: does not change the active object branch:
x.kind = nkSub
As can been seen from the example, an advantage to an object hierarchy is that
no casting between different object types is needed. Yet, access to invalid
@ -1078,6 +1096,11 @@ object fields raises an exception.
The syntax of ``case`` in an object declaration follows closely the syntax of
the ``case`` statement: The branches in a ``case`` section may be indented too.
In the example the ``kind`` field is called the `discriminator`:idx:\: For
safety its address cannot be taken and assignments to it are restricted: The
new value must not lead to a change of the active object branch. For an object
branch switch ``system.reset`` has to be used.
Set type
--------
@ -2387,6 +2410,7 @@ the proc's name.
Procs as expressions can appear both as nested procs and inside top level
executable code.
Do notation
-----------
@ -2410,7 +2434,7 @@ Again, let's see the equivalent of the previous example:
sort(cities) do (x,y: string) -> int:
cmp(x.len, y.len)
Finally, more than one ``do`` blocks can appear in a single call:
Finally, more than one ``do`` block can appear in a single call:
.. code-block:: nimrod
proc performWithUndo(task: proc(), undo: proc()) = ...
@ -2426,6 +2450,7 @@ omitted if the supplied proc doesn't have any parameters and return value.
The compatibility works in the other direction too as the ``do`` syntax can be
used with macros and templates expecting ``stmt`` blocks.
Nonoverloadable builtins
------------------------
@ -2987,8 +3012,7 @@ possibly raised exceptions; the algorithm operates on ``p``'s call graph:
raise ``system.E_Base`` unless ``q`` has an explicit ``raises`` list.
3. Every call to a method ``m`` is assumed to
raise ``system.E_Base`` unless ``m`` has an explicit ``raises`` list.
4. For every other call the analysis can determine an
exact ``raises`` list.
4. For every other call the analysis can determine an exact ``raises`` list.
5. For determining a ``raises`` list, the ``raise`` and ``try`` statements
of ``p`` are taken into consideration.
@ -3259,7 +3283,7 @@ Symbol lookup in generics
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
context, an "open" symbol can be. Per default overloaded symbols are open
context, an "open" symbol can. Per default overloaded symbols are open
and every other symbol is closed.
Open symbols are looked up in two different contexts: Both the context
@ -4106,8 +4130,8 @@ implemented with term rewriting:
proc p(x, y: int; cond: bool): int =
result = if cond: x + y else: x - y
template optP{p(x, y, true)}(x, y: expr): expr = x + y
template optP{p(x, y, false)}(x, y: expr): expr = x - y
template optP1{p(x, y, true)}(x, y: expr): expr = x + y
template optP2{p(x, y, false)}(x, y: expr): expr = x - y
Example: hoisting