summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xcompiler/ccgstmts.nim4
-rwxr-xr-xcompiler/cgen.nim2
-rwxr-xr-xcompiler/msgs.nim2
-rwxr-xr-xcompiler/sem.nim5
-rwxr-xr-xcompiler/semcall.nim40
-rwxr-xr-xcompiler/semexprs.nim1
-rwxr-xr-xcompiler/seminst.nim6
-rwxr-xr-xcompiler/semstmts.nim15
-rwxr-xr-xcompiler/sigmatch.nim34
-rwxr-xr-xconfig/nimrod.cfg2
-rwxr-xr-xdoc/lib.txt4
-rwxr-xr-xdoc/manual.txt299
-rwxr-xr-xdoc/tut1.txt7
-rw-r--r--readme.md6
-rwxr-xr-xreadme.txt6
-rw-r--r--tests/run/titer9.nim6
-rwxr-xr-xtodo.txt5
17 files changed, 275 insertions, 169 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 089f7fb83..9d5659f5e 100755
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -124,6 +124,7 @@ proc genBreakState(p: BProc, n: PNode) =
     lineF(p, cpsStmts, "if ((((NI*) $1.ClEnv)[0]) < 0) break;$n", [rdLoc(a)])
   #  lineF(p, cpsStmts, "if (($1) < 0) break;$n", [rdLoc(a)])
 
+proc genVarPrototypeAux(m: BModule, sym: PSym)
 proc genSingleVar(p: BProc, a: PNode) =
   var v = a.sons[0].sym
   if sfCompileTime in v.flags: return
@@ -142,6 +143,9 @@ proc genSingleVar(p: BProc, a: PNode) =
     genObjectInit(p.module.preInitProc, cpsInit, v.typ, v.loc, true)
     # Alternative construction using default constructor (which may zeromem):
     # if sfImportc notin v.flags: constructLoc(p.module.preInitProc, v.loc)
+    if sfExportc in v.flags and generatedHeader != nil:
+      genVarPrototypeAux(generatedHeader, v)
+
   else:
     assignLocalVar(p, v)
     initLocalVar(p, v, immediateAsgn)
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 5bdbefde1..d024f3479 100755
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -799,8 +799,6 @@ proc genVarPrototypeAux(m: BModule, sym: PSym) =
 
 proc genVarPrototype(m: BModule, sym: PSym) =
   genVarPrototypeAux(m, sym)
-  if sfExportc in sym.flags and generatedHeader != nil:
-    genVarPrototypeAux(generatedHeader, sym)
 
 proc addIntTypes(result: var PRope) {.inline.} =
   appf(result, "#define NIM_INTBITS $1", [
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index 0f795c07d..240115817 100755
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -132,7 +132,7 @@ const
     errNumberOutOfRange: "number $1 out of valid range", 
     errNnotAllowedInCharacter: "\\n not allowed in character literal", 
     errClosingBracketExpected: "closing ']' expected, but end of file reached", 
-    errMissingFinalQuote: "missing final \'", 
+    errMissingFinalQuote: "missing final \' for character literal", 
     errIdentifierExpected: "identifier expected, but found \'$1\'", 
     errNewlineExpected: "newline expected, but found \'$1\'",
     errInvalidModuleName: "invalid module name: '$1'",
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 911eafb08..c70cbf61e 100755
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -39,14 +39,15 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType
 proc semStmt(c: PContext, n: PNode): PNode
 proc semParamList(c: PContext, n, genericParams: PNode, s: PSym)
 proc addParams(c: PContext, n: PNode, kind: TSymKind)
-proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind)
-proc addResultNode(c: PContext, n: PNode)
+proc maybeAddResult(c: PContext, s: PSym, n: PNode)
 proc instGenericContainer(c: PContext, n: PNode, header: PType): PType
 proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
 proc fixImmediateParams(n: PNode): PNode
 proc activate(c: PContext, n: PNode)
 proc semQuoteAst(c: PContext, n: PNode): PNode
 
+proc IndexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode
+
 proc typeMismatch(n: PNode, formal, actual: PType) = 
   if formal.kind != tyError and actual.kind != tyError: 
     LocalError(n.Info, errGenerated, msgKindToString(errTypeMismatch) &
diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index 962e4d3cc..0a5f19822 100755
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -84,15 +84,34 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
         getProcHeader(best.calleeSym), getProcHeader(alt.calleeSym),
         args])
 
-proc instantiateGenericConverters(c: PContext, n: PNode, x: TCandidate) {.
-                                  noinline.}=
-  for i in 1 .. <n.len:
-    var a = n.sons[i]
-    if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym and
-        isGenericRoutine(a.sons[0].sym):
-      let finalCallee = generateInstance(c, a.sons[0].sym, x.bindings, n.info)
-      a.sons[0].sym = finalCallee
-      a.sons[0].typ = finalCallee.typ
+
+proc instGenericConvertersArg*(c: PContext, a: PNode, x: TCandidate) =
+  if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym and
+      isGenericRoutine(a.sons[0].sym):
+    let finalCallee = generateInstance(c, a.sons[0].sym, x.bindings, a.info)
+    a.sons[0].sym = finalCallee
+    a.sons[0].typ = finalCallee.typ
+    #a.typ = finalCallee.typ.sons[0]
+
+proc instGenericConvertersSons*(c: PContext, n: PNode, x: TCandidate) =
+  assert n.kind in nkCallKinds
+  if x.genericConverter:
+    for i in 1 .. <n.len:
+      instGenericConvertersArg(c, n.sons[i], x)
+
+proc IndexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode = 
+  var m: TCandidate
+  initCandidate(m, f)
+  result = paramTypesMatch(c, m, f, a, arg, nil)
+  if m.genericConverter and result != nil:
+    instGenericConvertersArg(c, result, m)
+
+proc ConvertTo*(c: PContext, f: PType, n: PNode): PNode = 
+  var m: TCandidate
+  initCandidate(m, f)
+  result = paramTypesMatch(c, m, f, n.typ, n, nil)
+  if m.genericConverter and result != nil:
+    instGenericConvertersArg(c, result, m)
 
 proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
   assert x.state == csMatch
