summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xdoc/intern.txt130
-rwxr-xr-xdoc/lib.txt2
-rwxr-xr-xdoc/theindex.txt138
-rwxr-xr-xexamples/keyval.nim4
-rwxr-xr-xlib/impure/dialogs.nim5
-rwxr-xr-xlib/nimbase.h7
-rwxr-xr-xlib/pure/os.nim7
-rwxr-xr-xlib/pure/times.nim27
-rwxr-xr-xlib/pure/unicode.nim2
-rwxr-xr-xlib/system.nim15
-rwxr-xr-xlib/system/alloc.nim8
-rwxr-xr-xlib/system/gc.nim7
-rwxr-xr-xlib/system/sysio.nim11
-rwxr-xr-xlib/wrappers/sdl/sdl.nim2
-rwxr-xr-xlib/wrappers/sdl/sdl_ttf.nim2
-rwxr-xr-xrod/docgen.nim11
-rwxr-xr-xrod/evals.nim3
-rwxr-xr-xrod/semexprs.nim2
-rwxr-xr-xrod/seminst.nim59
-rwxr-xr-xrod/semstmts.nim5
-rwxr-xr-xrod/semtypes.nim135
-rwxr-xr-xrod/sigmatch.nim54
-rwxr-xr-xrod/transf.nim106
-rwxr-xr-xtests/accept/run/spec.csv1
-rwxr-xr-xweb/news.txt11
25 files changed, 411 insertions, 343 deletions
diff --git a/doc/intern.txt b/doc/intern.txt
index 37c376568..50fc9b8b1 100755
--- a/doc/intern.txt
+++ b/doc/intern.txt
@@ -114,6 +114,71 @@ Thus we need to serialize this graph as RTTI for C code generation.
 Look at the file ``lib/system/hti.nim`` for more information.
 
 
+The compiler's architecture
+===========================
+
+Nimrod uses the classic compiler architecture: A scanner feds tokens to a
+parser. The parser builds a syntax tree that is used by the code generator.
+This syntax tree is the interface between the parser and the code generator.
+It is essential to understand most of the compiler's code.
+
+In order to compile Nimrod correctly, type-checking has to be seperated from
+parsing. Otherwise generics cannot work.
+
+.. include:: filelist.txt
+
+
+The syntax tree
+---------------
+The synax tree consists of nodes which may have an arbitrary number of
+children. Types and symbols are represented by other nodes, because they
+may contain cycles. The AST changes its shape after semantic checking. This
+is needed to make life easier for the code generators. See the "ast" module
+for the type definitions. The `macros <macros.html>`_ module contains many
+examples how the AST represents each syntactic structure. 
+
+
+How the RTL is compiled
+=======================
+
+The ``system`` module contains the part of the RTL which needs support by
+compiler magic (and the stuff that needs to be in it because the spec
+says so). The C code generator generates the C code for it just like any other
+module. However, calls to some procedures like ``addInt`` are inserted by
+the CCG. Therefore the module ``magicsys`` contains a table (``compilerprocs``)
+with all symbols that are marked as ``compilerproc``. ``compilerprocs`` are
+needed by the code generator. A ``magic`` proc is not the same as a
+``compilerproc``: A ``magic`` is a proc that needs compiler magic for its
+semantic checking, a ``compilerproc`` is a proc that is used by the code
+generator.
+
+
+Debugging Nimrod's memory management
+====================================
+
+The following paragraphs are mostly a reminder for myself. Things to keep
+in mind:
+
+* Segmentation faults can have multiple reasons: One that is frequently
+  forgotten is that *stack overflow* can trigger one!
+* If an assertion in Nimrod's memory manager or GC fails, the stack trace
+  keeps allocating memory! Thus a stack overflow may happen, hiding the
+  real issue. 
+* What seem to be C code generation problems is often a bug resulting from
+  not producing prototypes, so that some types default to ``cint``. Testing
+  without the ``-w`` option helps!
+
+
+Generation of dynamic link libraries
+====================================
+
+Generation of dynamic link libraries or shared libraries is not difficult; the
+underlying C compiler already does all the hard work for us. The problem is the
+common runtime library, especially the memory manager. Note that Borland's
+Delphi had exactly the same problem. The workaround is to not link the GC with
+the Dll and provide an extra runtime dll that needs to be initialized.
+
+
 The Garbage Collector
 =====================
 
@@ -216,71 +281,6 @@ the check whether the ref is on the stack is very cheap (only two
 comparisons).
 
 
-The compiler's architecture
-===========================
-
-Nimrod uses the classic compiler architecture: A scanner feds tokens to a
-parser. The parser builds a syntax tree that is used by the code generator.
-This syntax tree is the interface between the parser and the code generator.
-It is essential to understand most of the compiler's code.
-
-In order to compile Nimrod correctly, type-checking has to be seperated from
-parsing. Otherwise generics would not work.
-
-.. include:: filelist.txt
-
-
-The syntax tree
----------------
-The synax tree consists of nodes which may have an arbitrary number of
-children. Types and symbols are represented by other nodes, because they
-may contain cycles. The AST changes its shape after semantic checking. This
-is needed to make life easier for the code generators. See the "ast" module
-for the type definitions. The `macros <macros.html>`_ module contains many
-examples how the AST represents each syntactic structure. 
-
-
-How the RTL is compiled
-=======================
-
-The ``system`` module contains the part of the RTL which needs support by
-compiler magic (and the stuff that needs to be in it because the spec
-says so). The C code generator generates the C code for it just like any other
-module. However, calls to some procedures like ``addInt`` are inserted by
-the CCG. Therefore the module ``magicsys`` contains a table (``compilerprocs``)
-with all symbols that are marked as ``compilerproc``. ``compilerprocs`` are
-needed by the code generator. A ``magic`` proc is not the same as a
-``compilerproc``: A ``magic`` is a proc that needs compiler magic for its
-semantic checking, a ``compilerproc`` is a proc that is used by the code
-generator.
-
-
-Debugging Nimrod's memory management
-====================================
-
-The following paragraphs are mostly a reminder for myself. Things to keep
-in mind:
-
-* Segmentation faults can have multiple reasons: One that is frequently
-  forgotten is that *stack overflow* can trigger one!
-* If an assertion in Nimrod's memory manager or GC fails, the stack trace
-  keeps allocating memory! Thus a stack overflow may happen, hiding the
-  real issue. 
-* What seem to be C code generation problems is often a bug resulting from
-  not producing prototypes, so that some types default to ``cint``. Testing
-  without the ``-w`` option helps!
-
-
-Generation of dynamic link libraries
-====================================
-
-Generation of dynamic link libraries or shared libraries is not difficult; the
-underlying C compiler already does all the hard work for us. The problem is the
-common runtime library, especially the memory manager. Note that Borland's
-Delphi had exactly the same problem. The workaround is to not link the GC with
-the Dll and provide an extra runtime dll that needs to be initialized.
-
-
 Code generation for closures
 ============================
 
diff --git a/doc/lib.txt b/doc/lib.txt
index a56aa5bf4..227a73405 100755
--- a/doc/lib.txt
+++ b/doc/lib.txt
@@ -238,7 +238,7 @@ Database support
   for other databases too.
  
 * `db_sqlite <db_sqlite.html>`_
-  A higher level mySQL database wrapper. The same interface is implemented
+  A higher level SQLite database wrapper. The same interface is implemented
   for other databases too.
 
 
diff --git a/doc/theindex.txt b/doc/theindex.txt
index b734046af..9fc9b10e2 100755
--- a/doc/theindex.txt
+++ b/doc/theindex.txt
@@ -276,10 +276,10 @@ Index
      `ropes.html#115 <ropes.html#115>`_
 
    `[]`:idx:
-     `xmltree.html#114 <xmltree.html#114>`_
+     `graphics.html#111 <graphics.html#111>`_
 
    `[]`:idx:
-     `graphics.html#111 <graphics.html#111>`_
+     `xmltree.html#114 <xmltree.html#114>`_
 
    `[]=`:idx:
      `strtabs.html#106 <strtabs.html#106>`_
@@ -731,12 +731,6 @@ Index
    `clonglong`:idx:
      `system.html#388 <system.html#388>`_
 
-   `Close`:idx:
-     * `system.html#512 <system.html#512>`_
-     * `db_postgres.html#117 <db_postgres.html#117>`_
-     * `db_mysql.html#117 <db_mysql.html#117>`_
-     * `db_sqlite.html#117 <db_sqlite.html#117>`_
-
    `close`:idx:
      * `sockets.html#121 <sockets.html#121>`_
      * `lexbase.html#105 <lexbase.html#105>`_
@@ -746,8 +740,14 @@ Index
      * `zipfiles.html#103 <zipfiles.html#103>`_
      * `httpserver.html#106 <httpserver.html#106>`_
 
+   `Close`:idx:
+     * `system.html#513 <system.html#513>`_
+     * `db_postgres.html#117 <db_postgres.html#117>`_
+     * `db_mysql.html#117 <db_mysql.html#117>`_
+     * `db_sqlite.html#117 <db_sqlite.html#117>`_
+
    `CloseFile`:idx:
