diff options
author | Araq <rumpf_a@web.de> | 2017-11-28 01:25:59 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2017-11-28 01:25:59 +0100 |
commit | 58c3e5d2f518d10f500dec9627fbe6c4c91dfc64 (patch) | |
tree | 27f820746c91ead879e41aaa2c0c45eef6e63b07 /doc | |
parent | 5d2e86ea1a4c6a0b1e74708f038da5590eeffc48 (diff) | |
download | Nim-58c3e5d2f518d10f500dec9627fbe6c4c91dfc64.tar.gz |
test the snippets in tut2.rst
Diffstat (limited to 'doc')
-rw-r--r-- | doc/tut2.rst | 52 |
1 files changed, 37 insertions, 15 deletions
diff --git a/doc/tut2.rst b/doc/tut2.rst index 0636c4ed6..91cb52834 100644 --- a/doc/tut2.rst +++ b/doc/tut2.rst @@ -55,6 +55,7 @@ Objects have access to their type at runtime. There is an ``of`` operator that can be used to check the object's type: .. code-block:: nim + :test: "nim c $1" type Person = ref object of RootObj name*: string # the * means that `name` is accessible from other modules @@ -103,6 +104,7 @@ would require arbitrary symbol lookahead which slows down compilation.) Example: .. code-block:: nim + :test: "nim c $1" type Node = ref object # a reference to an object with the following field: le, ri: Node # left and right subtrees @@ -144,6 +146,7 @@ variant types are needed. An example: .. code-block:: nim + :test: "nim c $1" # This is an example how an abstract syntax tree could be modelled in Nim type @@ -201,9 +204,11 @@ This method call syntax is not restricted to objects, it can be used for any type: .. code-block:: nim + :test: "nim c $1" + import strutils echo "abc".len # is the same as echo len("abc") - echo "abc".toUpper() + echo "abc".toUpperAscii() echo({'a', 'b', 'c'}.card) stdout.writeLine("Hallo") # the same as writeLine(stdout, "Hallo") @@ -213,6 +218,7 @@ postfix notation.) So "pure object oriented" code is easy to write: .. code-block:: nim + :test: "nim c $1" import strutils, sequtils stdout.writeLine("Give a list of numbers (separated by spaces): ") @@ -228,6 +234,7 @@ the same. But setting a value is different; for this a special setter syntax is needed: .. code-block:: nim + :test: "nim c $1" type Socket* = ref object of RootObj @@ -252,6 +259,7 @@ The ``[]`` array access operator can be overloaded to provide `array properties`:idx:\ : .. code-block:: nim + :test: "nim c $1" type Vector* = object x, y, z: float @@ -283,23 +291,24 @@ Procedures always use static dispatch. For dynamic dispatch replace the ``proc`` keyword by ``method``: .. code-block:: nim + :test: "nim c $1" type - PExpr = ref object of RootObj ## abstract base class for an expression - PLiteral = ref object of PExpr + Expression = ref object of RootObj ## abstract base class for an expression + Literal = ref object of Expression x: int - PPlusExpr = ref object of PExpr - a, b: PExpr + PlusExpr = ref object of Expression + a, b: Expression # watch out: 'eval' relies on dynamic binding - method eval(e: PExpr): int = + method eval(e: Expression): int = # override this base method quit "to override!" - method eval(e: PLiteral): int = e.x - method eval(e: PPlusExpr): int = eval(e.a) + eval(e.b) + method eval(e: Literal): int = e.x + method eval(e: PlusExpr): int = eval(e.a) + eval(e.b) - proc newLit(x: int): PLiteral = PLiteral(x: x) - proc newPlus(a, b: PExpr): PPlusExpr = PPlusExpr(a: a, b: b) + proc newLit(x: int): Literal = Literal(x: x) + proc newPlus(a, b: Expression): PlusExpr = PlusExpr(a: a, b: b) echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4))) @@ -311,6 +320,7 @@ In a multi-method all parameters that have an object type are used for the dispatching: .. code-block:: nim + :test: "nim c $1" type Thing = ref object of RootObj @@ -365,6 +375,7 @@ Raise statement Raising an exception is done with the ``raise`` statement: .. code-block:: nim + :test: "nim c $1" var e: ref OSError new(e) @@ -385,6 +396,9 @@ Try statement The ``try`` statement handles exceptions: .. code-block:: nim + :test: "nim c $1" + from strutils import parseInt + # read the first two lines of a text file that should contain numbers # and tries to add them var @@ -479,6 +493,7 @@ with `type parameters`:idx:. They are most useful for efficient type safe containers: .. code-block:: nim + :test: "nim c $1" type BinaryTree*[T] = ref object # BinaryTree is a generic type with # generic param ``T`` @@ -573,6 +588,7 @@ Templates are especially useful for lazy evaluation purposes. Consider a simple proc for logging: .. code-block:: nim + :test: "nim c $1" const debug = true @@ -590,6 +606,7 @@ evaluation for procedures is *eager*). Turning the ``log`` proc into a template solves this problem: .. code-block:: nim + :test: "nim c $1" const debug = true @@ -611,6 +628,7 @@ If the template has no explicit return type, To pass a block of statements to a template, use 'untyped' for the last parameter: .. code-block:: nim + :test: "nim c $1" template withFile(f: untyped, filename: string, mode: FileMode, body: untyped): typed = @@ -665,6 +683,7 @@ The following example implements a powerful ``debug`` command that accepts a variable number of arguments: .. code-block:: nim + :test: "nim c $1" # to work with Nim syntax trees, we need an API that is defined in the # ``macros`` module: import macros @@ -744,6 +763,7 @@ dynamic code into something that compiles statically. For the exercise we will use the following snippet of code as the starting point: .. code-block:: nim + :test: "nim c $1" import strutils, tables @@ -863,9 +883,9 @@ variables with ``cfg``. In essence, what the compiler is doing is replacing the line calling the macro with the following snippet of code: .. code-block:: nim - const cfgversion= "1.1" - const cfglicenseOwner= "Hyori Lee" - const cfglicenseKey= "M1Tl3PjBWO2CC48m" + const cfgversion = "1.1" + const cfglicenseOwner = "Hyori Lee" + const cfglicenseKey = "M1Tl3PjBWO2CC48m" You can verify this yourself adding the line ``echo source`` somewhere at the end of the macro and compiling the program. Another difference is that instead @@ -891,12 +911,13 @@ an expression macro. Since we know that we want to generate a bunch of see what the compiler *expects* from us: .. code-block:: nim + :test: "nim c $1" import macros dumpTree: const cfgversion: string = "1.1" - const cfglicenseOwner= "Hyori Lee" - const cfglicenseKey= "M1Tl3PjBWO2CC48m" + const cfglicenseOwner = "Hyori Lee" + const cfglicenseKey = "M1Tl3PjBWO2CC48m" During compilation of the source code we should see the following lines in the output (again, since this is a macro, compilation is enough, you don't have to @@ -996,6 +1017,7 @@ Lifting Procs +++++++++++++ .. code-block:: nim + :test: "nim c $1" import math template liftScalarProc(fname) = |