@@ -111,8 +130,7 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
       if ContainsGenericType(result.typ): result.typ = errorType(c)
       return
   result = x.call
-  if x.genericConverter:
-    instantiateGenericConverters(c, result, x)
+  instGenericConvertersSons(c, result, x)
   result.sons[0] = newSymNode(finalCallee, result.sons[0].info)
   result.typ = finalCallee.typ.sons[0]
 
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 7b37987ee..d0fbcab6f 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -664,6 +664,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
       result = nil
     else:
       result = m.call
+      instGenericConvertersSons(c, result, m)
     # we assume that a procedure that calls something indirectly 
     # has side-effects:
     if tfNoSideEffect notin t.flags: incl(c.p.owner.flags, sfSideEffect)
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index 8e164531a..0a1a17f72 100755
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -93,9 +93,7 @@ proc instantiateBody(c: PContext, n: PNode, result: PSym) =
     # add it here, so that recursive generic procs are possible:
     addDecl(c, result)
     pushProcCon(c, result)
-    if result.kind in {skProc, skMethod, skConverter, skMacro}: 
-      addResult(c, result.typ.sons[0], n.info, result.kind)
-      addResultNode(c, n)
+    maybeAddResult(c, result, n)
     var b = n.sons[bodyPos]
     var symMap: TIdTable
     InitIdTable symMap
@@ -168,6 +166,8 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
     result.typ = newTypeS(tyProc, c)
     rawAddSon(result.typ, nil)
   result.typ.callConv = fn.typ.callConv
+  if result.kind == skIterator: result.typ.flags.incl(tfIterator)
+
   var oldPrc = GenericCacheGet(c, entry)
   if oldPrc == nil:
     c.generics.generics.add(entry)
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 68d485f48..abd064a62 100755
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -713,6 +713,12 @@ proc doDestructorStuff(c: PContext, s: PSym, n: PNode) =
             useSym(t.sons[i].destructor),
             n.sons[paramsPos][1][0]]))
 
+proc maybeAddResult(c: PContext, s: PSym, n: PNode) =
+  if s.typ.sons[0] != nil and
+      (s.kind != skIterator or s.typ.callConv == ccClosure):
+    addResult(c, s.typ.sons[0], n.info, s.kind)
+    addResultNode(c, n)
+
 proc semProcAux(c: PContext, n: PNode, kind: TSymKind, 
                 validPragmas: TSpecialWords): PNode = 
   result = semProcAnnotation(c, n)
@@ -794,17 +800,13 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
     if n.sons[genericParamsPos].kind == nkEmpty: 
       ParamsTypeCheck(c, s.typ)
       pushProcCon(c, s)
-      if s.typ.sons[0] != nil and
-          (kind != skIterator or s.typ.callConv == ccClosure):
-        addResult(c, s.typ.sons[0], n.info, kind)
-        addResultNode(c, n)
+      maybeAddResult(c, s, n)
       if sfImportc notin s.flags:
         # no semantic checking for importc:
         let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
         # unfortunately we cannot skip this step when in 'system.compiles'
         # context as it may even be evaluated in 'system.compiles':
         n.sons[bodyPos] = transformBody(c.module, semBody, s)
-      #if s.typ.sons[0] != nil and kind != skIterator: addResultNode(c, n)
       popProcCon(c)
     else: 
       if s.typ.sons[0] != nil and kind != skIterator:
@@ -1076,7 +1078,8 @@ proc insertDestructors(c: PContext, varSection: PNode):
       varTyp = varId.sym.typ
       info = varId.info
 
-    if varTyp != nil and instantiateDestructor(c, varTyp):
+    if varTyp != nil and instantiateDestructor(c, varTyp) and 
+        sfGlobal notin varId.sym.flags:
       var tryStmt = newNodeI(nkTryStmt, info)
 
       if j < totalVars - 1:
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 1f2511694..2fecda427 100755
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -594,7 +594,7 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
       addSon(result, copyTree(arg))
       inc(m.convMatches)
       m.genericConverter = srca == isGeneric or destIsGeneric
-      return
+      return result
 
 proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType, 
                     arg: PNode): PNode = 
@@ -705,8 +705,8 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
         else:
           result = userConvMatch(c, m, base(f), a, arg)
 
-proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType, 
-                     arg, argOrig: PNode): PNode =
+proc ParamTypesMatch*(c: PContext, m: var TCandidate, f, a: PType, 
+                      arg, argOrig: PNode): PNode =
   if arg == nil or arg.kind notin nkSymChoices:
     result = ParamTypesMatchAux(c, m, f, a, arg, argOrig)
   else: 
@@ -752,27 +752,12 @@ proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType,
       result = ParamTypesMatchAux(c, m, f, arg.sons[best].typ, arg.sons[best],
                                   argOrig)
 
-proc IndexTypesMatch*(c: PContext, f, a: PType, arg: PNode): PNode = 
-  var m: TCandidate
-  initCandidate(m, f)
-  result = paramTypesMatch(c, m, f, a, arg, nil)
-
-proc ConvertTo*(c: PContext, f: PType, n: PNode): PNode = 
-  var m: TCandidate
-  initCandidate(m, f)
-  result = paramTypesMatch(c, m, f, n.typ, n, nil)
-
-proc argtypeMatches*(c: PContext, f, a: PType): bool = 
-  var m: TCandidate
-  initCandidate(m, f)
-  result = paramTypesMatch(c, m, f, a, ast.emptyNode, nil) != nil  
-
 proc setSon(father: PNode, at: int, son: PNode) = 
   if sonsLen(father) <= at: setlen(father.sons, at + 1)
   father.sons[at] = son
 