-     `system.html#511 <system.html#511>`_
+     `system.html#512 <system.html#512>`_
 
    `closure`:idx:
      `manual.html#177 <manual.html#177>`_
@@ -1350,8 +1350,8 @@ Index
      `system.html#392 <system.html#392>`_
 
    `cstringArrayToSeq`:idx:
-     * `system.html#539 <system.html#539>`_
      * `system.html#540 <system.html#540>`_
+     * `system.html#541 <system.html#541>`_
 
    `CSV`:idx:
      `parsecsv.html#101 <parsecsv.html#101>`_
@@ -1777,8 +1777,7 @@ Index
      * `strutils.html#157 <strutils.html#157>`_
 
    `deleteStr`:idx:
-     * `strutils.html#124 <strutils.html#124>`_
-     * `strutils.html#158 <strutils.html#158>`_
+     `strutils.html#124 <strutils.html#124>`_
 
    `dfn`:idx:
      `xmlgen.html#125 <xmlgen.html#125>`_
@@ -1894,7 +1893,7 @@ Index
      * `db_sqlite.html#104 <db_sqlite.html#104>`_
 
    `editDistance`:idx:
-     `strutils.html#166 <strutils.html#166>`_
+     `strutils.html#165 <strutils.html#165>`_
 
    `EDivByZero`:idx:
      `system.html#147 <system.html#147>`_
@@ -2020,7 +2019,7 @@ Index
      `endb.html#102 <endb.html#102>`_
 
    `EndOfFile`:idx:
-     * `system.html#513 <system.html#513>`_
+     * `system.html#514 <system.html#514>`_
      * `lexbase.html#101 <lexbase.html#101>`_
 
    `endsWith`:idx:
@@ -2132,7 +2131,7 @@ Index
 
    `escape`:idx:
      * `manual.html#133 <manual.html#133>`_
-     * `strutils.html#163 <strutils.html#163>`_
+     * `strutils.html#162 <strutils.html#162>`_
      * `xmltree.html#122 <xmltree.html#122>`_
 
    `escape sequences`:idx:
@@ -2373,7 +2372,7 @@ Index
      `mysql.html#218 <mysql.html#218>`_
 
    `fileHandle`:idx:
-     `system.html#538 <system.html#538>`_
+     `system.html#539 <system.html#539>`_
 
    `fileNewer`:idx:
      `os.html#119 <os.html#119>`_
@@ -2433,7 +2432,7 @@ Index
      `macros.html#130 <macros.html#130>`_
 
    `FlushFile`:idx:
-     `system.html#515 <system.html#515>`_
+     `system.html#516 <system.html#516>`_
 
    `for`:idx:
      * `manual.html#214 <manual.html#214>`_
@@ -2594,10 +2593,10 @@ Index
      `os.html#162 <os.html#162>`_
 
    `getFilePos`:idx:
-     `system.html#535 <system.html#535>`_
+     `system.html#536 <system.html#536>`_
 
    `getFileSize`:idx:
-     * `system.html#527 <system.html#527>`_
+     * `system.html#528 <system.html#528>`_
      * `os.html#171 <os.html#171>`_
 
    `getFreeMem`:idx:
@@ -2866,13 +2865,13 @@ Index
    `hr`:idx:
      `xmlgen.html#140 <xmlgen.html#140>`_
 
-   `html`:idx:
-     `xmlgen.html#139 <xmlgen.html#139>`_
-
    `HTML`:idx:
      * `parsexml.html#102 <parsexml.html#102>`_
      * `xmlgen.html#102 <xmlgen.html#102>`_
 
+   `html`:idx:
+     `xmlgen.html#139 <xmlgen.html#139>`_
+
    `htmlTag`:idx:
      * `htmlparser.html#105 <htmlparser.html#105>`_
      * `htmlparser.html#106 <htmlparser.html#106>`_
@@ -2914,24 +2913,24 @@ Index
    `ident=`:idx:
      `macros.html#132 <macros.html#132>`_
 
-   `IdentChars`:idx:
-     `strutils.html#105 <strutils.html#105>`_
-
    `identChars`:idx:
      `pegs.html#132 <pegs.html#132>`_
 
+   `IdentChars`:idx:
+     `strutils.html#105 <strutils.html#105>`_
+
    `identifier`:idx:
      `manual.html#105 <manual.html#105>`_
 
    `Identifiers`:idx:
      `manual.html#116 <manual.html#116>`_
 
-   `IdentStartChars`:idx:
-     `strutils.html#106 <strutils.html#106>`_
-
    `identStartChars`:idx:
      `pegs.html#133 <pegs.html#133>`_
 
+   `IdentStartChars`:idx:
+     `strutils.html#106 <strutils.html#106>`_
+
    `if`:idx:
      `manual.html#189 <manual.html#189>`_
 
@@ -3018,7 +3017,7 @@ Index
      * `db_sqlite.html#115 <db_sqlite.html#115>`_
 
    `insertSep`:idx:
-     `strutils.html#162 <strutils.html#162>`_
+     `strutils.html#161 <strutils.html#161>`_
 
    `int`:idx:
      `system.html#101 <system.html#101>`_
@@ -3208,8 +3207,8 @@ Index
      `nimrodc.html#103 <nimrodc.html#103>`_
 
    `lines`:idx:
-     * `system.html#536 <system.html#536>`_
      * `system.html#537 <system.html#537>`_
+     * `system.html#538 <system.html#538>`_
 
    `lineTrace`:idx:
      `nimrodc.html#105 <nimrodc.html#105>`_
@@ -3233,13 +3232,13 @@ Index
    `LoadLib`:idx:
      `dynlib.html#102 <dynlib.html#102>`_
 
-   `loadXML`:idx:
-     `xmldomparser.html#104 <xmldomparser.html#104>`_
-
    `loadXml`:idx:
      * `xmlparser.html#104 <xmlparser.html#104>`_
      * `xmlparser.html#105 <xmlparser.html#105>`_
 
+   `loadXML`:idx:
+     `xmldomparser.html#104 <xmldomparser.html#104>`_
+
    `loadXMLFile`:idx:
      `xmldomparser.html#105 <xmldomparser.html#105>`_
 
@@ -3965,12 +3964,12 @@ Index
    `nan`:idx:
      `system.html#441 <system.html#441>`_
 
-   `natural`:idx:
-     `pegs.html#135 <pegs.html#135>`_
-
    `Natural`:idx:
      `system.html#134 <system.html#134>`_
 
+   `natural`:idx:
+     `pegs.html#135 <pegs.html#135>`_
+
    `neginf`:idx:
      `system.html#440 <system.html#440>`_
 
@@ -4056,13 +4055,13 @@ Index
    `newIntLitNode`:idx:
      `macros.html#142 <macros.html#142>`_
 
+   `newLine`:idx:
+     `pegs.html#122 <pegs.html#122>`_
+
    `newline`:idx:
      * `manual.html#121 <manual.html#121>`_
      * `pegs.html#121 <pegs.html#121>`_
 
-   `newLine`:idx:
-     `pegs.html#122 <pegs.html#122>`_
-
    `NewLines`:idx:
      `lexbase.html#102 <lexbase.html#102>`_
 
@@ -4246,12 +4245,12 @@ Index
    `ord`:idx:
      `system.html#182 <system.html#182>`_
 
-   `ordinal`:idx:
-     `tut1.html#114 <tut1.html#114>`_
-
    `Ordinal`:idx:
      `system.html#114 <system.html#114>`_
 
+   `ordinal`:idx:
+     `tut1.html#114 <tut1.html#114>`_
+
    `Ordinal types`:idx:
      `manual.html#142 <manual.html#142>`_
 
@@ -4313,12 +4312,12 @@ Index
    `parseColor`:idx:
      `colors.html#249 <colors.html#249>`_
 
-   `parseFloat`:idx:
-     `parseutils.html#111 <parseutils.html#111>`_
-
    `ParseFloat`:idx:
      `strutils.html#144 <strutils.html#144>`_
 
+   `parseFloat`:idx:
+     `parseutils.html#111 <parseutils.html#111>`_
+
    `parseHex`:idx:
      `parseutils.html#101 <parseutils.html#101>`_
 
@@ -4332,17 +4331,17 @@ Index
    `parseIdent`:idx:
      `parseutils.html#103 <parseutils.html#103>`_
 
-   `ParseInt`:idx:
-     `strutils.html#142 <strutils.html#142>`_
-
    `parseInt`:idx:
      `parseutils.html#109 <parseutils.html#109>`_
 
+   `ParseInt`:idx:
+     `strutils.html#142 <strutils.html#142>`_
+
    `parseOct`:idx:
      `parseutils.html#102 <parseutils.html#102>`_
 
    `ParseOctInt`:idx:
-     `strutils.html#159 <strutils.html#159>`_
+     `strutils.html#158 <strutils.html#158>`_
 
    `parsePeg`:idx:
      `pegs.html#154 <pegs.html#154>`_
@@ -4644,8 +4643,7 @@ Index
      `httpclient.html#109 <httpclient.html#109>`_
 
    `PostgreSQL`:idx:
-     * `db_postgres.html#101 <db_postgres.html#101>`_
-     * `db_sqlite.html#101 <db_sqlite.html#101>`_
+     `db_postgres.html#101 <db_postgres.html#101>`_
 
    `pow`:idx:
      `math.html#132 <math.html#132>`_
