diff options
author | rumpf_a@web.de <> | 2009-10-21 10:20:15 +0200 |
---|---|---|
committer | rumpf_a@web.de <> | 2009-10-21 10:20:15 +0200 |
commit | 053309e60aee1eda594a4817ac8ac2fb8c18fb04 (patch) | |
tree | 0f1ce8b0de0b493045eb97eeca6ebf06542de601 /doc/manual.txt | |
parent | 581572b28c65bc9fe47974cfd625210a69be0f3f (diff) | |
download | Nim-053309e60aee1eda594a4817ac8ac2fb8c18fb04.tar.gz |
version 0.8.2
Diffstat (limited to 'doc/manual.txt')
-rwxr-xr-x | doc/manual.txt | 97 |
1 files changed, 91 insertions, 6 deletions
diff --git a/doc/manual.txt b/doc/manual.txt index 3c24e4b1a..9cf1f3bc2 100755 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -342,7 +342,7 @@ Syntax ====== This section lists Nimrod's standard syntax in ENBF. How the parser receives -indentation tokens is already described in the Lexical Analysis section. +indentation tokens is already described in the `Lexical Analysis`_ section. Nimrod allows user-definable operators. Binary operators have 8 different levels of precedence. For user-defined @@ -363,8 +363,7 @@ Precedence level Operators First characte ================ ============================================== ================== =============== -The grammar's start symbol is ``module``. The grammar is LL(1) and therefore -not ambiguous. +The grammar's start symbol is ``module``. .. include:: grammar.txt :literal: @@ -875,8 +874,7 @@ Procedural type ~~~~~~~~~~~~~~~ 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 -types to achieve `functional`:idx: programming techniques. Dynamic dispatch -for OOP constructs can also be implemented with procedural types. +types to achieve `functional`:idx: programming techniques. Example: @@ -946,6 +944,16 @@ each other: Most calling conventions exist only for the Windows 32-bit platform. +Assigning/passing a procedure to a procedural variable is only allowed if one +of the following conditions hold: +1) The procedure that is accessed resists in the current module. +2) The procedure is marked with the ``procvar`` pragma (see `procvar pragma`_). +3) The procedure has a calling convention that differs from ``nimcall``. +4) The procedure is anonymous. + +These rules should prevent the case that extending a non-``procvar`` +procedure with default parameters breaks client code. + Distinct type ~~~~~~~~~~~~~ @@ -1054,7 +1062,7 @@ describe the type checking done by the compiler. Type equality ~~~~~~~~~~~~~ Nimrod uses structural type equivalence for most types. Only for objects, -enumerations and abstract types name equivalence is used. The following +enumerations and distinct types name equivalence is used. The following algorithm determines type equality: .. code-block:: nimrod @@ -1800,6 +1808,77 @@ Even more elegant is to use `tuple unpacking`:idx: to access the tuple's fields: assert y == 3 +Multi-methods +~~~~~~~~~~~~~ + +Procedures always use static dispatch. Dynamic dispatch is achieved by +`multi-methods`:idx:. + +.. code-block:: nimrod + type + TExpr = object ## abstract base class for an expression + TLiteral = object of TExpr + x: int + TPlusExpr = object of TExpr + a, b: ref TExpr + + method eval(e: ref TExpr): int = + # override this base method + quit "to override!" + + method eval(e: ref TLiteral): int = return e.x + + method eval(e: ref TPlusExpr): int = + # watch out: relies on dynamic binding + return eval(e.a) + eval(e.b) + + proc newLit(x: int): ref TLiteral = + new(result) + result.x = x + + proc newPlus(a, b: ref TExpr): ref TPlusExpr = + new(result) + result.a = a + result.b = b + + echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4))) + +In the example the constructors ``newLit`` and ``newPlus`` are procs +because they should use static binding, but ``eval`` is a method because it +requires dynamic binding. + +In a multi-method all parameters that have an object type are used for the +dispatching: + +.. code-block:: nimrod + type + TThing = object + TUnit = object of TThing + x: int + + method collide(a, b: TThing) {.inline.} = + quit "to override!" + + method collide(a: TThing, b: TUnit) {.inline.} = + echo "1" + + method collide(a: TUnit, b: TThing) {.inline.} = + echo "2" + + var + a, b: TUnit + collide(a, b) # output: 2 + + +Invokation of a multi-method cannot be ambiguous: Collide 2 is prefered over +collide 1 because the resolution works from left to right. +Thus ``TUnit, TThing`` is prefered over ``TThing, TUnit``. + +**Perfomance note**: Nimrod does not produce a virtual method table, but +generates dispatch trees. This avoids the expensive indirect branch for method +calls and enables inlining. However, other optimizations like compile time +evaluation or dead code elimination do not work with methods. + Iterators and the for statement ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2275,6 +2354,12 @@ error to mark a proc/iterator to have no side effect if the compiler cannot verify this. +procvar pragma +-------------- +The `procvar`:idx: pragma is used to mark a proc that it can be passed to a +procedural variable. + + compileTime pragma ------------------ The `compileTime`:idx: pragma is used to mark a proc to be used at compile |