-proc matchesAux*(c: PContext, n, nOrig: PNode,
-                 m: var TCandidate, marker: var TIntSet) = 
+proc matchesAux(c: PContext, n, nOrig: PNode,
+                m: var TCandidate, marker: var TIntSet) = 
   template checkConstraint(n: expr) {.immediate, dirty.} =
     if not formal.constraint.isNil:
       if matchNodeKinds(formal.constraint, n):
@@ -904,4 +889,13 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
         setSon(m.call, formal.position + 1, copyTree(formal.ast))
     inc(f)
 
+proc argtypeMatches*(c: PContext, f, a: PType): bool = 
+  var m: TCandidate
+  initCandidate(m, f)
+  let res = paramTypesMatch(c, m, f, a, ast.emptyNode, nil)
+  #instantiateGenericConverters(c, res, m)
+  # XXX this is used by patterns.nim too; I think it's better to not
+  # instantiate generic converters for that
+  result = res != nil
+
 include suggest
diff --git a/config/nimrod.cfg b/config/nimrod.cfg
index ea3d11a0e..9db13e836 100755
--- a/config/nimrod.cfg
+++ b/config/nimrod.cfg
@@ -33,7 +33,7 @@ path="$lib/ecmas"
 path="$lib/pure/unidecode"
 
 @if nimbabel:
-  babelpath="$home/babeltest/"
+  babelpath="$home/.babel/libs/"
 @end
 
 @if release or quick:
diff --git a/doc/lib.txt b/doc/lib.txt
index f4d3dde30..a429a8289 100755
--- a/doc/lib.txt
+++ b/doc/lib.txt
@@ -38,11 +38,11 @@ Core
 
 * `threads <threads.html>`_
   Nimrod thread support. **Note**: This is part of the system module. Do not
-  import it explicitely.
+  import it explicitly.
 
 * `channels <channels.html>`_
   Nimrod message passing support for threads. **Note**: This is part of the 
-  system module. Do not import it explicitely.
+  system module. Do not import it explicitly.
 
 * `locks <locks.html>`_
   Locks and condition variables for Nimrod.
diff --git a/doc/manual.txt b/doc/manual.txt
index d8d53085c..2a79c0f99 100755
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -479,11 +479,8 @@ The grammar's start symbol is ``module``.
 
 
 
-Semantics
-=========
-
 Types
------
+=====
 
 All expressions have a `type`:idx: which is known at compile time. Nimrod
 is statically typed. One can declare new types, which is in essence defining
@@ -502,7 +499,7 @@ These are the major type classes:
 
 
 Ordinal types
-~~~~~~~~~~~~~
+-------------
 `Ordinal types`:idx: have the following characteristics:
 
 - Ordinal types are countable and ordered. This property allows
@@ -519,7 +516,7 @@ the types ``uint`` and ``uint64`` are no ordinal types.
 
 
 Pre-defined integer types
-~~~~~~~~~~~~~~~~~~~~~~~~~
+-------------------------
 These integer types are pre-defined:
 
 ``int``
@@ -602,7 +599,7 @@ For further details, see `Convertible relation`_.
 
 
 Subrange types
-~~~~~~~~~~~~~~
+--------------
 A `subrange`:idx: type is a range of values from an ordinal type (the base
 type). To define a subrange type, one must specify it's limiting values: the
 lowest and highest value of the type:
@@ -642,7 +639,7 @@ This means that the following code is accepted:
   
 
 Pre-defined floating point types
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+--------------------------------
 
 The following floating point types are pre-defined:
 
@@ -703,7 +700,7 @@ the ``+``, ``-``, ``*``, ``/`` operators for floating point types.
 
 
 Boolean type
-~~~~~~~~~~~~
+------------
 The `boolean`:idx: type is named `bool`:idx: in Nimrod and can be one of the two
 pre-defined values ``true`` and ``false``. Conditions in while,
 if, elif, when statements need to be of type bool.
@@ -727,7 +724,7 @@ The size of the bool type is one byte.
 
 
 Character type
-~~~~~~~~~~~~~~
+--------------
 The `character type`:idx: is named ``char`` in Nimrod. Its size is one byte.
 Thus it cannot represent an UTF-8 character, but a part of it.
 The reason for this is efficiency: for the overwhelming majority of use-cases,
@@ -741,7 +738,7 @@ character. ``TRune`` is declared in the ``unicode`` module.
 
 
 Enumeration types
-~~~~~~~~~~~~~~~~~
+-----------------
 `Enumeration`:idx: types define a new type whose values consist of the ones
 specified. The values are ordered. Example:
 
@@ -811,7 +808,7 @@ via ``TMyEnum.value``:
 
 
 String type
-~~~~~~~~~~~
+-----------
 All string literals are of the type `string`:idx:. A string in Nimrod is very
 similar to a sequence of characters. However, strings in Nimrod are both
 zero-terminated and have a length field. One can retrieve the length with the
@@ -838,7 +835,7 @@ module can be used for iteration over all Unicode characters.
 
 
 CString type
-~~~~~~~~~~~~
+------------
 The `cstring`:idx: type represents a pointer to a zero-terminated char array
 compatible to the type ``char*`` in Ansi C. Its primary purpose lies in easy
 interfacing with C. The index operation ``s[i]`` means the i-th *char* of 
@@ -864,13 +861,13 @@ not work.
 
 
 Structured types
-~~~~~~~~~~~~~~~~
+----------------
 A variable of a `structured type`:idx: can hold multiple values at the same
 time. Structured types can be nested to unlimited levels. Arrays, sequences,
 tuples, objects and sets belong to the structured types.
 
 Array and sequence types
-~~~~~~~~~~~~~~~~~~~~~~~~
+------------------------
 `Arrays`:idx: are a homogeneous type, meaning that each element in the array
 has the same type. Arrays always have a fixed length which is specified at
 compile time (except for open arrays). They can be indexed by any ordinal type.
@@ -918,7 +915,7 @@ The current implementation does not support nested open arrays.
 
 
 Varargs