@@ -4878,23 +4876,23 @@ Index
      `streams.html#106 <streams.html#106>`_
 
    `readBuffer`:idx:
-     `system.html#530 <system.html#530>`_
+     `system.html#531 <system.html#531>`_
 
    `ReadBytes`:idx:
-     `system.html#528 <system.html#528>`_
+     `system.html#529 <system.html#529>`_
 
    `readChar`:idx:
-     * `system.html#514 <system.html#514>`_
+     * `system.html#515 <system.html#515>`_
      * `streams.html#105 <streams.html#105>`_
 
    `ReadChars`:idx:
-     `system.html#529 <system.html#529>`_
+     `system.html#530 <system.html#530>`_
 
    `readData`:idx:
      `cgi.html#109 <cgi.html#109>`_
 
    `readFile`:idx:
-     `system.html#516 <system.html#516>`_
+     `system.html#517 <system.html#517>`_
 
    `readFloat32`:idx:
      `streams.html#111 <streams.html#111>`_
@@ -4915,7 +4913,7 @@ Index
      `streams.html#107 <streams.html#107>`_
 
    `readLine`:idx:
-     * `system.html#524 <system.html#524>`_
+     * `system.html#525 <system.html#525>`_
      * `streams.html#114 <streams.html#114>`_
 
    `readRow`:idx:
@@ -5041,6 +5039,9 @@ Index
      * `regexprs.html#117 <regexprs.html#117>`_
      * `re.html#131 <re.html#131>`_
 
+   `reopen`:idx:
+     `system.html#511 <system.html#511>`_
+
    `repeatChar`:idx:
      `strutils.html#147 <strutils.html#147>`_
 
@@ -5256,7 +5257,7 @@ Index
      `os.html#163 <os.html#163>`_
 
    `setFilePos`:idx:
-     `system.html#534 <system.html#534>`_
+     `system.html#535 <system.html#535>`_
 
    `SET_FLAG`:idx:
      `mysql.html#135 <mysql.html#135>`_
@@ -5378,6 +5379,9 @@ Index
      * `db_postgres.html#106 <db_postgres.html#106>`_
      * `db_sqlite.html#106 <db_sqlite.html#106>`_
 
+   `SQLite`:idx:
+     `db_sqlite.html#101 <db_sqlite.html#101>`_
+
    `sqlite3_aggregate_context`:idx:
      `sqlite3.html#261 <sqlite3.html#261>`_
 
@@ -6401,7 +6405,7 @@ Index
      `system.html#411 <system.html#411>`_
 
    `toBin`:idx:
-     `strutils.html#161 <strutils.html#161>`_
+     `strutils.html#160 <strutils.html#160>`_
 
    `TObject`:idx:
      `system.html#136 <system.html#136>`_
@@ -6421,7 +6425,7 @@ Index
      * `unicode.html#111 <unicode.html#111>`_
 
    `toOct`:idx:
-     `strutils.html#160 <strutils.html#160>`_
+     `strutils.html#159 <strutils.html#159>`_
 
    `toOctal`:idx:
      `strutils.html#125 <strutils.html#125>`_
@@ -6722,10 +6726,10 @@ Index
      `cgi.html#110 <cgi.html#110>`_
 
    `validEmailAddress`:idx:
-     `strutils.html#164 <strutils.html#164>`_
+     `strutils.html#163 <strutils.html#163>`_
 
    `validIdentifier`:idx:
-     `strutils.html#165 <strutils.html#165>`_
+     `strutils.html#164 <strutils.html#164>`_
 
    `Var`:idx:
      `manual.html#187 <manual.html#187>`_
@@ -6788,32 +6792,32 @@ Index
      `times.html#118 <times.html#118>`_
 
    `write`:idx:
-     * `system.html#517 <system.html#517>`_
      * `system.html#518 <system.html#518>`_
      * `system.html#519 <system.html#519>`_
      * `system.html#520 <system.html#520>`_
      * `system.html#521 <system.html#521>`_
      * `system.html#522 <system.html#522>`_
      * `system.html#523 <system.html#523>`_
+     * `system.html#524 <system.html#524>`_
      * `streams.html#103 <streams.html#103>`_
      * `streams.html#104 <streams.html#104>`_
      * `ropes.html#118 <ropes.html#118>`_
 
    `writeBuffer`:idx:
-     `system.html#533 <system.html#533>`_
+     `system.html#534 <system.html#534>`_
 
    `writeBytes`:idx:
-     `system.html#531 <system.html#531>`_
+     `system.html#532 <system.html#532>`_
 
    `writeChars`:idx:
-     `system.html#532 <system.html#532>`_
+     `system.html#533 <system.html#533>`_
 
    `writeContentType`:idx:
      `cgi.html#144 <cgi.html#144>`_
 
    `writeln`:idx:
-     * `system.html#525 <system.html#525>`_
      * `system.html#526 <system.html#526>`_
+     * `system.html#527 <system.html#527>`_
 
    `WriteStyled`:idx:
      `terminal.html#112 <terminal.html#112>`_
diff --git a/examples/keyval.nim b/examples/keyval.nim
index f5ff4ac01..19a430a1e 100755
--- a/examples/keyval.nim
+++ b/examples/keyval.nim
@@ -3,7 +3,7 @@ import re
 
 for x in lines("myfile.txt"):
   if x =~ re"(\w+)=(.*)":
-    echo "Key: ", matches[1], 
-         " Value: ", matches[2]
+    echo "Key: ", matches[0], 
+         " Value: ", matches[1]
 
 
diff --git a/lib/impure/dialogs.nim b/lib/impure/dialogs.nim
index ef52d573a..c0b077177 100755
--- a/lib/impure/dialogs.nim
+++ b/lib/impure/dialogs.nim
@@ -9,8 +9,7 @@
 
 
 ## This module implements portable dialogs for Nimrod; the implementation
-## builds on the GTK interface. On Windows, native dialogs are shown if
-## appropriate.
+## builds on the GTK interface. On Windows, native dialogs are shown instead.
 
 import
   glib2, gtk2
@@ -174,7 +173,7 @@ proc ChooseFileToSave*(window: PWindow, root: string = ""): string =
     var chooser = file_chooser_dialog_new("Save File", window,
                 FILE_CHOOSER_ACTION_SAVE,
                 STOCK_CANCEL, RESPONSE_CANCEL,
-                STOCK_OPEN, RESPONSE_OK, nil)
+                STOCK_SAVE, RESPONSE_OK, nil)
     if root.len > 0:
       discard set_current_folder(chooser, root)
     set_do_overwrite_confirmation(chooser, true)
diff --git a/lib/nimbase.h b/lib/nimbase.h
index c7b3e551d..4c549120c 100755
--- a/lib/nimbase.h
+++ b/lib/nimbase.h
@@ -24,6 +24,13 @@ __TINYC__
 
 #if !defined(__TINYC__)
 #  include  <math.h>
+#else
+/*#  define __GNUC__ 3
+#  define GCC_MAJOR 4
+#  define __GNUC_MINOR__ 4
+#  define __GNUC_PATCHLEVEL__ 5 */
+
+#  define __DECLSPEC_SUPPORTED 1
 #endif
 
 /* calling convention mess ----------------------------------------------- */
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index 129774f6e..39ff699bb 100755
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -953,8 +953,8 @@ proc parseCmdLine*(c: string): seq[string] =
   ##   causing a literal double quotation mark (") to be placed in argv.
   ##
   ## On Posix systems, it uses the following parsing rules:
-  ## components are separated by
-  ## whitespace unless the whitespace occurs within ``"`` or ``'`` quotes.
+  ## Components are separated by whitespace unless the whitespace 
+  ## occurs within ``"`` or ``'`` quotes.
   result = @[]
   var i = 0
   var a = ""
@@ -963,6 +963,7 @@ proc parseCmdLine*(c: string): seq[string] =
     while c[i] == ' ' or c[i] == '\t': inc(i)
     when defined(windows):
       # parse a single argument according to the above rules:
+      if c[i] == '\0': break
       var inQuote = false
       while true:
         case c[i]        
@@ -971,7 +972,7 @@ proc parseCmdLine*(c: string): seq[string] =
           var j = i
           while c[j] == '\\': inc(j)
           if c[j] == '"': 
-            for k in 0..(j-i) div 2: a.add('\\')
+            for k in 1..(j-i) div 2: a.add('\\')
             if (j-i) mod 2 == 0: 
               i = j
             else: 
diff --git a/lib/pure/times.nim b/lib/pure/times.nim
index 70cb038a7..da712263d 100755
--- a/lib/pure/times.nim
+++ b/lib/pure/times.nim
@@ -26,6 +26,19 @@ type
 when defined(posix): 
   type
     TTime* = distinct int ## distinct type that represents a time
