diff options
author | Araq <rumpf_a@web.de> | 2012-12-09 03:02:52 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2012-12-09 03:02:52 +0100 |
commit | 92f8f2e7766d6c5475f643a17df88aa680a4e5dc (patch) | |
tree | 197e8e6af6f3be022389c38a864ac2607b7f8f07 /doc | |
parent | 40b611cc2f7d5cf4972dfb92fc63f0bb350adf89 (diff) | |
download | Nim-92f8f2e7766d6c5475f643a17df88aa680a4e5dc.tar.gz |
documented AST overloading and some TR optimizations
Diffstat (limited to 'doc')
-rwxr-xr-x | doc/manual.txt | 85 |
1 files changed, 83 insertions, 2 deletions
diff --git a/doc/manual.txt b/doc/manual.txt index 4d0c3b01b..da66833ab 100755 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -3973,18 +3973,95 @@ parameter is of the type ``varargs`` it is treated specially and it can match +Example: Partial evaluation +--------------------------- + +The following example shows how some simple partial evaluation can be +implemented with term rewriting: + +.. code-block:: nimrod + 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 + + +Example: hoisting +----------------- + +The following example how some form of hoisting can be implemented: + +.. code-block:: nimrod + import pegs + + template optPeg{peg(pattern)}(pattern: string{lit}): TPeg = + var gl {.global, gensym.} = peg(pattern) + gl + + for i in 0 .. 3: + echo match("(a b c)", peg"'(' @ ')'") + echo match("W_HI_Le", peg"\y 'while'") + +The ``optPeg`` template optimizes the case of a peg constructor with a string +literal, so that the pattern will only be parsed once at program startup and +stored in global ``gl`` which is then re-used. This optimization is called +hoisting because it is comparable to classical loop hoisting. + + AST based overloading ===================== Parameter constraints can also be used for ordinary routine parameters; these constraints affect ordinary overloading resolution then: +.. code-block:: nimrod + proc optLit(a: string{lit|`const`}) = + echo "string literal" + proc optLit(a: string) = + echo "no string literal" + + const + constant = "abc" + + var + variable = "xyz" + optLit("literal") + optLit(constant) + optLit(variable) However, the constraints ``alias`` and ``noalias`` are not available in ordinary routines. +Move optimization +----------------- + +The ``call`` constraint is particular useful to implement a `move`:idx: +optimization for types that have copying semantics: + +.. code-block:: nimrod + proc `[]=`*(t: var TTable, key: string, val: string) = + ## puts a (key, value)-pair into `t`. The semantics of string require + ## a copy here: + let idx = findInsertionPosition(key) + t[idx] = key + t[idx] = val + + proc `[]=`*(t: var TTable, key: string{call}, val: string{call}) = + ## puts a (key, value)-pair into `t`. Optimized version that knows that + ## the strings are unique and thus don't need to be copied: + let idx = findInsertionPosition(key) + shallowCopy t[idx], key + shallowCopy t[idx], val + + var t: TTable + # overloading resolution ensures that the optimized []= is called here: + t["abc"] = "xyz" + + + Modules ======= Nimrod supports splitting a program into pieces by a `module`:idx: concept. @@ -4692,10 +4769,14 @@ Threadvar pragma ---------------- A global variable can be marked with the `threadvar`:idx: pragma; it is -a `thead-local`:idx: variable then: +a `thread-local`:idx: variable then: .. code-block:: nimrod - var checkpoints* {.threadvar.}: seq[string] = @[] + var checkpoints* {.threadvar.}: seq[string] + +Due to implementation restrictions thread local variables cannot be +initialized within the ``var`` section. (Every thread local variable needs to +be replicated at thread creation.) Actor model |