-~~~~~~~
+-------
 
 A `varargs`:idx: parameter is an openarray parameter that additionally
 allows to pass a variable number of arguments to a procedure. The compiler 
@@ -954,7 +951,7 @@ parameter ``a``. (Note that ``$`` applied to strings is a nop.)
 
 
 Tuples and object types
-~~~~~~~~~~~~~~~~~~~~~~~
+-----------------------
 A variable of a `tuple`:idx: or `object`:idx: type is a heterogeneous storage
 container.
 A tuple or object defines various named *fields* of a type. A tuple also
@@ -1022,7 +1019,7 @@ introduce new object roots apart from ``system.TObject``.
 
 
 Object variants
-~~~~~~~~~~~~~~~
+---------------
 Often an object hierarchy is overkill in certain situations where simple
 `variant`:idx: types are needed.
 
@@ -1069,7 +1066,7 @@ the ``case`` statement: The branches in a ``case`` section may be indented too.
 
 
 Set type
-~~~~~~~~
+--------
 The `set type`:idx: models the mathematical notion of a set. The set's
 basetype can only be an ordinal type. The reason is that sets are implemented
 as high performance bit vectors.
@@ -1104,7 +1101,7 @@ operation             meaning
 
 
 Reference and pointer types
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+---------------------------
 References (similar to `pointers`:idx: in other programming languages) are a
 way to introduce many-to-one relationships. This means different references can
 point to and modify the same location in memory (also called `aliasing`:idx:).
@@ -1193,14 +1190,14 @@ mysterious crashes.
 
 **Note**: The example only works because the memory is initialized to zero
 (``alloc0`` instead of ``alloc`` does this): ``d.s`` is thus initialized to
-``nil`` which the string assignment can handle. You need to know low level
+``nil`` which the string assignment can handle. One needs to know low level
 details like this when mixing garbage collected data with unmanaged memory.
 
 .. XXX finalizers for traced objects
 
 
 Not nil annotation
-~~~~~~~~~~~~~~~~~~
+------------------
 
 All types for that ``nil`` is a valid value can be annotated to 
 exclude ``nil`` as a valid value with the `not nil`:idx: annotation:
@@ -1225,7 +1222,7 @@ for now the compiler can only catch the most trivial type violations.
 
 
 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.
@@ -1335,7 +1332,7 @@ accesses its environment. If it does so, it has the calling convention
 
 
 Distinct type
-~~~~~~~~~~~~~
+-------------
 
 A distinct type is new type derived from a `base type`:idx: that is
 incompatible with its base type. In particular, it is an essential property
@@ -1431,9 +1428,9 @@ currency. This can be solved with templates_.
 
 
 Void type
-~~~~~~~~~
+---------
 
-The `void`:idx: type denotes the absence of any type. Parameters of 
+The `void`:idx: type denotes the absense of any type. Parameters of 
 type ``void`` are treated as non-existent, ``void`` as a return type means that
 the procedure does not return a value:
 
@@ -1471,14 +1468,14 @@ cannot have the type ``void``.
 
 
 Type relations
---------------
+==============
 
 The following section defines several relations on types that are needed to
 describe the type checking done by the compiler.
 
 
 Type equality
-~~~~~~~~~~~~~
+-------------
 Nimrod uses structural type equivalence for most types. Only for objects,
 enumerations and distinct types name equivalence is used. The following
 algorithm (in pseudo-code) determines type equality:
@@ -1523,7 +1520,7 @@ auxiliary set ``s`` to detect this case.
 
 
 Type equality modulo type distinction
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-------------------------------------
 
 The following algorithm (in pseudo-code) determines whether two types
 are equal with no respect to ``distinct`` types. For brevity the cycle check
@@ -1565,7 +1562,7 @@ with an auxiliary set ``s`` is omitted:
       
 
 Subtype relation
-~~~~~~~~~~~~~~~~
+----------------
 If object ``a`` inherits from ``b``, ``a`` is a subtype of ``b``. This subtype
 relation is extended to the types ``var``, ``ref``, ``ptr``:
 
@@ -1584,7 +1581,7 @@ relation is extended to the types ``var``, ``ref``, ``ptr``:
 
 
 Convertible relation
-~~~~~~~~~~~~~~~~~~~~
+--------------------
 A type ``a`` is **implicitly** convertible to type ``b`` iff the following
 algorithm returns true:
 
@@ -1651,20 +1648,21 @@ The type conversion ``T(a)`` is an L-value if ``a`` is an L-value and
 
 
 Assignment compatibility
-~~~~~~~~~~~~~~~~~~~~~~~~
+------------------------
 
 An expression ``b`` can be assigned to an expression ``a`` iff ``a`` is an
 `l-value` and ``isImplicitlyConvertible(b.typ, a.typ)`` holds.
 
 
 Overloading resolution
-~~~~~~~~~~~~~~~~~~~~~~
+----------------------
 
 To be written.
 
 
 Statements and expressions
---------------------------
+==========================
+
 Nimrod uses the common statement/expression paradigm: `Statements`:idx: do not
 produce a value in contrast to expressions. Call expressions are statements.
 If the called procedure returns a value, it is not a valid statement
@@ -1698,7 +1696,7 @@ statements always have to be intended::
 
 
 Discard statement
-~~~~~~~~~~~~~~~~~
+-----------------
 
 Syntax::
 
@@ -1729,7 +1727,7 @@ been declared with the `discardable`:idx: pragma:
 
 
 Var statement
-~~~~~~~~~~~~~
+-------------
 
 Syntax::
 
@@ -1790,7 +1788,7 @@ If a proc is annotated with the ``noinit`` pragma this refers to its implicit
 
 
 let statement
-~~~~~~~~~~~~~
+-------------
 
 A `Let`:idx: statement declares new local and global `single assignment`:idx:
 variables and binds a value to them. The syntax is the of the ``var`` 
@@ -1802,7 +1800,7 @@ For let variables the same pragmas are available as for ordinary variables.
 
 
 Const section