+
+    Ttimeval {.importc: "struct timeval", header: "<sys/select.h>", 
+               final, pure.} = object ## struct timeval
+      tv_sec: int  ## Seconds. 
+      tv_usec: int ## Microseconds. 
+      
+  # we cannot import posix.nim here, because posix.nim depends on times.nim.
+  # Ok, we could, but I don't want circular dependencies. 
+  # And gettimeofday() is not defined in the posix module anyway. Sigh.
+  
+  proc posix_gettimeofday(tp: var Ttimeval, unused: pointer = nil) {.
+    importc: "gettimeofday", header: "<sys/time.h>".}
+
 elif defined(windows):
   when defined(vcc):
     # newest version of Visual C++ defines time_t to be of 64 bits
@@ -147,7 +160,7 @@ when not defined(ECMAScript):
     PTimeInfo = ptr structTM
     PTime = ptr TTime
   
-    TClock {.importc: "clock_t".} = range[low(int)..high(int)]
+    TClock {.importc: "clock_t".} = distinct int #range[low(int)..high(int)]
   
   proc localtime(timer: PTime): PTimeInfo {.
     importc: "localtime", header: "<time.h>".}
@@ -197,9 +210,17 @@ when not defined(ECMAScript):
     return toBiggestInt(difftime(a, b))
   
   proc getStartMilsecs(): int =
-    #echo "clocks per sec: ", clocksPerSec
+    #echo "clocks per sec: ", clocksPerSec, "clock: ", int(clock())
     #return clock() div (clocksPerSec div 1000)
-    result = toInt(toFloat(clock()) / (toFloat(clocksPerSec) / 1000.0))
+    when defined(posix):
+      var a: Ttimeval
+      posix_gettimeofday(a)
+      result = a.tv_sec * 1000 + a.tv_usec
+    else:
+      result = int(clock()) div (clocksPerSec div 1000)
+    when false:
+      when defined(macosx):
+        result = toInt(toFloat(clock()) / (toFloat(clocksPerSec) / 1000.0))
     
   proc getTime(): TTime = return timec(nil)
   proc getLocalTime(t: TTime): TTimeInfo =
diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim
index 099509afe..a43f66fa0 100755
--- a/lib/pure/unicode.nim
+++ b/lib/pure/unicode.nim
@@ -1176,3 +1176,5 @@ proc cmpRunesIgnoreCase*(a, b: string): int =
     if result != 0: return
   result = a.len - b.len
 
+proc substringAt*(s, sub: string, start: int): int = 
+  
diff --git a/lib/system.nim b/lib/system.nim
index a83812ed0..b34adf62a 100755
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -981,6 +981,9 @@ when not defined(NimrodVM):
   proc getCurrentExceptionMsg*(): string {.exportc.}
     ## retrieves the error message that was attached to the current
     ## exception; if there is none, "" is returned.
+  
+  proc getCurrentException*(): ref E_Base
+    ## retrieves the current exception; if there is none, nil is returned.
 
 # new constants:
 const
@@ -1390,6 +1393,13 @@ when not defined(EcmaScript) and not defined(NimrodVM):
     ##
     ## Default mode is readonly. Returns true iff the file could be opened.
 
+  proc reopen*(f: TFile, filename: string, mode: TFileMode = fmRead): bool
+    ## reopens the file `f` with given `filename` and `mode`. This 
+    ## is often used to redirect the `stdin`, `stdout` or `stderr`
+    ## file variables.
+    ##
+    ## Default mode is readonly. Returns true iff the file could be reopened.
+
   proc CloseFile*(f: TFile) {.importc: "fclose", nodecl, deprecated.}
     ## Closes the file.
     ## **Deprecated since version 0.8.0**: Use `close` instead.
@@ -1554,6 +1564,7 @@ when not defined(EcmaScript) and not defined(NimrodVM):
     else:
       result = n.sons[n.len]
 
+  include "system/systhread"
   include "system/mm"
   include "system/sysstr"
   include "system/assign"
@@ -1564,6 +1575,10 @@ when not defined(EcmaScript) and not defined(NimrodVM):
     if excHandler == nil: return ""
     return $excHandler.exc.msg
 
+  proc getCurrentException(): ref E_Base = 
+    if excHandler != nil: 
+      result = excHandler.exc
+
   {.push stack_trace: off.}
   when defined(endb):
     include "system/debugger"
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim
index 95feff854..0d3f52b2f 100755
--- a/lib/system/alloc.nim
+++ b/lib/system/alloc.nim
@@ -376,10 +376,10 @@ proc freeBigChunk(a: var TAllocator, c: PBigChunk) =
 
 proc splitChunk(a: var TAllocator, c: PBigChunk, size: int) = 
   var rest = cast[PBigChunk](cast[TAddress](c) +% size)
-  if rest in a.freeChunksList: 
-    c_fprintf(c_stdout, "to add: %p\n", rest)
-    writeFreeList(allocator)
-    assert false
+  assert(rest notin a.freeChunksList)
+  #  c_fprintf(c_stdout, "to add: %p\n", rest)
+  #  writeFreeList(allocator)
+  #  assert false
   rest.size = c.size - size
   rest.used = false
   rest.next = nil
diff --git a/lib/system/gc.nim b/lib/system/gc.nim
index da8f75768..1e9cd5a4a 100755
--- a/lib/system/gc.nim
+++ b/lib/system/gc.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nimrod's Runtime Library
-#        (c) Copyright 2009 Andreas Rumpf
+#        (c) Copyright 2010 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -478,6 +478,10 @@ proc gcMark(p: pointer) {.inline.} =
       cell.refcount = cell.refcount +% rcIncrement
       add(gch.decStack, cell)
 
+proc markThreadStacks(gch: var TGcHeap) = 
+  when isMultiThreaded:
+    nil
+
 # ----------------- stack management --------------------------------------
 #  inspired from Smart Eiffel
 
@@ -613,6 +617,7 @@ proc collectCT(gch: var TGcHeap) =
     gch.stat.maxStackSize = max(gch.stat.maxStackSize, stackSize())
     assert(gch.decStack.len == 0)
     markStackAndRegisters(gch)
+    markThreadStacks(gch)
     gch.stat.maxStackCells = max(gch.stat.maxStackCells, gch.decStack.len)
     inc(gch.stat.stackScans)
     collectZCT(gch)
diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim
index 3c99a5eed..1dcc2ab3a 100755
--- a/lib/system/sysio.nim
+++ b/lib/system/sysio.nim
@@ -27,6 +27,9 @@ proc strlen(c: cstring): int {.importc: "strlen", nodecl.}
 proc setvbuf(stream: TFile, buf: pointer, typ, size: cint): cint {.
   importc, nodecl.}
 
+proc freopen(path, mode: cstring, stream: TFile): TFile {.importc: "freopen",
+  nodecl.}
+
 proc write(f: TFile, c: cstring) = fputs(c, f)
 
 var
@@ -112,9 +115,7 @@ const
 proc Open(f: var TFile, filename: string,
           mode: TFileMode = fmRead,
           bufSize: int = -1): Bool =
-  var
-    p: pointer
-  p = fopen(filename, FormatOpen[mode])
+  var p: pointer = fopen(filename, FormatOpen[mode])
   result = (p != nil)
   f = cast[TFile](p)
   if bufSize > 0:
