summary refs log tree commit diff stats
path: root/doc
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-12-09 03:02:52 +0100
committerAraq <rumpf_a@web.de>2012-12-09 03:02:52 +0100
commit92f8f2e7766d6c5475f643a17df88aa680a4e5dc (patch)
tree197e8e6af6f3be022389c38a864ac2607b7f8f07 /doc
parent40b611cc2f7d5cf4972dfb92fc63f0bb350adf89 (diff)
downloadNim-92f8f2e7766d6c5475f643a17df88aa680a4e5dc.tar.gz
documented AST overloading and some TR optimizations
Diffstat (limited to 'doc')
-rwxr-xr-xdoc/manual.txt85
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