-~~~~~~~~~~~~~
+-------------
 
 Syntax::
 
@@ -1840,7 +1838,7 @@ they contain such a type.
 
 
 Static statement/expression
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+---------------------------
 
 Syntax::
   staticExpr ::= 'static' '(' optInd expr optPar ')'
@@ -1865,7 +1863,7 @@ support the FFI at compile time.
 
 
 If statement
-~~~~~~~~~~~~
+------------
 
 Syntax::
 
@@ -1895,7 +1893,7 @@ part, execution continues with the statement after the ``if`` statement.
 
 
 Case statement
-~~~~~~~~~~~~~~
+--------------
 
 Syntax::
 
@@ -1961,7 +1959,7 @@ a list of its elements:
 
 
 When statement
-~~~~~~~~~~~~~~
+--------------
 
 Syntax::
 
@@ -1995,7 +1993,7 @@ within ``object`` definitions.
 
 
 Return statement
-~~~~~~~~~~~~~~~~
+----------------
 
 Syntax::
 
@@ -2026,7 +2024,7 @@ variables, ``result`` is initialized to (binary) zero:
 
 
 Yield statement
-~~~~~~~~~~~~~~~
+---------------
 
 Syntax::
 
@@ -2046,7 +2044,7 @@ for further information.
 
 
 Block statement
-~~~~~~~~~~~~~~~
+---------------
 
 Syntax::
 
@@ -2071,7 +2069,7 @@ block to specify which block is to leave.
 
 
 Break statement
-~~~~~~~~~~~~~~~
+---------------
 
 Syntax::
 
@@ -2088,7 +2086,7 @@ absent, the innermost block is left.
 
 
 While statement
-~~~~~~~~~~~~~~~
+---------------
 
 Syntax::
 
@@ -2110,7 +2108,7 @@ so that they can be left with a ``break`` statement.
 
 
 Continue statement
-~~~~~~~~~~~~~~~~~~
+------------------
 
 Syntax::
 
@@ -2137,7 +2135,7 @@ Is equivalent to:
 
 
 Assembler statement
-~~~~~~~~~~~~~~~~~~~
+-------------------
 Syntax::
 
   asmStmt ::= 'asm' [pragma] (STR_LIT | RSTR_LIT | TRIPLESTR_LIT)