@@ -123,6 +124,10 @@ proc Open(f: var TFile, filename: string,
   elif bufSize == 0:
     discard setvbuf(f, nil, IONBF, 0)
 
+proc reopen(f: TFile, filename: string, mode: TFileMode = fmRead): bool = 
+  var p: pointer = freopen(filename, FormatOpen[mode], f)
+  result = p != nil
+
 proc fdopen(filehandle: TFileHandle, mode: cstring): TFile {.
   importc: pccHack & "fdopen", header: "<stdio.h>".}
 
diff --git a/lib/wrappers/sdl/sdl.nim b/lib/wrappers/sdl/sdl.nim
index a4c8273b8..9b3f960b6 100755
--- a/lib/wrappers/sdl/sdl.nim
+++ b/lib/wrappers/sdl/sdl.nim
@@ -278,7 +278,7 @@ elif defined(macosx):
     LibName = "libSDL-1.2.0.dylib"
 else: 
   const 
-    LibName = "libSDL.so"
+    LibName = "libSDL.so(|.1|.0)"
 const 
   MAJOR_VERSION* = 1'i8
   MINOR_VERSION* = 2'i8
diff --git a/lib/wrappers/sdl/sdl_ttf.nim b/lib/wrappers/sdl/sdl_ttf.nim
index ca4b56f5a..dd65af275 100755
--- a/lib/wrappers/sdl/sdl_ttf.nim
+++ b/lib/wrappers/sdl/sdl_ttf.nim
@@ -163,7 +163,7 @@ elif defined(macosx):
     ttfLibName = "libSDL_ttf-2.0.0.dylib"
 else: 
   const 
-    ttfLibName = "libSDL_ttf.so"
+    ttfLibName = "libSDL_ttf.so(|.1|.0)"
 const 
   MAJOR_VERSION* = 2'i8
   MINOR_VERSION* = 0'i8
diff --git a/rod/docgen.nim b/rod/docgen.nim
index 10516bf73..9da191d8d 100755
--- a/rod/docgen.nim
+++ b/rod/docgen.nim
@@ -417,23 +417,20 @@ proc renderRstToRst(d: PDoc, n: PRstNode): PRope =
   # debugging, but most code is already debugged...
   const 
     lvlToChar: array[0..8, char] = ['!', '=', '-', '~', '`', '<', '*', '|', '+']
-  var 
-    L: int
-    ind: PRope
   result = nil
   if n == nil: return 
-  ind = toRope(repeatChar(d.indent))
+  var ind = toRope(repeatChar(d.indent))
   case n.kind
   of rnInner: 
     result = renderRstSons(d, n)
   of rnHeadline: 
     result = renderRstSons(d, n)
-    L = ropeLen(result)
+    var L = ropeLen(result)
     result = ropef("$n$1$2$n$1$3", 
                    [ind, result, toRope(repeatChar(L, lvlToChar[n.level]))])
   of rnOverline: 
     result = renderRstSons(d, n)
-    L = ropeLen(result)
+    var L = ropeLen(result)
     result = ropef("$n$1$3$n$1$2$n$1$3", 
                    [ind, result, toRope(repeatChar(L, lvlToChar[n.level]))])
   of rnTransition: 
@@ -464,7 +461,7 @@ proc renderRstToRst(d: PDoc, n: PRstNode): PRope =
     dec(d.indent, 2)
   of rnField: 
     result = renderRstToRst(d, n.sons[0])
-    L = max(ropeLen(result) + 3, 30)
+    var L = max(ropeLen(result) + 3, 30)
     inc(d.indent, L)
     result = ropef("$n$1:$2:$3$4", [ind, result, toRope(
         repeatChar(L - ropeLen(result) - 2)), renderRstToRst(d, n.sons[1])])
diff --git a/rod/evals.nim b/rod/evals.nim
index 7306f61b1..4232bb832 100755
--- a/rod/evals.nim
+++ b/rod/evals.nim
@@ -714,8 +714,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
     var a = result
     result = newNodeIT(nkIntLit, n.info, n.typ)
     case a.kind
-    of nkEmpty..nkNilLit: 
-      nil
+    of nkEmpty..nkNilLit: nil
     else: result.intVal = sonsLen(a)
   of mNChild: 
     result = evalAux(c, n.sons[1], {efLValue})
diff --git a/rod/semexprs.nim b/rod/semexprs.nim
index 8d8b627eb..6ce1628d5 100755
--- a/rod/semexprs.nim
+++ b/rod/semexprs.nim
@@ -1022,8 +1022,6 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
     var s = qualifiedLookup(c, n.sons[0], false)
     if s != nil and s.kind in {skProc, skMethod, skConverter, skIterator}: 
       # type parameters: partial generic specialization
-      # XXX: too implement!
-      internalError(n.info, "explicit generic instantation not implemented")
       result = partialSpecialization(c, n, s)
     else: 
       result = semArrayAccess(c, n, flags)
diff --git a/rod/seminst.nim b/rod/seminst.nim
index ba1f05cb2..417922825 100755
--- a/rod/seminst.nim
+++ b/rod/seminst.nim
@@ -1,29 +1,28 @@
 #
 #
 #           The Nimrod Compiler
-#        (c) Copyright 2009 Andreas Rumpf
+#        (c) Copyright 2010 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
 #
+
 # This module does the instantiation of generic procs and types.
 
-proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, info: TLineInfo): PSym
+proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
+                      info: TLineInfo): PSym
   # generates an instantiated proc
 proc searchInstTypes(tab: TIdTable, key: PType): PType = 
-  var 
-    t: PType
-    match: bool
   # returns nil if we need to declare this type
   result = PType(IdTableGet(tab, key))
   if (result == nil) and (tab.counter > 0): 
     # we have to do a slow linear search because types may need
     # to be compared by their structure:
     for h in countup(0, high(tab.data)): 
-      t = PType(tab.data[h].key)
+      var t = PType(tab.data[h].key)
       if t != nil: 
         if key.containerId == t.containerID: 
-          match = true
+          var match = true
           for j in countup(0, sonsLen(t) - 1): 
             # XXX sameType is not really correct for nested generics?
             if not sameType(t.sons[j], key.sons[j]): 
@@ -39,20 +38,16 @@ proc containsGenericType(t: PType): bool =
   result = iterOverType(t, containsGenericTypeIter, nil)
 
 proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable) = 
-  var 
-    s, q: PSym
-    t: PType
-    a: PNode
   if (n.kind != nkGenericParams): 
     InternalError(n.info, "instantiateGenericParamList; no generic params")
   for i in countup(0, sonsLen(n) - 1): 
-    a = n.sons[i]
+    var a = n.sons[i]
     if a.kind != nkSym: 
       InternalError(a.info, "instantiateGenericParamList; no symbol")
-    q = a.sym
+    var q = a.sym
     if not (q.typ.kind in {tyTypeDesc, tyGenericParam}): continue 
-    s = newSym(skType, q.name, getCurrOwner())
-    t = PType(IdTableGet(pt, q.typ))
+    var s = newSym(skType, q.name, getCurrOwner())
+    var t = PType(IdTableGet(pt, q.typ))
     if t == nil: liMessage(a.info, errCannotInstantiateX, s.name.s)
     if (t.kind == tyGenericParam): 
       InternalError(a.info, "instantiateGenericParamList: " & q.name.s)
@@ -60,27 +55,26 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable) =
     addDecl(c, s)
 
 proc GenericCacheGet(c: PContext, genericSym, instSym: PSym): PSym = 
-  var a, b: PSym
   result = nil
   for i in countup(0, sonsLen(c.generics) - 1): 
     if c.generics.sons[i].kind != nkExprEqExpr: 
       InternalError(genericSym.info, "GenericCacheGet")
-    a = c.generics.sons[i].sons[0].sym
+    var a = c.generics.sons[i].sons[0].sym
     if genericSym.id == a.id: 
-      b = c.generics.sons[i].sons[1].sym
+      var b = c.generics.sons[i].sons[1].sym
       if equalParams(b.typ.n, instSym.typ.n) == paramsEqual: 
         #if gVerbosity > 0 then 
         #  MessageOut('found in cache: ' + getProcHeader(instSym));
         return b
 
 proc GenericCacheAdd(c: PContext, genericSym, instSym: PSym) = 
-  var n: PNode
-  n = newNode(nkExprEqExpr)
+  var n = newNode(nkExprEqExpr)
   addSon(n, newSymNode(genericSym))
   addSon(n, newSymNode(instSym))
   addSon(c.generics, n)
 
-proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, info: TLineInfo): PSym = 
+proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, 
+                      info: TLineInfo): PSym = 
   # generates an instantiated proc
   var 
     oldPrc, oldMod: PSym
@@ -89,8 +83,8 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, info: TLineInfo): PSy
   if c.InstCounter > 1000: InternalError(fn.ast.info, "nesting too deep")
   inc(c.InstCounter)
   oldP = c.p # restore later
-             # NOTE: for access of private fields within generics from a different module
-             # and other identifiers we fake the current module temporarily!
+  # NOTE: for access of private fields within generics from a different module
+  # and other identifiers we fake the current module temporarily!
   oldMod = c.module
   c.module = getModule(fn)
   result = copySym(fn, false)
@@ -151,8 +145,6 @@ type
 proc ReplaceTypeVarsT(cl: var TReplTypeVars, t: PType): PType
 proc ReplaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym
 proc ReplaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode = 
-  var length: int
-  result = nil
   if n != nil: 
     result = copyNode(n)
     result.typ = ReplaceTypeVarsT(cl, n.typ)
@@ -162,7 +154,7 @@ proc ReplaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode =
     of nkSym: 
       result.sym = ReplaceTypeVarsS(cl, n.sym)
     else: 
-      length = sonsLen(n)
+      var length = sonsLen(n)
       if length > 0: 
         newSons(result, length)
         for i in countup(0, length - 1): 
@@ -172,7 +164,7 @@ proc ReplaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym =
   if s == nil: 
     return nil
   result = PSym(idTableGet(cl.symMap, s))
-  if (result == nil): 
+  if result == nil: 
     result = copySym(s, false)
     incl(result.flags, sfFromGeneric)
     idTablePut(cl.symMap, s, result)
@@ -229,8 +221,9 @@ proc ReplaceTypeVarsT(cl: var TReplTypeVars, t: PType): PType =
         result.sons[i] = ReplaceTypeVarsT(cl, result.sons[i])
       result.n = ReplaceTypeVarsN(cl, result.n)
       if result.Kind in GenericTypes: 
-        liMessage(cl.info, errCannotInstantiateX, TypeToString(t, preferName)) #writeln(output, ropeToStr(Typetoyaml(result)));
-                                                                               #checkConstructedType(cl.info, result);
+        liMessage(cl.info, errCannotInstantiateX, TypeToString(t, preferName))
+        #writeln(output, ropeToStr(Typetoyaml(result)))
+        #checkConstructedType(cl.info, result)
   
 proc instGenericContainer(c: PContext, n: PNode, header: PType): PType = 
   var cl: TReplTypeVars
@@ -240,7 +233,8 @@ proc instGenericContainer(c: PContext, n: PNode, header: PType): PType =
   cl.c = c
   result = ReplaceTypeVarsT(cl, header)
 