@@ -2159,7 +2157,7 @@ specified in the statement's pragmas. The default special character is ``'`'``:
     """
 
 If expression
-~~~~~~~~~~~~~
+-------------
 
 An `if expression` is almost like an if statement, but it is an expression.
 Example:
@@ -2172,12 +2170,12 @@ required. ``Elif`` parts are also allowed (but unlikely to be good
 style).
 
 When expression
-~~~~~~~~~~~~~~~
+---------------
 
 Just like an `if expression`, but corresponding to the when statement.
 
 Case expression
-~~~~~~~~~~~~~~~
+---------------
 
 The `case expression` is again very similar to the case statement:
 
@@ -2195,7 +2193,7 @@ effects. When multiple statements are given for a branch, Nimrod will use
 the last expression as the result value, much like in an `expr` template.
 
 Table constructor
-~~~~~~~~~~~~~~~~~
+-----------------
 
 A `table constructor`:idx: is syntactic sugar for an array constructor:
 
@@ -2223,7 +2221,7 @@ has lots of advantages:
 
 
 Type conversions
-~~~~~~~~~~~~~~~~
+----------------
 Syntactically a `type conversion` is like a procedure call, but a
 type name replaces the procedure name. A type conversion is always
 safe in the sense that a failure to convert a type to another
@@ -2231,7 +2229,7 @@ results in an exception (if it cannot be determined statically).
 
 
 Type casts
-~~~~~~~~~~
+----------
 Example:
 
 
@@ -2244,7 +2242,7 @@ only needed for low-level programming and are inherently unsafe.
 
 
 The addr operator
-~~~~~~~~~~~~~~~~~
+-----------------
 The `addr` operator returns the address of an l-value. If the
 type of the location is ``T``, the `addr` operator result is
 of the type ``ptr T``. Taking the address of an object that resides
@@ -2253,7 +2251,8 @@ object on the stack and can thus reference a non-existing object.
 
 
 Procedures
-~~~~~~~~~~
+==========
+
 What most programming languages call `methods`:idx: or `functions`:idx: are
 called `procedures`:idx: in Nimrod (which is the correct terminology). A
 procedure declaration defines an identifier and associates it with a block
@@ -2332,7 +2331,7 @@ notation. (Thus an operator can have more than two parameters):
   assert `*+`(3, 4, 6) == `*`(a, `+`(b, c))
 
 Closures
-~~~~~~~~
+--------
 
 Procedures can appear at the top level in a module as well as inside other
 scopes, in which case they are called nested procs. A nested proc can access
@@ -2344,7 +2343,7 @@ visible in both places). The closure environment may be allocated on the heap
 or on the stack if the compiler determines that this would be safe.
 
 Anonymous Procs
-~~~~~~~~~~~~~~~
+---------------
 
 Procs can also be treated as expressions, in which case it's allowed to omit
 the proc's name.
@@ -2360,7 +2359,7 @@ Procs as expressions can appear both as nested procs and inside top level
 executable code.
 
 Do notation
-~~~~~~~~~~~
+-----------
 
 As a special more convenient notation, proc expressions involved in procedure
 calls can use the ``do`` keyword:
@@ -2399,7 +2398,7 @@ The compatibility works in the other direction too as the ``do`` syntax can be
 used with macros and templates expecting ``stmt`` blocks.
 
 Nonoverloadable builtins
-~~~~~~~~~~~~~~~~~~~~~~~~
+------------------------
 
 The following builtin procs cannot be overloaded for reasons of implementation
 simplicity (they require specialized semantic checking)::
@@ -2413,7 +2412,7 @@ the ``system`` module.
 
 
 Var parameters
-~~~~~~~~~~~~~~
+--------------
 The type of a parameter may be prefixed with the ``var`` keyword:
 
 .. code-block:: nimrod
@@ -2465,7 +2464,7 @@ One can use `tuple unpacking`:idx: to access the tuple's fields:
 
 
 Var return type
-~~~~~~~~~~~~~~~
+---------------
 
 A proc, converter or iterator may return a ``var`` type which means that the
 returned value is an l-value and can be modified by the caller:
@@ -2499,7 +2498,7 @@ starts with the prefix ``m`` per convention.
 
 
 Overloading of the subscript operator
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-------------------------------------
 
 The ``[]`` subscript operator for arrays/openarrays/sequences can be overloaded.
 Overloading support is only possible if the first parameter has no type that
@@ -2508,7 +2507,7 @@ does not check this restriction.
 
 
 Multi-methods
-~~~~~~~~~~~~~
+=============
 
 Procedures always use static dispatch. `Multi-methods`:idx: use dynamic
 dispatch.
@@ -2580,7 +2579,7 @@ evaluation or dead code elimination do not work with methods.
 
 
 Iterators and the for statement
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+===============================
 
 Syntax::
 
@@ -2598,8 +2597,9 @@ Syntax::
 The `for`:idx: statement is an abstract mechanism to iterate over the elements
 of a container. It relies on an `iterator`:idx: to do so. Like ``while``
 statements, ``for`` statements open an `implicit block`:idx:, so that they
-can be left with a ``break`` statement. The ``for`` loop declares
+can be left with a ``break`` statement. 
 
+The ``for`` loop declares
 iteration variables (``x`` in the example) - their scope reaches until the
 end of the loop body. The iteration variables' types are inferred by the
 return type of the iterator.
@@ -2632,18 +2632,13 @@ The compiler generates code as if the programmer would have written this:
     echo(ch)
     inc(i)
 
-The current implementation always inlines the iterator code leading to zero
-overhead for the abstraction. But this may increase the code size. Later
-versions of the compiler will only inline iterators which have the calling
-convention ``inline``.
-
 If the iterator yields a tuple, there have to be as many iteration variables
 as there are components in the tuple. The i'th iteration variable's type is
 the type of the i'th component.
 
 
 Implict items/pairs invocations
-+++++++++++++++++++++++++++++++
+-------------------------------
 
 If the for loop expression ``e`` does not denote an iterator and the for loop
 has exactly 1 variable, the for loop expression is rewritten to ``items(e)``;
@@ -2660,8 +2655,90 @@ the rewriting step, so that all overloadings of ``items``/``pairs`` are taken
 into account.
 
 
+First class iterators
+---------------------
+
+There are 2 kinds of iterators in Nimrod: *inline* and *closure* iterators.
+An `inline iterator`:idx: is an iterator that's always inlined by the compiler 
+leading to zero overhead for the abstraction, but may result in a heavy
+increasee in code size. Inline iterators are second class
+citizens; one cannot pass them around like first class procs.
+
+In contrast to that, a `closure iterator`:idx: can be passed around:
+
+.. code-block:: nimrod
+  iterator count0(): int {.closure.} =
+    yield 0
+   
+  iterator count2(): int {.closure.} =
+    var x = 1
+    yield x
+    inc x
+    yield x
+
+  proc invoke(iter: iterator(): int {.closure.}) =
+    for x in iter(): echo x
+
+  invoke(count0)
+  invoke(count2)
+
+
+Closure iterators have other restrictions than inline iterators:
+
+1.) ``yield`` in a closure iterator can not occur in a ``try`` statement.
+2.) For now, a closure iterator cannot be evaluated at compile time.
+3.) ``return`` is allowed in a closure iterator (but rarely useful).
+4.) Since closure iterators can be used as a collaborative tasking 
+    system, ``void`` is a valid return type for them.
+5.) Both inline and closure iterators cannot be recursive.
+
+
+Iterators that are neither marked ``{.closure.}`` nor ``{.inline.}`` explicitly
+default to being inline, but that this may change in future versions of the
+implementation.
+
+The ``iterator`` type is always of the calling convention ``closure`` 
+implicitly; the following example shows how to use iterators to implement
+a `collaborative tasking`:idx: system:
+
+.. code-block:: nimrod
+  # simple tasking:
+  type
+    TTask = iterator (ticker: int)
+
+  iterator a1(ticker: int) {.closure.} =
+    echo "a1: A"
+    yield
+    echo "a1: B"
+    yield
+    echo "a1: C"
+    yield
+    echo "a1: D"
+
+  iterator a2(ticker: int) {.closure.} =
+    echo "a2: A"
+    yield
+    echo "a2: B"
+    yield
+    echo "a2: C"
+
+  proc runTasks(t: varargs[TTask]) =
+    var ticker = 0
+    while true:
+      let x = t[ticker mod t.len]
+      if finished(x): break
+      x(ticker)
+      inc ticker
+
+  runTasks(a1, a2)
+
+The builtin ``system.finished`` can be used to determine if an iterator has
+finished its operation; no exception is raised on an attempt to invoke an
+iterator that has already finished its work. 
+
+
 Type sections
-~~~~~~~~~~~~~
+=============
 
 Syntax::
 
@@ -2697,10 +2774,10 @@ possible within a single ``type`` section.
 
 
 Exception handling
-------------------
+==================
 
 Try statement
-~~~~~~~~~~~~~
+-------------
 
 Syntax::
 
@@ -2755,7 +2832,7 @@ is not executed (if an exception occurs).
 
 
 Except and finally statements
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-----------------------------
 
 `except`:idx: and `finally`:idx: can also be used as a stand-alone statements.
 Any statements following them in the current block will be considered to be 
@@ -2768,7 +2845,7 @@ in an implicit try block:
 
 
 Raise statement
-~~~~~~~~~~~~~~~
+---------------
 
 Syntax::
 
@@ -2791,7 +2868,7 @@ exception (unless a raise hook has been provided).
 
 
 OnRaise builtin
-~~~~~~~~~~~~~~~
+---------------
 
 ``system.onRaise`` can be used to override the behaviour of ``raise`` for a
 single ``try`` statement. `onRaise`:idx: has to be called within the ``try`` 
@@ -2815,10 +2892,10 @@ This allows for a Lisp-like `condition system`:idx:\:
 
 
 Effect system
--------------
+=============
 
 Exception tracking
-~~~~~~~~~~~~~~~~~~
+------------------
 
 Nimrod supports `exception tracking`:idx:. The `raises`:idx: pragma can used to
 explicitly define which exceptions a proc/iterator/method/converter is allowed
@@ -2873,7 +2950,7 @@ possibly raised exceptions; the algorithm operates on ``p``'s call graph:
 
 
 Tag tracking
-~~~~~~~~~~~~
+------------
 
 The exception tracking is part of Nimrod's `effect system`:idx:. Raising an
 exception is an *effect*. Other effects can also be defined. A user defined 
@@ -2895,7 +2972,7 @@ exception tracking.
 
 
 Read/Write tracking
-~~~~~~~~~~~~~~~~~~~
+-------------------
 
 **Note**: Read/write tracking is not yet implemented!
 
@@ -2904,7 +2981,7 @@ exception tracking.
 
 
 Effects pragma
-~~~~~~~~~~~~~~
+--------------
 
 The `effects`:idx: pragma has been designed to assist the programmer with the
 effects analysis. It is a statement that makes the compiler output all inferred
@@ -2923,7 +3000,7 @@ listed as it cannot be raised in the branch the ``effects`` pragma appears in.
 
 
 Generics
---------
+========
 
 Example:
 
@@ -2981,7 +3058,7 @@ introduce type parameters or to instantiate a generic proc, iterator or type.
 
 
 Is operator
-~~~~~~~~~~~
+-----------
 
 The `is`:idx: operator checks for type equivalence at compile time. It is
 therefore very useful for type specialization within generic code: 
@@ -2996,7 +3073,7 @@ therefore very useful for type specialization within generic code:
 
 
 Type operator
-~~~~~~~~~~~~~
+-------------
 
 The `type`:idx: (in many other languages called `typeof`:idx:) operator can
 be used to get the type of an expression: 
@@ -3019,7 +3096,7 @@ other interpretations:
 
 
 Type Classes
-~~~~~~~~~~~~
+------------
 
 A `type class`:idx: is a special pseudo-type that can be used to match against
 types in the context of overload resolution or the ``is`` operator. 
@@ -3108,13 +3185,15 @@ the dot syntax:
 If anonymous type classes are used, the ``type`` operator can be used to 
 discover the instantiated type of each param.
 
+
 User defined type classes
-~~~~~~~~~~~~~~~~~~~~~~~~~
+-------------------------
 
 To be written.
 
+
 Return Type Inference
-~~~~~~~~~~~~~~~~~~~~~
+---------------------
 
 If a type class is used as the return type of a proc and it won't be bound to
 a concrete type by some of the proc params, Nimrod will infer the return type
@@ -3132,7 +3211,7 @@ also influence the inferred return type.
 
 
 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
@@ -3171,7 +3250,7 @@ A symbol can be forced to be open by a `mixin`:idx: declaration:
 
 
 Templates
----------
+=========
 
 A `template`:idx: is a simple form of a macro: It is a simple substitution
 mechanism that operates on Nimrod's abstract syntax trees. It is processed in
@@ -3202,7 +3281,7 @@ Real types can be used too; this implies that expressions are expected.
 
 
 Ordinary vs immediate templates
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-------------------------------
 
 There are two different kinds of templates: `immediate`:idx: templates and
 ordinary templates. Ordinary templates take part in overloading resolution. As
@@ -3229,7 +3308,7 @@ receive undeclared identifiers:
 
 
 Scoping in templates
-~~~~~~~~~~~~~~~~~~~~
+--------------------
 
 The template body does not open a new scope. To open a new scope a ``block``
 statement can be used:
@@ -3251,7 +3330,7 @@ statement can be used:
 
 
 Passing a code block to a template
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+----------------------------------
 
 If there is a ``stmt`` parameter it should be the last in the template
 declaration, because statements are passed to a template via a
@@ -3298,7 +3377,7 @@ Symbol binding within templates happens after template instantiation:
 
 
 Bind statement
-~~~~~~~~~~~~~~
+--------------
 
 Syntax::
   
@@ -3329,7 +3408,7 @@ A ``bind`` statement can also be used in generics for the same purpose.
 
 
 Identifier construction
-~~~~~~~~~~~~~~~~~~~~~~~
+-----------------------
 
 In templates identifiers can be constructed with the backticks notation:
 
@@ -3348,7 +3427,7 @@ In the example ``name`` is instantiated with ``myint``, so \`T name\` becomes
 
 
 Lookup rules for template parameters
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+------------------------------------
 
 A parameter ``p`` in a template is even substituted in the expression ``x.p``.
 Thus template arguments can be used as field names and a global symbol can be
@@ -3389,7 +3468,7 @@ But the global symbol can properly be captured by a ``bind`` statement:
 
 
 Hygiene in templates
-~~~~~~~~~~~~~~~~~~~~
+--------------------
 
 Per default templates are `hygienic`:idx:\: Local identifiers declared in a
 template cannot be accessed in the instantiation context:
@@ -3444,7 +3523,7 @@ a template. ``inject`` and ``gensym`` have no effect in ``dirty`` templates.
 
 
 Macros
-------
+======
 
 A `macro`:idx: is a special kind of low level template. Macros can be used
 to implement `domain specific languages`:idx:. Like templates, macros come in
@@ -3463,7 +3542,7 @@ There are two ways to invoke a macro:
 
 
 Expression Macros
-~~~~~~~~~~~~~~~~~
+-----------------
 
 The following example implements a powerful ``debug`` command that accepts a
 variable number of arguments:
@@ -3517,7 +3596,7 @@ children.
 
 
 BindSym
-~~~~~~~
+-------
 
 The above ``debug`` macro relies on the fact that ``write``, ``writeln`` and
 ``stdout`` are declared in the system module and thus visible in the 
@@ -3565,7 +3644,7 @@ overloaded symbols implicitly.
 
 
 Statement Macros
-~~~~~~~~~~~~~~~~
+----------------
 
 Statement macros are defined just as expression macros. However, they are
 invoked by an expression following a colon::
@@ -3609,7 +3688,7 @@ powerful programming construct that still suffices. So the "check list" is:
 
 
 Macros as pragmas
-~~~~~~~~~~~~~~~~~
+-----------------
 
 Whole routines (procs, iterators etc.) can also be passed to a template or 
 a macro via the pragma notation: 
@@ -3629,17 +3708,17 @@ This is a simple syntactic transformation into:
 
 
 Special Types
--------------
+=============
 
 typedesc
-~~~~~~~~
+--------
 
-`typedesc` is a special type allowing you to treat types as compile-time values
+`typedesc` is a special type allowing one to treat types as compile-time values
 (i.e. if types are compile-time values and all values have a type, then 
 typedesc must be their type).
 
 When used as a regular proc param, typedesc acts as a type class. The proc
-will be instantiated for each unique type parameter and you can refer to the
+will be instantiated for each unique type parameter and one can refer to the
 instantiation type using the param name:
 
 .. code-block:: nimrod
@@ -3654,8 +3733,8 @@ instantiation type using the param name:
 When used with macros and .compileTime. procs on the other hand, the compiler
 don't need to instantiate the code multiple times, because types then can be
 manipulated using the unified internal symbol representation. In such context
-typedesc acts as any other type. You can create variables, store typedesc
-values inside containers and so on. For example, here is how we can create 
+typedesc acts as any other type. One can create variables, store typedesc
+values inside containers and so on. For example, here is how one can create 
 a type-safe wrapper for the unsafe `printf` function from C:
 
 .. code-block:: nimrod
diff --git a/doc/tut1.txt b/doc/tut1.txt
index 95d13ceb9..d8d04bc93 100755
--- a/doc/tut1.txt
+++ b/doc/tut1.txt
@@ -780,12 +780,15 @@ important differences:
 * Iterators cannot contain a ``return`` statement and procs cannot contain a
   ``yield`` statement.
 * Iterators have no implicit ``result`` variable.
-* Iterators do not support recursion. (This restriction will be gone in a
-  future version of the compiler.)
+* Iterators do not support recursion.
 * Iterators cannot be forward declared, because the compiler must be able
   to inline an iterator. (This restriction will be gone in a
   future version of the compiler.)
 
+However, you can also use a ``closure`` iterator to get a different set of
+restrictions. See `first class iterators <manual.html#first-class-iterators>`_
+for details.
+
 
 Basic types
 ===========
diff --git a/readme.md b/readme.md
index fe4542b56..d5cb35820 100644
--- a/readme.md
+++ b/readme.md
@@ -34,7 +34,9 @@ If you are on a fairly modern *nix system, the following steps should work:
 ```
 $ git clone git://github.com/Araq/Nimrod.git
 $ cd Nimrod
-$ unzip build/csources.zip
+$ cd build
+$ unzip csources.zip
+$ cd ..
 $ ./build.sh
 $ bin/nimrod c koch
 $ ./koch boot -d:release
@@ -61,4 +63,4 @@ developed with Nimrod, allowing you to create commercial applications.
 Read copying.txt for more details.
 
 Copyright (c) 2004-2012 Andreas Rumpf.
-All rights reserved.
\ No newline at end of file
+All rights reserved.
diff --git a/readme.txt b/readme.txt
index fe4542b56..d5cb35820 100755
--- a/readme.txt
+++ b/readme.txt
@@ -34,7 +34,9 @@ If you are on a fairly modern *nix system, the following steps should work:
 ```
 $ git clone git://github.com/Araq/Nimrod.git
 $ cd Nimrod
-$ unzip build/csources.zip
+$ cd build
+$ unzip csources.zip
+$ cd ..
 $ ./build.sh
 $ bin/nimrod c koch
 $ ./koch boot -d:release