-proc generateTypeInstance(p: PContext, pt: TIdTable, arg: PNode, t: PType): PType = 
+proc generateTypeInstance(p: PContext, pt: TIdTable, arg: PNode, 
+                          t: PType): PType = 
   var cl: TReplTypeVars
   InitIdTable(cl.symMap)
   copyIdTable(cl.typeMap, pt)
@@ -251,4 +245,9 @@ proc generateTypeInstance(p: PContext, pt: TIdTable, arg: PNode, t: PType): PTyp
   popInfoContext()
 
 proc partialSpecialization(c: PContext, n: PNode, s: PSym): PNode = 
+  for i in 1..sonsLen(n)-1:
+    n.sons[i].typ = semTypeNode(c, n.sons[i], nil)
+  # we cannot check for the proper number of type parameters because in
+  # `f[a,b](x, y)` `f` is not resolved yet properly.
+  # XXX: BUG this should be checked somehow!
   result = n
diff --git a/rod/semstmts.nim b/rod/semstmts.nim
index b07e724bc..0f96e5b94 100755
--- a/rod/semstmts.nim
+++ b/rod/semstmts.nim
@@ -6,6 +6,7 @@
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
 #
+
 # this module does the semantic checking of statements
 
 proc semExprNoType(c: PContext, n: PNode): PNode =
@@ -267,14 +268,13 @@ proc SemReturn(c: PContext, n: PNode): PNode =
       liMessage(n.info, errCannotReturnExpr)
   
 proc SemYield(c: PContext, n: PNode): PNode = 
-  var restype: PType
   result = n
   checkSonsLen(n, 1)
   if (c.p.owner == nil) or (c.p.owner.kind != skIterator): 
     liMessage(n.info, errYieldNotAllowedHere)
   if (n.sons[0] != nil): 
     n.sons[0] = SemExprWithType(c, n.sons[0]) # check for type compatibility:
-    restype = c.p.owner.typ.sons[0]
+    var restype = c.p.owner.typ.sons[0]
     if (restype != nil): 
       n.sons[0] = fitNode(c, restype, n.sons[0])
       if (n.sons[0].typ == nil): InternalError(n.info, "semYield")
@@ -477,6 +477,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
         s = newSymS(skType, a.sons[j], c)
         s.typ = newTypeS(tyGenericParam, c)
       else: 
+        # not a type param, but an expression
         s = newSymS(skGenericParam, a.sons[j], c)
         s.typ = typ
       s.ast = def
diff --git a/rod/semtypes.nim b/rod/semtypes.nim
index f4b17f071..a88490ce0 100755
--- a/rod/semtypes.nim
+++ b/rod/semtypes.nim
@@ -6,6 +6,7 @@
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
 #
+
 # this module does the semantic checking of type declarations
 
 proc fitNode(c: PContext, formal: PType, arg: PNode): PNode = 
@@ -63,10 +64,9 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
     inc(counter)
 
 proc semSet(c: PContext, n: PNode, prev: PType): PType = 
-  var base: PType
   result = newOrPrevType(tySet, prev, c)
   if sonsLen(n) == 2: 
-    base = semTypeNode(c, n.sons[1], nil)
+    var base = semTypeNode(c, n.sons[1], nil)
     addSon(result, base)
     if base.kind == tyGenericInst: base = lastSon(base)
     if base.kind != tyGenericParam: 
@@ -77,29 +77,26 @@ proc semSet(c: PContext, n: PNode, prev: PType): PType =
   
 proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string, 
                   prev: PType): PType = 
-  var base: PType
   result = newOrPrevType(kind, prev, c)
   if sonsLen(n) == 2: 
-    base = semTypeNode(c, n.sons[1], nil)
+    var base = semTypeNode(c, n.sons[1], nil)
     addSon(result, base)
   else: 
     liMessage(n.info, errXExpectsOneTypeParam, kindStr)
   
 proc semAnyRef(c: PContext, n: PNode, kind: TTypeKind, kindStr: string, 
                prev: PType): PType = 
-  var base: PType
   result = newOrPrevType(kind, prev, c)
   if sonsLen(n) == 1: 
-    base = semTypeNode(c, n.sons[0], nil)
+    var base = semTypeNode(c, n.sons[0], nil)
     addSon(result, base)
   else: 
     liMessage(n.info, errXExpectsOneTypeParam, kindStr)
   
 proc semVarType(c: PContext, n: PNode, prev: PType): PType = 
-  var base: PType
   result = newOrPrevType(tyVar, prev, c)
   if sonsLen(n) == 1: 
-    base = semTypeNode(c, n.sons[0], nil)
+    var base = semTypeNode(c, n.sons[0], nil)
     if base.kind == tyVar: liMessage(n.info, errVarVarTypeNotAllowed)
     addSon(result, base)
   else: 
@@ -111,15 +108,14 @@ proc semDistinct(c: PContext, n: PNode, prev: PType): PType =
   else: liMessage(n.info, errXExpectsOneTypeParam, "distinct")
   
 proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = 
-  var a, b: PNode
   if (n.kind != nkRange): InternalError(n.info, "semRangeAux")
   checkSonsLen(n, 2)
   result = newOrPrevType(tyRange, prev, c)
   result.n = newNodeI(nkRange, n.info)
   if (n.sons[0] == nil) or (n.sons[1] == nil): 
     liMessage(n.Info, errRangeIsEmpty)
-  a = semConstExpr(c, n.sons[0])
-  b = semConstExpr(c, n.sons[1])
+  var a = semConstExpr(c, n.sons[0])
+  var b = semConstExpr(c, n.sons[1])
   if not sameType(a.typ, b.typ): liMessage(n.info, errPureTypeMismatch)
   if not (a.typ.kind in
       {tyInt..tyInt64, tyEnum, tyBool, tyChar, tyFloat..tyFloat128}): 
@@ -159,10 +155,9 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType =
     liMessage(n.info, errArrayExpectsTwoTypeParams)
   
 proc semOrdinal(c: PContext, n: PNode, prev: PType): PType = 
-  var base: PType
   result = newOrPrevType(tyOrdinal, prev, c)
   if sonsLen(n) == 2: 
-    base = semTypeNode(c, n.sons[1], nil)
+    var base = semTypeNode(c, n.sons[1], nil)
     if base.kind != tyGenericParam: 
       if not isOrdinalType(base): 
         liMessage(n.sons[1].info, errOrdinalTypeExpected)
@@ -231,7 +226,7 @@ proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
                  allowed: TSymFlags): PSym = 
   # identifier with visibility
   if n.kind == nkPostfix: 
-    if (sonsLen(n) == 2) and (n.sons[0].kind == nkIdent): 
+    if sonsLen(n) == 2 and n.sons[0].kind == nkIdent: 
       result = newSymS(kind, n.sons[1], c)
       var v = n.sons[0].ident
       if (sfStar in allowed) and (v.id == ord(wStar)): 
@@ -426,7 +421,7 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType =
     base: PType
     pos: int
   IntSetInit(check)
-  pos = 0                     # n.sons[0] contains the pragmas (if any). We process these later...
+  pos = 0 # n.sons[0] contains the pragmas (if any). We process these later...
   checkSonsLen(n, 3)
   if n.sons[1] != nil: 
     base = semTypeNode(c, n.sons[1].sons[0], nil)
@@ -444,28 +439,30 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType =
   
 proc addTypeVarsOfGenericBody(c: PContext, t: PType, genericParams: PNode, 
                               cl: var TIntSet): PType = 
-  var 
-    L: int
-    s: PSym
   result = t
-  if (t == nil): return 
+  if t == nil: return 
   if IntSetContainsOrIncl(cl, t.id): return 
   case t.kind
   of tyGenericBody: 
+    #debug(t)
     result = newTypeS(tyGenericInvokation, c)
     addSon(result, t)
     for i in countup(0, sonsLen(t) - 2): 
       if t.sons[i].kind != tyGenericParam: 
         InternalError("addTypeVarsOfGenericBody")
-      s = copySym(t.sons[i].sym)
+      # do not declare ``TKey`` twice:
+      #if not IntSetContainsOrIncl(cl, t.sons[i].sym.ident.id):
+      var s = copySym(t.sons[i].sym)
       s.position = sonsLen(genericParams)
       addDecl(c, s)
       addSon(genericParams, newSymNode(s))
       addSon(result, t.sons[i])
   of tyGenericInst: 
-    L = sonsLen(t) - 1
+    #debug(t)
+    var L = sonsLen(t) - 1
     t.sons[L] = addTypeVarsOfGenericBody(c, t.sons[L], genericParams, cl)
   of tyGenericInvokation: 
+    #debug(t)
     for i in countup(1, sonsLen(t) - 1): 
       t.sons[i] = addTypeVarsOfGenericBody(c, t.sons[i], genericParams, cl)
   else: 
@@ -476,13 +473,12 @@ proc paramType(c: PContext, n, genericParams: PNode, cl: var TIntSet): PType =
   result = semTypeNode(c, n, nil)
   if (genericParams != nil) and (sonsLen(genericParams) == 0): 
     result = addTypeVarsOfGenericBody(c, result, genericParams, cl)
+    #if result.kind == tyGenericInvokation: debug(result)
   
 proc semProcTypeNode(c: PContext, n, genericParams: PNode, prev: PType): PType = 
   var 