@@ -61,4 +63,4 @@ developed with Nimrod, allowing you to create commercial applications.
 Read copying.txt for more details.
 
 Copyright (c) 2004-2012 Andreas Rumpf.
-All rights reserved.
\ No newline at end of file
+All rights reserved.
diff --git a/tests/run/titer9.nim b/tests/run/titer9.nim
index 0d6c466c1..99874e70a 100644
--- a/tests/run/titer9.nim
+++ b/tests/run/titer9.nim
@@ -4,17 +4,17 @@ discard """
 0'''
 """
 
-iterator count(x: int, skip: bool): int {.closure.} =
+iterator count[T](x: T, skip: bool): int {.closure.} =
   if skip: return x+10
   else: yield x+1
 
   if skip: return x+10
   else: yield x+2
 
-proc takeProc(x: iterator (x: int, skip: bool): int) =
+proc takeProc[T](x: iterator (x: T, skip: bool): int) =
   echo x(4, false)
   echo x(4, true)
   echo x(4, false)
 
-takeProc(count)
+takeProc(count[int])
 
diff --git a/todo.txt b/todo.txt
index b162812bc..3d8859fc2 100755
--- a/todo.txt
+++ b/todo.txt
@@ -1,11 +1,11 @@
 version 0.9.2
 =============
 
+- fix closure bug finally
 - test&finish first class iterators:
   * nested iterators
-  * test generic iterators
-- fix closure bug finally
 - fix marshal bug
+- investigate nimgame bug
 
 
 version 0.9.X
@@ -87,6 +87,7 @@ GC
 Optimizations
 =============
 
+- optimize 'if' with a constant condition
 - escape analysis for string/seq seems to be easy to do too;
   even further write barrier specialization
 - inlining of first class functions