-    length, counter: int
-    a, def, res: PNode
+    def, res: PNode
     typ: PType
-    arg: PSym
     check, cl: TIntSet
   checkMinSonsLen(n, 1)
   result = newOrPrevType(tyProc, prev, c)
@@ -491,27 +487,29 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, prev: PType): PType =
   if (genericParams != nil) and (sonsLen(genericParams) == 0): IntSetInit(cl)
   if n.sons[0] == nil: 
     addSon(result, nil)       # return type
-    addSon(result.n, newNodeI(nkType, n.info)) # BUGFIX: nkType must exist!
-                                               # XXX but it does not, if n.sons[paramsPos] == nil?
+    addSon(result.n, newNodeI(nkType, n.info)) 
+    # BUGFIX: nkType must exist!
+    # XXX but it does not, if n.sons[paramsPos] == nil?
   else: 
     addSon(result, nil)
     res = newNodeI(nkType, n.info)
     addSon(result.n, res)
   IntSetInit(check)
-  counter = 0
+  var counter = 0
   for i in countup(1, sonsLen(n) - 1): 
-    a = n.sons[i]
-    if (a.kind != nkIdentDefs): IllFormedAst(a)
+    var a = n.sons[i]
+    if a.kind != nkIdentDefs: IllFormedAst(a)
     checkMinSonsLen(a, 3)
-    length = sonsLen(a)
+    var length = sonsLen(a)
     if a.sons[length - 2] != nil: 
       typ = paramType(c, a.sons[length - 2], genericParams, cl)
     else: 
       typ = nil
     if a.sons[length - 1] != nil: 
-      def = semExprWithType(c, a.sons[length - 1]) # check type compability between def.typ and typ:
-      if (typ != nil): 
-        if (cmpTypes(typ, def.typ) < isConvertible): 
+      def = semExprWithType(c, a.sons[length - 1]) 
+      # check type compability between def.typ and typ:
+      if typ != nil: 
+        if cmpTypes(typ, def.typ) < isConvertible: 
           typeMismatch(a.sons[length - 1], typ, def.typ)
         def = fitNode(c, typ, def)
       else: 
@@ -519,7 +517,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, prev: PType): PType =
     else: 
       def = nil
     for j in countup(0, length - 3): 
-      arg = newSymS(skParam, a.sons[j], c)
+      var arg = newSymS(skParam, a.sons[j], c)
       arg.typ = typ
       arg.position = counter
       inc(counter)
@@ -600,21 +598,16 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
       markUsed(n, n.sym)
     else: 
       liMessage(n.info, errTypeExpected)
-  of nkObjectTy: 
-    result = semObjectNode(c, n, prev)
-  of nkTupleTy: 
-    result = semTuple(c, n, prev)
-  of nkRefTy: 
-    result = semAnyRef(c, n, tyRef, "ref", prev)
-  of nkPtrTy: 
-    result = semAnyRef(c, n, tyPtr, "ptr", prev)
-  of nkVarTy: 
-    result = semVarType(c, n, prev)
-  of nkDistinctTy: 
-    result = semDistinct(c, n, prev)
+  of nkObjectTy: result = semObjectNode(c, n, prev)
+  of nkTupleTy: result = semTuple(c, n, prev)
+  of nkRefTy: result = semAnyRef(c, n, tyRef, "ref", prev)
+  of nkPtrTy: result = semAnyRef(c, n, tyPtr, "ptr", prev)
+  of nkVarTy: result = semVarType(c, n, prev)
+  of nkDistinctTy: result = semDistinct(c, n, prev)
   of nkProcTy: 
     checkSonsLen(n, 2)
-    result = semProcTypeNode(c, n.sons[0], nil, prev) # dummy symbol for `pragma`:
+    result = semProcTypeNode(c, n.sons[0], nil, prev) 
+    # dummy symbol for `pragma`:
     s = newSymS(skProc, newIdentNode(getIdent("dummy"), n.info), c)
     s.typ = result
     pragma(c, s, n.sons[1], procTypePragmas)
@@ -636,49 +629,33 @@ proc setMagicType(m: PSym, kind: TTypeKind, size: int) =
   
 proc processMagicType(c: PContext, m: PSym) = 
   case m.magic                #registerSysType(m.typ);
-  of mInt: 
-    setMagicType(m, tyInt, intSize)
-  of mInt8: 
-    setMagicType(m, tyInt8, 1)
-  of mInt16: 
-    setMagicType(m, tyInt16, 2)
-  of mInt32: 
-    setMagicType(m, tyInt32, 4)
-  of mInt64: 
-    setMagicType(m, tyInt64, 8)
-  of mFloat: 
-    setMagicType(m, tyFloat, floatSize)
-  of mFloat32: 
-    setMagicType(m, tyFloat32, 4)
-  of mFloat64: 
-    setMagicType(m, tyFloat64, 8)
-  of mBool: 
-    setMagicType(m, tyBool, 1)
-  of mChar: 
-    setMagicType(m, tyChar, 1)
+  of mInt: setMagicType(m, tyInt, intSize)
+  of mInt8: setMagicType(m, tyInt8, 1)
+  of mInt16: setMagicType(m, tyInt16, 2)
+  of mInt32: setMagicType(m, tyInt32, 4)
+  of mInt64: setMagicType(m, tyInt64, 8)
+  of mFloat: setMagicType(m, tyFloat, floatSize)
+  of mFloat32: setMagicType(m, tyFloat32, 4)
+  of mFloat64: setMagicType(m, tyFloat64, 8)
+  of mBool: setMagicType(m, tyBool, 1)
+  of mChar: setMagicType(m, tyChar, 1)
   of mString: 
     setMagicType(m, tyString, ptrSize)
     addSon(m.typ, getSysType(tyChar))
   of mCstring: 
     setMagicType(m, tyCString, ptrSize)
     addSon(m.typ, getSysType(tyChar))
-  of mPointer: 
-    setMagicType(m, tyPointer, ptrSize)
+  of mPointer: setMagicType(m, tyPointer, ptrSize)
   of mEmptySet: 
     setMagicType(m, tySet, 1)
     addSon(m.typ, newTypeS(tyEmpty, c))
   of mIntSetBaseType: 
     setMagicType(m, tyRange, intSize) #intSetBaseType := m.typ;
     return 
-  of mNil: 
-    setMagicType(m, tyNil, ptrSize)
-  of mExpr: 
-    setMagicType(m, tyExpr, 0)
-  of mStmt: 
-    setMagicType(m, tyStmt, 0)
-  of mTypeDesc: 
-    setMagicType(m, tyTypeDesc, 0)
-  of mArray, mOpenArray, mRange, mSet, mSeq, mOrdinal: 
-    return 
+  of mNil: setMagicType(m, tyNil, ptrSize)
+  of mExpr: setMagicType(m, tyExpr, 0)
+  of mStmt: setMagicType(m, tyStmt, 0)
+  of mTypeDesc: setMagicType(m, tyTypeDesc, 0)
+  of mArray, mOpenArray, mRange, mSet, mSeq, mOrdinal: return 
   else: liMessage(m.info, errTypeExpected)
   
diff --git a/rod/sigmatch.nim b/rod/sigmatch.nim
index 0698bf18d..a1b322d86 100755
--- a/rod/sigmatch.nim
+++ b/rod/sigmatch.nim
@@ -30,7 +30,7 @@ type
   TTypeRelation = enum        # order is important!
     isNone, isConvertible, isIntConv, isSubtype, isGeneric, isEqual
 
-proc initCandidate(c: var TCandidate, callee: PType) = 
+proc initCandidateAux(c: var TCandidate, callee: PType) {.inline.} = 
   c.exactMatches = 0
   c.subtypeMatches = 0
   c.convMatches = 0
@@ -38,11 +38,25 @@ proc initCandidate(c: var TCandidate, callee: PType) =
   c.genericMatches = 0
   c.state = csEmpty
   c.callee = callee
-  c.calleeSym = nil
   c.call = nil
   c.baseTypeMatch = false
-  initIdTable(c.bindings)     #assert(c.callee <> nil);
-  
+
+proc initCandidate(c: var TCandidate, callee: PType) = 
+  initCandidateAux(c, callee)
+  c.calleeSym = nil
+  initIdTable(c.bindings)
+
+proc initCandidate(c: var TCandidate, callee: PSym, binding: PNode) = 
+  initCandidateAux(c, callee.typ)
+  c.calleeSym = callee
+  initIdTable(c.bindings)
+  if binding != nil:
+    var typeParams = callee.ast[genericParamsPos]
+    for i in 1..min(sonsLen(typeParams), sonsLen(binding)-1):
+      var formalTypeParam = typeParams.sons[i-1].typ
+      #debug(formalTypeParam)
+      IdTablePut(c.bindings, formalTypeParam, binding[i].typ)
+
 proc copyCandidate(a: var TCandidate, b: TCandidate) = 
   a.exactMatches = b.exactMatches
   a.subtypeMatches = b.subtypeMatches
@@ -326,7 +340,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
     case a.kind
     of tyPointer: result = isEqual
     of tyNil: result = isSubtype
-    of tyRef, tyPtr, tyProc, tyCString: result = isConvertible
+    of tyPtr, tyProc, tyCString: result = isConvertible
     else: nil
   of tyString: 
     case a.kind
@@ -664,21 +678,20 @@ proc sameMethodDispatcher(a, b: PSym): bool =
     if aa.kind == nkSym and bb.kind == nkSym and aa.sym == bb.sym: 
       result = true
   
-proc semDirectCall(c: PContext, n: PNode, filter: TSymKinds): PNode = 
-  var 
+proc semDirectCallWithBinding(c: PContext, n, f: PNode, filter: TSymKinds,
+                              initialBinding: PNode): PNode = 
+  var
     o: TOverloadIter
     x, y, z: TCandidate
   #liMessage(n.info, warnUser, renderTree(n));
-  var sym = initOverloadIter(o, c, n.sons[0])
+  var sym = initOverloadIter(o, c, f)
   result = nil
   if sym == nil: return 
-  initCandidate(x, sym.typ)
-  x.calleeSym = sym
-  initCandidate(y, sym.typ)
-  y.calleeSym = sym
+  initCandidate(x, sym, initialBinding)
+  initCandidate(y, sym, initialBinding)
   while sym != nil: 
     if sym.kind in filter: 
-      initCandidate(z, sym.typ)
+      initCandidate(z, sym, initialBinding)
       z.calleeSym = sym
       matches(c, n, z)
       if z.state == csMatch: 
@@ -689,7 +702,7 @@ proc semDirectCall(c: PContext, n: PNode, filter: TSymKinds): PNode =
           if cmp < 0: x = z # z is better than x
           elif cmp == 0: y = z # z is as good as x
           else: nil
-    sym = nextOverloadIter(o, c, n.sons[0])
+    sym = nextOverloadIter(o, c, f)
   if x.state == csEmpty: 
     # no overloaded proc found
     # do not generate an error yet; the semantic checking will check for
@@ -714,3 +727,16 @@ proc semDirectCall(c: PContext, n: PNode, filter: TSymKinds): PNode =
     result = x.call
     result.sons[0] = newSymNode(x.calleeSym)
     result.typ = x.callee.sons[0]
+        
+proc semDirectCall(c: PContext, n: PNode, filter: TSymKinds): PNode = 
+  # process the bindings once:
+  var initialBinding: PNode
+  var f = n.sons[0]
+  if f.kind == nkBracketExpr:
+    # fill in the bindings:
+    initialBinding = f
+    f = f.sons[0]
+  else: 
+    initialBinding = nil
+  result = semDirectCallWithBinding(c, n, f, filter, initialBinding)
+
diff --git a/rod/transf.nim b/rod/transf.nim
index ac746f834..16c279c80 100755
--- a/rod/transf.nim
+++ b/rod/transf.nim
@@ -63,55 +63,55 @@ proc newTemp(c: PTransf, typ: PType, info: TLineInfo): PSym =
   incl(result.flags, sfFromGeneric)
 
 proc transform(c: PTransf, n: PNode): PNode
-  #
-  #
-  #Transforming iterators into non-inlined versions is pretty hard, but
-  #unavoidable for not bloating the code too much. If we had direct access to
-  #the program counter, things'd be much easier.
-  #::
-  #
-  #  iterator items(a: string): char =
-  #    var i = 0
-  #    while i < length(a):
-  #      yield a[i]
-  #      inc(i)
-  #
-  #  for ch in items("hello world"): # `ch` is an iteration variable
-  #    echo(ch)
-  #
-  #Should be transformed into::
-  #
-  #  type
-  #    TItemsClosure = record
-  #      i: int
-  #      state: int
-  #  proc items(a: string, c: var TItemsClosure): char =
-  #    case c.state
-  #    of 0: goto L0 # very difficult without goto!
-  #    of 1: goto L1 # can be implemented by GCC's computed gotos
-  #
-  #    block L0:
-  #      c.i = 0
-  #      while c.i < length(a):
-  #        c.state = 1
-  #        return a[i]
-  #        block L1: inc(c.i)
-  #
-  #More efficient, but not implementable::
-  #
-  #  type
-  #    TItemsClosure = record
-  #      i: int
-  #      pc: pointer
-  #
-  #  proc items(a: string, c: var TItemsClosure): char =
-  #    goto c.pc
-  #    c.i = 0
-  #    while c.i < length(a):
-  #      c.pc = label1
-  #      return a[i]
-  #      label1: inc(c.i)
-  #
+
+# Transforming iterators into non-inlined versions is pretty hard, but
+# unavoidable for not bloating the code too much. If we had direct access to
+# the program counter, things'd be much easier.
+# ::
+#
+#  iterator items(a: string): char =
+#    var i = 0
+#    while i < length(a):
+#      yield a[i]
+#      inc(i)
+#
+#  for ch in items("hello world"): # `ch` is an iteration variable
+#    echo(ch)
+#
+# Should be transformed into::
+#
+#  type
+#    TItemsClosure = record
+#      i: int
+#      state: int
+#  proc items(a: string, c: var TItemsClosure): char =
+#    case c.state
+#    of 0: goto L0 # very difficult without goto!
+#    of 1: goto L1 # can be implemented by GCC's computed gotos
+#
+#    block L0:
+#      c.i = 0
+#      while c.i < length(a):
+#        c.state = 1
+#        return a[i]
+#        block L1: inc(c.i)
+#
+# More efficient, but not implementable::
+#
+#  type
+#    TItemsClosure = record
+#      i: int
+#      pc: pointer
+#
+#  proc items(a: string, c: var TItemsClosure): char =
+#    goto c.pc
+#    c.i = 0
+#    while c.i < length(a):
+#      c.pc = label1
+#      return a[i]
+#      label1: inc(c.i)
+#
+
 proc newAsgnStmt(c: PTransf, le, ri: PNode): PNode = 
   result = newNodeI(nkFastAsgn, ri.info)
   addSon(result, le)
@@ -290,8 +290,8 @@ proc transformConv(c: PTransf, n: PNode): PNode =
     if not isOrdinalType(source):
       # XXX int64 -> float conversion?
       result = n
-    elif (firstOrd(dest) <= firstOrd(source)) and
-        (lastOrd(source) <= lastOrd(dest)): 
+    elif firstOrd(dest) <= firstOrd(source) and
+        lastOrd(source) <= lastOrd(dest): 
       # BUGFIX: simply leave n as it is; we need a nkConv node,
       # but no range check:
       result = n
@@ -540,8 +540,8 @@ proc getMergeOp(n: PNode): PSym =
 
 proc flattenTreeAux(d, a: PNode, op: PSym) = 
   var op2 = getMergeOp(a)
-  if (op2 != nil) and
-      ((op2.id == op.id) or (op.magic != mNone) and (op2.magic == op.magic)): 
+  if op2 != nil and
+      (op2.id == op.id or op.magic != mNone and op2.magic == op.magic): 
     for i in countup(1, sonsLen(a) - 1): flattenTreeAux(d, a.sons[i], op)
   else: 
     addSon(d, copyTree(a))
diff --git a/tests/accept/run/spec.csv b/tests/accept/run/spec.csv
index d537c139f..f176b5645 100755
--- a/tests/accept/run/spec.csv
+++ b/tests/accept/run/spec.csv
@@ -17,6 +17,7 @@ tcnstseq.nim;AngelikaAnneAnnaAnkaAnja
 tconstr2.nim;69
 tcopy.nim;TEMP=C:\Programs\xyz\bin
 tcurrncy.nim;25
+texplicitgeneric1.nim;Key: 12 value: 12Key: 13 value: 13 Key: A value: 12 Key: B value: 13
 tfinally.nim;came here
 tfloat1.nim;Error: unhandled exception: FPU operation caused an overflow [EFloatOverflow]
 tfloat2.nim;Error: unhandled exception: FPU operation caused a NaN result [EFloatInvalidOp]
diff --git a/web/news.txt b/web/news.txt
index 94ba076b7..7de119d34 100755
--- a/web/news.txt
+++ b/web/news.txt
@@ -10,6 +10,13 @@ Bugfixes
 
 - Bugfix: Command line parsing on Windows and ``os.parseCmdLine`` now adheres
   to the same parsing rules as Microsoft's C/C++ startup code.
+- Bugfix: Passing a ``ref`` pointer to the untyped ``pointer`` type is invalid.
+- Bugfix: Updated ``keyval`` example.
+- Bugfix: ``system.splitChunk`` still contained code for debug output.
+- Bugfix: ``times.getStartMilsecs`` uses ``gettimeofday`` for Posix times. It
+  used to use ``clock`` which has the wrong semantics.
+- Bugfix: ``dialogs.ChooseFileToSave`` uses ``STOCK_SAVE`` instead of 
+  ``STOCK_OPEN`` for the GTK backend.
 
 
 Changes affecting backwards compatibility
@@ -24,6 +31,10 @@ Additions
 
 - The ``{.compile: "file.c".}`` pragma uses a CRC check to see if the file 
   needs to be recompiled.
+- Added ``system.reopen``. 
+- Added ``system.getCurrentException``.
+- Implemented explicit type arguments for generics.
+- Implemented implicit type arguments for generics.
 
 
 2010-03-14 Version 0.8.8 released