summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ast.nim4
-rw-r--r--compiler/commands.nim4
-rw-r--r--compiler/lexer.nim6
-rw-r--r--compiler/options.nim1
-rw-r--r--compiler/parser.nim55
-rw-r--r--compiler/pragmas.nim8
-rw-r--r--compiler/sem.nim3
-rw-r--r--compiler/semdata.nim5
-rw-r--r--compiler/semexprs.nim2
-rw-r--r--compiler/semstmts.nim21
-rw-r--r--compiler/wordrecg.nim9
-rw-r--r--doc/advopt.txt1
-rw-r--r--doc/gc.txt3
-rw-r--r--doc/grammar.txt26
-rw-r--r--doc/keywords.txt2
-rw-r--r--doc/manual/pragmas.txt18
-rw-r--r--doc/manual/stmts.txt3
-rw-r--r--doc/manual/syntax.txt50
-rw-r--r--lib/core/locks.nim21
-rw-r--r--lib/core/macros.nim2
-rw-r--r--lib/core/typeinfo.nim9
-rw-r--r--lib/impure/db_mysql.nim7
-rw-r--r--lib/packages/docutils/highlite.nim5
-rw-r--r--lib/pure/parseutils.nim95
-rw-r--r--lib/system.nim16
-rw-r--r--lib/system/platforms.nim74
-rw-r--r--lib/system/sysstr.nim4
-rw-r--r--lib/windows/windows.nim10
-rw-r--r--todo.txt5
-rw-r--r--web/news.txt6
30 files changed, 267 insertions, 208 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 62f2d105f..8ebe5afa6 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -160,6 +160,7 @@ type
     nkConstDef,           # a const definition
     nkTypeDef,            # a type definition
     nkYieldStmt,          # the yield statement as a tree
+    nkDefer,              # the 'defer' statement
     nkTryStmt,            # a try statement
     nkFinally,            # a finally section
     nkRaiseStmt,          # a raise statement
@@ -293,6 +294,7 @@ const
                        # require RC ops
   sfCompileToCpp* = sfInfixCall       # compile the module as C++ code
   sfCompileToObjc* = sfNamedParamCall # compile the module as Objective-C code
+  sfExperimental* = sfOverriden       # module uses the .experimental switch
 
 const
   # getting ready for the future expr/stmt merge
@@ -566,7 +568,7 @@ type
     mBool, mChar, mString, mCstring,
     mPointer, mEmptySet, mIntSetBaseType, mNil, mExpr, mStmt, mTypeDesc,
     mVoidType, mPNimrodNode, mShared, mGuarded, mLock, mSpawn, mDeepCopy,
-    mIsMainModule, mCompileDate, mCompileTime, mProcCall, 
+    mIsMainModule, mCompileDate, mCompileTime, mProcCall,
     mCpuEndian, mHostOS, mHostCPU, mAppType,
     mNaN, mInf, mNegInf,
     mCompileOption, mCompileOptionArg,
diff --git a/compiler/commands.nim b/compiler/commands.nim
index f26d1d6c7..a5b0b40d7 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -226,6 +226,7 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
   of "tlsemulation": result = contains(gGlobalOptions, optTlsEmulation)
   of "implicitstatic": result = contains(gOptions, optImplicitStatic)
   of "patterns": result = contains(gOptions, optPatterns)
+  of "experimental": result = gExperimentalMode
   else: invalidCmdLineOption(passCmd1, switch, info)
   
 proc processPath(path: string, notRelativeToProj = false): string =
@@ -568,6 +569,9 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
     of "none": idents.firstCharIsCS = false
     else: localError(info, errGenerated,
       "'partial' or 'none' expected, but found " & arg)
+  of "experimental":
+    expectNoArg(switch, arg, pass, info)
+    gExperimentalMode = true
   else:
     if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
     else: invalidCmdLineOption(pass, switch, info)
diff --git a/compiler/lexer.nim b/compiler/lexer.nim
index dbeec8acf..fb74f27d6 100644
--- a/compiler/lexer.nim
+++ b/compiler/lexer.nim
@@ -35,7 +35,8 @@ type
     tkSymbol, # keywords:
     tkAddr, tkAnd, tkAs, tkAsm, tkAtomic, 
     tkBind, tkBlock, tkBreak, tkCase, tkCast, 
-    tkConst, tkContinue, tkConverter, tkDiscard, tkDistinct, tkDiv, tkDo,
+    tkConst, tkContinue, tkConverter,
+    tkDefer, tkDiscard, tkDistinct, tkDiv, tkDo,
     tkElif, tkElse, tkEnd, tkEnum, tkExcept, tkExport,
     tkFinally, tkFor, tkFrom,
     tkGeneric, tkIf, tkImport, tkIn, tkInclude, tkInterface, 
@@ -71,7 +72,8 @@ const
     "tkSymbol",
     "addr", "and", "as", "asm", "atomic", 
     "bind", "block", "break", "case", "cast", 
-    "const", "continue", "converter", "discard", "distinct", "div", "do",
+    "const", "continue", "converter",
+    "defer", "discard", "distinct", "div", "do",
     "elif", "else", "end", "enum", "except", "export",
     "finally", "for", "from", "generic", "if", 
     "import", "in", "include", "interface", "is", "isnot", "iterator",
diff --git a/compiler/options.nim b/compiler/options.nim
index 838f99f8e..415ac8430 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -115,6 +115,7 @@ var
                               # the tracked source X, saved by the CAAS client.
   gDirtyOriginalIdx* = 0'i32  # the original source file of the dirtified buffer.
   gNoNimblePath* = false
+  gExperimentalMode*: bool
 
 proc importantComments*(): bool {.inline.} = gCmd in {cmdDoc, cmdIdeTools}
 proc usesNativeGC*(): bool {.inline.} = gSelectedGC >= gcRefc
diff --git a/compiler/parser.nim b/compiler/parser.nim
index e4de75a07..a91760e15 100644
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -188,18 +188,13 @@ proc parseTypeDesc(p: var TParser): PNode
 proc parseDoBlocks(p: var TParser, call: PNode)
 proc parseParamList(p: var TParser, retColon = true): PNode
 
-proc relevantOprChar(ident: PIdent): char {.inline.} =
-  result = ident.s[0]
-  var L = ident.s.len
-  if result == '\\' and L > 1:
-    result = ident.s[1]
-
 proc isSigilLike(tok: TToken): bool {.inline.} =
-  result = tok.tokType == tkOpr and relevantOprChar(tok.ident) == '@'
+  result = tok.tokType == tkOpr and tok.ident.s[0] == '@'
 
-proc isLeftAssociative(tok: TToken): bool {.inline.} =
-  ## Determines whether the token is left assocative.
-  result = tok.tokType != tkOpr or relevantOprChar(tok.ident) != '^'
+proc isRightAssociative(tok: TToken): bool {.inline.} =
+  ## Determines whether the token is right assocative.
+  result = tok.tokType == tkOpr and (tok.ident.s[0] == '^' or
+    (let L = tok.ident.s.len; L > 1 and tok.ident.s[L-1] == '>'))
 
 proc getPrecedence(tok: TToken, strongSpaces: bool): int =
   ## Calculates the precedence of the given token.
@@ -209,7 +204,10 @@ proc getPrecedence(tok: TToken, strongSpaces: bool): int =
   case tok.tokType
   of tkOpr:
     let L = tok.ident.s.len
-    let relevantChar = relevantOprChar(tok.ident)
+    let relevantChar = tok.ident.s[0]
+
+    # arrow like?
+    if L > 1 and tok.ident.s[L-1] == '>': return considerStrongSpaces(1)
     
     template considerAsgn(value: expr) =
       result = if tok.ident.s[L-1] == '=': 1 else: considerStrongSpaces(value)
@@ -269,17 +267,18 @@ proc checkBinary(p: TParser) {.inline.} =
 #| 
 #| optInd = COMMENT?
 #| optPar = (IND{>} | IND{=})?
-#| 
-#| simpleExpr = assignExpr (OP0 optInd assignExpr)*
-#| assignExpr = orExpr (OP1 optInd orExpr)*
-#| orExpr = andExpr (OP2 optInd andExpr)*
-#| andExpr = cmpExpr (OP3 optInd cmpExpr)*
-#| cmpExpr = sliceExpr (OP4 optInd sliceExpr)*
-#| sliceExpr = ampExpr (OP5 optInd ampExpr)*
-#| ampExpr = plusExpr (OP6 optInd plusExpr)*
-#| plusExpr = mulExpr (OP7 optInd mulExpr)*
-#| mulExpr = dollarExpr (OP8 optInd dollarExpr)*
-#| dollarExpr = primary (OP9 optInd primary)*
+#|
+#| simpleExpr = arrowExpr (OP0 optInd arrowExpr)*
+#| arrowExpr = assignExpr (OP1 optInd assignExpr)*
+#| assignExpr = orExpr (OP2 optInd orExpr)*
+#| orExpr = andExpr (OP3 optInd andExpr)*
+#| andExpr = cmpExpr (OP4 optInd cmpExpr)*
+#| cmpExpr = sliceExpr (OP5 optInd sliceExpr)*
+#| sliceExpr = ampExpr (OP6 optInd ampExpr)*
+#| ampExpr = plusExpr (OP7 optInd plusExpr)*
+#| plusExpr = mulExpr (OP8 optInd mulExpr)*
+#| mulExpr = dollarExpr (OP9 optInd dollarExpr)*
+#| dollarExpr = primary (OP10 optInd primary)*
 
 proc colcom(p: var TParser, n: PNode) =
   eat(p, tkColon)
@@ -734,7 +733,7 @@ proc parseOperators(p: var TParser, headNode: PNode,
   # the operator itself must not start on a new line:
   while opPrec >= limit and p.tok.indent < 0 and not isUnary(p):
     checkBinary(p)
-    var leftAssoc = ord(isLeftAssociative(p.tok))
+    var leftAssoc = 1-ord(isRightAssociative(p.tok))
     var a = newNodeP(nkInfix, p)
     var opNode = newIdentNodeP(p.tok.ident, p) # skip operator:
     getTok(p)
@@ -1423,9 +1422,10 @@ proc parseBlock(p: var TParser): PNode =
   colcom(p, result)
   addSon(result, parseStmt(p))
 
-proc parseStatic(p: var TParser): PNode =
+proc parseStaticOrDefer(p: var TParser; k: TNodeKind): PNode =
   #| staticStmt = 'static' colcom stmt
-  result = newNodeP(nkStaticStmt, p)
+  #| deferStmt = 'defer' colcom stmt
+  result = newNodeP(k, p)
   getTokNoInd(p)
   colcom(p, result)
   addSon(result, parseStmt(p))
@@ -1863,7 +1863,7 @@ proc simpleStmt(p: var TParser): PNode =
 proc complexOrSimpleStmt(p: var TParser): PNode =
   #| complexOrSimpleStmt = (ifStmt | whenStmt | whileStmt
   #|                     | tryStmt | finallyStmt | exceptStmt | forStmt
-  #|                     | blockStmt | staticStmt | asmStmt
+  #|                     | blockStmt | staticStmt | deferStmt | asmStmt
   #|                     | 'proc' routine
   #|                     | 'method' routine
   #|                     | 'iterator' routine
@@ -1884,7 +1884,8 @@ proc complexOrSimpleStmt(p: var TParser): PNode =
   of tkExcept: result = parseExceptBlock(p, nkExceptBranch)
   of tkFor: result = parseFor(p)
   of tkBlock: result = parseBlock(p)
-  of tkStatic: result = parseStatic(p)
+  of tkStatic: result = parseStaticOrDefer(p, nkStaticStmt)
+  of tkDefer: result = parseStaticOrDefer(p, nkDefer)
   of tkAsm: result = parseAsm(p)
   of tkProc: result = parseRoutine(p, nkProcDef)
   of tkMethod: result = parseRoutine(p, nkMethodDef)
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index b548837fe..879950e79 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -45,7 +45,7 @@ const
     wBreakpoint, wWatchPoint, wPassl, wPassc, wDeadCodeElim, wDeprecated,
     wFloatchecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
     wLinearScanEnd, wPatterns, wEffects, wNoForward, wComputedGoto,
-    wInjectStmt, wDeprecated}
+    wInjectStmt, wDeprecated, wExperimental}
   lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, 
     wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader, 
     wDeprecated, wExtern, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame,
@@ -850,6 +850,12 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
             localError(it.info, errExprExpected)
           else: 
             it.sons[1] = c.semExpr(c, it.sons[1])
+        of wExperimental:
+          noVal(it)
+          if isTopLevel(c):
+            c.module.flags.incl sfExperimental
+          else:
+            localError(it.info, "'experimental' pragma only valid as toplevel statement") 
         else: invalidPragma(it)
       else: invalidPragma(it)
   else: processNote(c, it)
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 5b31129a5..5160af20a 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -133,9 +133,6 @@ proc commonType*(x, y: PType): PType =
         result = newType(k, r.owner)
         result.addSonSkipIntLit(r)
 
-proc isTopLevel(c: PContext): bool {.inline.} = 
-  result = c.currentScope.depthLevel <= 2
-
 proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym = 
   result = newSym(kind, considerQuotedIdent(n), getCurrOwner(), n.info)
 
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index 921e87d30..f876770c0 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -312,3 +312,8 @@ proc checkSonsLen*(n: PNode, length: int) =
 proc checkMinSonsLen*(n: PNode, length: int) = 
   if sonsLen(n) < length: illFormedAst(n)
 
+proc isTopLevel*(c: PContext): bool {.inline.} = 
+  result = c.currentScope.depthLevel <= 2
+
+proc experimentalMode*(c: PContext): bool {.inline.} =
+  result = gExperimentalMode or sfExperimental in c.module.flags
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 108e21369..ac82e9fed 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1433,6 +1433,8 @@ proc newAnonSym(kind: TSymKind, info: TLineInfo,
 
 proc semUsing(c: PContext, n: PNode): PNode =
   result = newNodeI(nkEmpty, n.info)
+  if not experimentalMode(c):
+    localError(n.info, "use the {.experimental.} pragma to enable 'using'")
   for e in n.sons:
     let usedSym = semExpr(c, e)
     if usedSym.kind == nkSym:
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index c6906d98e..933ac7daf 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -1362,8 +1362,9 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
   #                                         nkNilLit, nkEmpty}:
   #  dec last
   for i in countup(0, length - 1):
-    case n.sons[i].kind
-    of nkFinally, nkExceptBranch:
+    let k = n.sons[i].kind
+    case k
+    of nkFinally, nkExceptBranch, nkDefer:
       # stand-alone finally and except blocks are
       # transformed into regular try blocks:
       #
@@ -1372,12 +1373,24 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
       # ...                       |   ...
       #                           | finally:
       #                           |   fclose(f)
+      var deferPart: PNode
+      if k == nkDefer:
+        deferPart = newNodeI(nkFinally, n.sons[i].info)
+        deferPart.add n.sons[i].sons[0]
+      elif k == nkFinally:
+        message(n.info, warnDeprecated,
+                "use 'defer'; standalone 'finally'")
+        deferPart = n.sons[i]
+      else:
+        message(n.info, warnDeprecated,
+                "use an explicit 'try'; standalone 'except'")
+        deferPart = n.sons[i]
       var tryStmt = newNodeI(nkTryStmt, n.sons[i].info)
       var body = newNodeI(nkStmtList, n.sons[i].info)
       if i < n.sonsLen - 1:
         body.sons = n.sons[(i+1)..(-1)]
       tryStmt.addSon(body)
-      tryStmt.addSon(n.sons[i])
+      tryStmt.addSon(deferPart)
       n.sons[i] = semTry(c, tryStmt)
       n.sons.setLen(i+1)
       return
@@ -1424,7 +1437,7 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
     # a statement list (s; e) has the type 'e':
     if result.kind == nkStmtList and result.len > 0:
       var lastStmt = lastSon(result)
-      if lastStmt.kind != nkNilLit and not ImplicitlyDiscardable(lastStmt):
+      if lastStmt.kind != nkNilLit and not implicitlyDiscardable(lastStmt):
         result.typ = lastStmt.typ
         #localError(lastStmt.info, errGenerated,
         #  "Last expression must be explicitly returned if it " &
diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim
index 068f59c71..f08ab0ad9 100644
--- a/compiler/wordrecg.nim
+++ b/compiler/wordrecg.nim
@@ -24,7 +24,7 @@ type
     
     wAddr, wAnd, wAs, wAsm, wAtomic, 
     wBind, wBlock, wBreak, wCase, wCast, wConst, 
-    wContinue, wConverter, wDiscard, wDistinct, wDiv, wDo, 
+    wContinue, wConverter, wDefer, wDiscard, wDistinct, wDiv, wDo, 
     wElif, wElse, wEnd, wEnum, wExcept, wExport,
     wFinally, wFor, wFrom, wGeneric, wIf, wImport, wIn, 
     wInclude, wInterface, wIs, wIsnot, wIterator, wLet,
@@ -61,7 +61,8 @@ type
     wPassc, wPassl, wBorrow, wDiscardable,
     wFieldChecks, 
     wWatchPoint, wSubsChar, 
-    wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto, wInjectStmt,
+    wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto, 
+    wInjectStmt, wExperimental,
     wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit, 
     wAsmNoStackFrame,
     wImplicitStatic, wGlobal, wCodegenDecl, wUnchecked, wGuard, wLocks,
@@ -103,7 +104,7 @@ const
     "addr", "and", "as", "asm", "atomic", 
     "bind", "block", "break", "case", "cast", 
     "const", "continue", "converter",
-    "discard", "distinct", "div", "do",
+    "defer", "discard", "distinct", "div", "do",
     "elif", "else", "end", "enum", "except", "export", 
     "finally", "for", "from", "generic", "if", 
     "import", "in", "include", "interface", "is", "isnot", "iterator",
@@ -144,7 +145,7 @@ const
     "passc", "passl", "borrow", "discardable", "fieldchecks",
     "watchpoint",
     "subschar", "acyclic", "shallow", "unroll", "linearscanend",
-    "computedgoto", "injectstmt",
+    "computedgoto", "injectstmt", "experimental",
     "write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
     "asmnostackframe", "implicitstatic", "global", "codegendecl", "unchecked",
     "guard", "locks",
diff --git a/doc/advopt.txt b/doc/advopt.txt
index 2ddba12e8..78c3d571a 100644
--- a/doc/advopt.txt
+++ b/doc/advopt.txt
@@ -91,4 +91,5 @@ Advanced options:
   --verbosity:0|1|2|3       set Nim's verbosity level (1 is default)
   --cs:none|partial         set case sensitivity level (default: none);
                             do not use! this setting affects the whole language
+  --experimental            enable experimental language features
   -v, --version             show detailed version information
diff --git a/doc/gc.txt b/doc/gc.txt
index fdb1d1b6c..9398262d9 100644
--- a/doc/gc.txt
+++ b/doc/gc.txt
@@ -47,7 +47,8 @@ Realtime support
 ================
 
 To enable realtime support, the symbol `useRealtimeGC`:idx: needs to be
-defined. With this switch the GC supports the following operations:
+defined via ``--define:useRealtimeGC`` (you can put this into your config 
+file as well). With this switch the GC supports the following operations:
 
 .. code-block:: nim
   proc GC_setMaxPause*(MaxPauseInUs: int)
diff --git a/doc/grammar.txt b/doc/grammar.txt
index a54428678..e751c2d8d 100644
--- a/doc/grammar.txt
+++ b/doc/grammar.txt
@@ -4,7 +4,7 @@ semicolon = ';' COMMENT?
 colon = ':' COMMENT?
 colcom = ':' COMMENT?
 
-operator =  OP0 | OP1 | OP2 | OP3 | OP4 | OP5 | OP6 | OP7 | OP8 | OP9
+operator =  OP0 | OP1 | OP2 | OP3 | OP4 | OP5 | OP6 | OP7 | OP8 | OP9 | OP10
          | 'or' | 'xor' | 'and'
          | 'is' | 'isnot' | 'in' | 'notin' | 'of'
          | 'div' | 'mod' | 'shl' | 'shr' | 'not' | 'addr' | 'static' | '..'
@@ -14,16 +14,17 @@ prefixOperator = operator
 optInd = COMMENT?
 optPar = (IND{>} | IND{=})?
 
-simpleExpr = assignExpr (OP0 optInd assignExpr)*
-assignExpr = orExpr (OP1 optInd orExpr)*
-orExpr = andExpr (OP2 optInd andExpr)*
-andExpr = cmpExpr (OP3 optInd cmpExpr)*
-cmpExpr = sliceExpr (OP4 optInd sliceExpr)*
-sliceExpr = ampExpr (OP5 optInd ampExpr)*
-ampExpr = plusExpr (OP6 optInd plusExpr)*
-plusExpr = mulExpr (OP7 optInd mulExpr)*
-mulExpr = dollarExpr (OP8 optInd dollarExpr)*
-dollarExpr = primary (OP9 optInd primary)*
+simpleExpr = arrowExpr (OP0 optInd arrowExpr)*
+arrowExpr = assignExpr (OP1 optInd assignExpr)*
+assignExpr = orExpr (OP2 optInd orExpr)*
+orExpr = andExpr (OP3 optInd andExpr)*
+andExpr = cmpExpr (OP4 optInd cmpExpr)*
+cmpExpr = sliceExpr (OP5 optInd sliceExpr)*
+sliceExpr = ampExpr (OP6 optInd ampExpr)*
+ampExpr = plusExpr (OP7 optInd plusExpr)*
+plusExpr = mulExpr (OP8 optInd mulExpr)*
+mulExpr = dollarExpr (OP9 optInd dollarExpr)*
+dollarExpr = primary (OP10 optInd primary)*
 symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`'
        | IDENT
 indexExpr = expr
@@ -142,6 +143,7 @@ exceptBlock = 'except' colcom stmt
 forStmt = 'for' (identWithPragma ^+ comma) 'in' expr colcom stmt
 blockStmt = 'block' symbol? colcom stmt
 staticStmt = 'static' colcom stmt
+deferStmt = 'defer' colcom stmt
 asmStmt = 'asm' pragma? (STR_LIT | RSTR_LIT | TRIPLE_STR_LIT)
 genericParam = symbol (comma symbol)* (colon expr)? ('=' optInd expr)?
 genericParamList = '[' optInd
@@ -182,7 +184,7 @@ simpleStmt = ((returnStmt | raiseStmt | yieldStmt | discardStmt | breakStmt
            | includeStmt | commentStmt) / exprStmt) COMMENT?
 complexOrSimpleStmt = (ifStmt | whenStmt | whileStmt
                     | tryStmt | finallyStmt | exceptStmt | forStmt
-                    | blockStmt | staticStmt | asmStmt
+                    | blockStmt | staticStmt | deferStmt | asmStmt
                     | 'proc' routine
                     | 'method' routine
                     | 'iterator' routine
diff --git a/doc/keywords.txt b/doc/keywords.txt
index a43b35475..67ff0ab7f 100644
--- a/doc/keywords.txt
+++ b/doc/keywords.txt
@@ -1,7 +1,7 @@
 addr and as asm atomic
 bind block break
 case cast const continue converter
-discard distinct div do
+defer discard distinct div do
 elif else end enum except export
 finally for from
 generic
diff --git a/doc/manual/pragmas.txt b/doc/manual/pragmas.txt
index 6181b3e1b..6bb1314cd 100644
--- a/doc/manual/pragmas.txt
+++ b/doc/manual/pragmas.txt
@@ -495,3 +495,21 @@ identifier that can be used to enable or disable it:
 This is often better than disabling all warnings at once.
 
 
+experimental pragma
+-------------------
+
+The ``experimental`` pragma enables experimental language features. Depending
+on the concrete feature this means that the feature is either considered
+too unstable for an otherwise stable release or that the future of the feature
+is uncertain (it may be removed any time).
+
+Example:
+
+.. code-block:: nim
+  {.experimental.}
+
+  proc useUsing(dest: var string) =
+    using dest
+    add "foo"
+    add "bar"
+
diff --git a/doc/manual/stmts.txt b/doc/manual/stmts.txt
index 8d958733d..e31be7121 100644
--- a/doc/manual/stmts.txt
+++ b/doc/manual/stmts.txt
@@ -488,7 +488,8 @@ Instead of:
 Using statement
 ---------------
 
-**Warning**: The ``using`` statement is highly experimental!
+**Warning**: The ``using`` statement is highly experimental and has to be
+explicitly enabled with the `experimental`:idx: pragma or command line option!
 
 The using statement provides syntactic convenience for procs that
 heavily use a single contextual parameter. When applied to a variable or a
diff --git a/doc/manual/syntax.txt b/doc/manual/syntax.txt
index 0ae353edd..c975e7f48 100644
--- a/doc/manual/syntax.txt
+++ b/doc/manual/syntax.txt
@@ -5,24 +5,21 @@ This section lists Nim's standard syntax. How the parser handles
 the indentation is already described in the `Lexical Analysis`_ section.
 
 Nim allows user-definable operators.
-Binary operators have 10 different levels of precedence.
+Binary operators have 11 different levels of precedence.
 
-Relevant character
-------------------
-
-An operator symbol's *relevant character* is its first
-character unless the first character is ``\`` and its length is greater than 1
-then it is the second character.
-
-This rule allows to escape operator symbols with ``\`` and keeps the operator's
-precedence and associativity; this is useful for meta programming.
 
 
 Associativity
 -------------
 
-Binary operators whose relevant character is ``^`` are right-associative, all
-other binary operators are left-associative.
+Binary operators whose first character is ``^`` or its last character
+is ``>`` are right-associative, all other binary operators are left-associative.
+
+Exception: The single "greater than" ``>`` operator is left-associative too.
+
+Operators ending in ``>`` but longer than a single character are 
+called `arrow like`:idx:.
+
 
 Precedence
 ----------
@@ -30,7 +27,7 @@ Precedence
 Unary operators always bind stronger than any binary 
 operator: ``$a + b`` is ``($a) + b`` and not ``$(a + b)``.
 
-If an unary operator's relevant character is ``@`` it is a `sigil-like`:idx: 
+If an unary operator's first character is ``@`` it is a `sigil-like`:idx: 
 operator which binds stronger than a ``primarySuffix``: ``@x.abc`` is parsed
 as ``(@x).abc`` whereas ``$x.abc`` is parsed as ``$(x.abc)``.
 
@@ -38,25 +35,26 @@ as ``(@x).abc`` whereas ``$x.abc`` is parsed as ``$(x.abc)``.
 For binary operators that are not keywords the precedence is determined by the
 following rules:
 
-If the operator ends with ``=`` and its relevant character is none of 
+If the operator ends with ``=`` and its first character is none of 
 ``<``, ``>``, ``!``, ``=``, ``~``, ``?``, it is an *assignment operator* which
 has the lowest precedence.
 
-Otherwise precedence is determined by the relevant character.
+Otherwise precedence is determined by the first character.
 
 ================  ===============================================  ==================  ===============
-Precedence level    Operators                                      Relevant character  Terminal symbol
+Precedence level    Operators                                      First character     Terminal symbol
 ================  ===============================================  ==================  ===============
-  9 (highest)                                                      ``$  ^``            OP9
-  8               ``*    /    div   mod   shl  shr  %``            ``* % \  /``        OP8
-  7               ``+    -``                                       ``+  ~  |``         OP7
-  6               ``&``                                            ``&``               OP6
-  5               ``..``                                           ``.``               OP5
-  4               ``==  <= < >= > !=  in notin is isnot not of``   ``= <  > !``        OP4
-  3               ``and``                                                              OP3
-  2               ``or xor``                                                           OP2
-  1                                                                ``@  : ?``          OP1
-  0 (lowest)      *assignment operator* (like ``+=``, ``*=``)                          OP0
+ 10 (highest)                                                      ``$  ^``            OP10
+  9               ``*    /    div   mod   shl  shr  %``            ``* % \  /``        OP9
+  8               ``+    -``                                       ``+  ~  |``         OP8
+  7               ``&``                                            ``&``               OP7
+  6               ``..``                                           ``.``               OP6
+  5               ``==  <= < >= > !=  in notin is isnot not of``   ``= <  > !``        OP5
+  4               ``and``                                                              OP4
+  3               ``or xor``                                                           OP3
+  2                                                                ``@  : ?``          OP2
+  1               *assignment operator* (like ``+=``, ``*=``)                          OP1
+  0 (lowest)      *arrow like operator* (like ``->``, ``=>``)                          OP0
 ================  ===============================================  ==================  ===============
 
 
diff --git a/lib/core/locks.nim b/lib/core/locks.nim
index 4e85474fb..766b7b536 100644
--- a/lib/core/locks.nim
+++ b/lib/core/locks.nim
@@ -16,12 +16,15 @@ type
                     ## or not is unspecified!
   TCond* = TSysCond ## Nim condition variable
   
-  LockEffect* = object of RootEffect ## effect that denotes that some lock operation
-                                     ## is performed
-  AquireEffect* = object of LockEffect  ## effect that denotes that some lock is
-                                        ## aquired
-  ReleaseEffect* = object of LockEffect ## effect that denotes that some lock is
-                                        ## released
+  LockEffect* {.deprecated.} = object of RootEffect ## \
+    ## effect that denotes that some lock operation
+    ## is performed. Deprecated, do not use anymore!
+  AquireEffect* {.deprecated.} = object of LockEffect  ## \
+    ## effect that denotes that some lock is
+    ## aquired. Deprecated, do not use anymore!
+  ReleaseEffect* {.deprecated.} = object of LockEffect ## \
+    ## effect that denotes that some lock is
+    ## released. Deprecated, do not use anymore!
 {.deprecated: [FLock: LockEffect, FAquireLock: AquireEffect, 
     FReleaseLock: ReleaseEffect].}
 
@@ -33,15 +36,15 @@ proc deinitLock*(lock: var TLock) {.inline.} =
   ## Frees the resources associated with the lock.
   deinitSys(lock)
 
-proc tryAcquire*(lock: var TLock): bool {.tags: [AquireEffect].} = 
+proc tryAcquire*(lock: var TLock): bool = 
   ## Tries to acquire the given lock. Returns `true` on success.
   result = tryAcquireSys(lock)
 
-proc acquire*(lock: var TLock) {.tags: [AquireEffect].} =
+proc acquire*(lock: var TLock) =
   ## Acquires the given lock.
   acquireSys(lock)
   
-proc release*(lock: var TLock) {.tags: [ReleaseEffect].} =
+proc release*(lock: var TLock) =
   ## Releases the given lock.
   releaseSys(lock)
 
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index b61fe1d17..ed5d3c50c 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -46,7 +46,7 @@ type
     nnkForStmt, nnkParForStmt, nnkWhileStmt, nnkCaseStmt,
     nnkTypeSection, nnkVarSection, nnkLetSection, nnkConstSection,
     nnkConstDef, nnkTypeDef,
-    nnkYieldStmt, nnkTryStmt, nnkFinally, nnkRaiseStmt,
+    nnkYieldStmt, nnkDefer, nnkTryStmt, nnkFinally, nnkRaiseStmt,
     nnkReturnStmt, nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, nnkStaticStmt,
     nnkDiscardStmt, nnkStmtList, 
     nnkImportStmt,
diff --git a/lib/core/typeinfo.nim b/lib/core/typeinfo.nim
index 84281485f..f3f00f9f5 100644
--- a/lib/core/typeinfo.nim
+++ b/lib/core/typeinfo.nim
@@ -7,9 +7,12 @@
 #    distribution, for details about the copyright.
 #
 
-## This module implements an interface to Nimrod's runtime type information.
+## This module implements an interface to Nim's runtime type information.
 ## Note that even though ``TAny`` and its operations hide the nasty low level
 ## details from its clients, it remains inherently unsafe!
+## 
+## See the `marshal <marshal.html>`_ module for what this module allows you
+## to do. 
 
 {.push hints: off.}
 
@@ -51,7 +54,7 @@ type
     akUInt32 = 43,      ## any represents an unsigned int32
     akUInt64 = 44,      ## any represents an unsigned int64
     
-  TAny* = object {.pure.} ## can represent any nim value; NOTE: the wrapped
+  TAny* = object          ## can represent any nim value; NOTE: the wrapped
                           ## value can be modified with its wrapper! This means
                           ## that ``TAny`` keeps a non-traced pointer to its
                           ## wrapped value and **must not** live longer than
@@ -62,7 +65,7 @@ type
   ppointer = ptr pointer
   pbyteArray = ptr array[0.. 0xffff, int8]
 
-  TGenSeq {.pure.} = object
+  TGenSeq = object
     len, space: int
   PGenSeq = ptr TGenSeq
 
diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim
index 37bea45b4..968a2923a 100644
--- a/lib/impure/db_mysql.nim
+++ b/lib/impure/db_mysql.nim
@@ -220,13 +220,12 @@ proc open*(connection, user, password, database: string): TDbConn {.
   if result == nil: dbError("could not open database connection") 
   let
     colonPos = connection.find(':')
-    host =        if colonPos < 0: connection
-                  else:            substr(connection, 0, colonPos-1)
+    host = if colonPos < 0: connection
+           else: substr(connection, 0, colonPos-1)
     port: int32 = if colonPos < 0: 0'i32
-                  else:            substr(connection, colonPos+1).parseInt.int32
+                  else: substr(connection, colonPos+1).parseInt.int32
   if mysql.realConnect(result, host, user, password, database, 
                        port, nil, 0) == nil:
     var errmsg = $mysql.error(result)
     db_mysql.close(result)
     dbError(errmsg)
-
diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim
index d4bd94e5e..9c482575a 100644
--- a/lib/packages/docutils/highlite.nim
+++ b/lib/packages/docutils/highlite.nim
@@ -47,8 +47,9 @@ const
   # The following list comes from doc/keywords.txt, make sure it is
   # synchronized with this array by running the module itself as a test case.
   nimKeywords = ["addr", "and", "as", "asm", "atomic", "bind", "block",
-    "break", "case", "cast", "const", "continue", "converter", "discard",
-    "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export",
+    "break", "case", "cast", "const", "continue", "converter",
+    "defer", "discard", "distinct", "div", "do",
+    "elif", "else", "end", "enum", "except", "export",
     "finally", "for", "from", "generic", "if", "import", "in", "include",
     "interface", "is", "isnot", "iterator", "let", "macro", "method",
     "mixin", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc",
diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim
index 8f8ca6ab3..1efb141fc 100644
--- a/lib/pure/parseutils.nim
+++ b/lib/pure/parseutils.nim
@@ -231,96 +231,11 @@ proc parseInt*(s: string, number: var int, start = 0): int {.
   else:
     number = int(res)
 
-when defined(nimParseBiggestFloatMagic):
-  proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {.
-    magic: "ParseBiggestFloat", importc: "nimParseBiggestFloat", noSideEffect.}
-    ## parses a float starting at `start` and stores the value into `number`.
-    ## Result is the number of processed chars or 0 if a parsing error
-    ## occurred.
-else:
-  proc tenToThePowerOf(b: int): BiggestFloat =
-    var b = b
-    var a = 10.0
-    result = 1.0
-    while true:
-      if (b and 1) == 1:
-        result *= a
-      b = b shr 1
-      if b == 0: break
-      a *= a
-
-  proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {.
-    rtl, extern: "npuParseBiggestFloat", noSideEffect.} =
-    ## parses a float starting at `start` and stores the value into `number`.
-    ## Result is the number of processed chars or 0 if there occured a parsing
-    ## error.
-    var
-      esign = 1.0
-      sign = 1.0
-      i = start
-      exponent: int
-      flags: int
-    number = 0.0
-    if s[i] == '+': inc(i)
-    elif s[i] == '-':
-      sign = -1.0
-      inc(i)
-    if s[i] == 'N' or s[i] == 'n':
-      if s[i+1] == 'A' or s[i+1] == 'a':
-        if s[i+2] == 'N' or s[i+2] == 'n':
-          if s[i+3] notin IdentChars:
-            number = NaN
-            return i+3 - start
-      return 0
-    if s[i] == 'I' or s[i] == 'i':
-      if s[i+1] == 'N' or s[i+1] == 'n':
-        if s[i+2] == 'F' or s[i+2] == 'f':
-          if s[i+3] notin IdentChars: 
-            number = Inf*sign
-            return i+3 - start
-      return 0
-    while s[i] in {'0'..'9'}:
-      # Read integer part
-      flags = flags or 1
-      number = number * 10.0 + toFloat(ord(s[i]) - ord('0'))
-      inc(i)
-      while s[i] == '_': inc(i)
-    # Decimal?
-    if s[i] == '.':
-      var hd = 1.0
-      inc(i)
-      while s[i] in {'0'..'9'}:
-        # Read fractional part
-        flags = flags or 2
-        number = number * 10.0 + toFloat(ord(s[i]) - ord('0'))
-        hd = hd * 10.0
-        inc(i)
-        while s[i] == '_': inc(i)
-      number = number / hd # this complicated way preserves precision
-    # Again, read integer and fractional part
-    if flags == 0: return 0
-    # Exponent?
-    if s[i] in {'e', 'E'}:
-      inc(i)
-      if s[i] == '+':
-        inc(i)
-      elif s[i] == '-':
-        esign = -1.0
-        inc(i)
-      if s[i] notin {'0'..'9'}:
-        return 0
-      while s[i] in {'0'..'9'}:
-        exponent = exponent * 10 + ord(s[i]) - ord('0')
-        inc(i)
-        while s[i] == '_': inc(i)
-    # Calculate Exponent
-    let hd = tenToThePowerOf(exponent)
-    if esign > 0.0: number = number * hd
-    else:           number = number / hd
-    # evaluate sign
-    number = number * sign
-    result = i - start
-
+proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {.
+  magic: "ParseBiggestFloat", importc: "nimParseBiggestFloat", noSideEffect.}
+  ## parses a float starting at `start` and stores the value into `number`.
+  ## Result is the number of processed chars or 0 if a parsing error
+  ## occurred.
 
 proc parseFloat*(s: string, number: var float, start = 0): int {.
   rtl, extern: "npuParseFloat", noSideEffect.} =
diff --git a/lib/system.nim b/lib/system.nim
index 269dbb1e0..0cd4b84e2 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1020,16 +1020,16 @@ const
     ## is the endianness of the target CPU. This is a valuable piece of
     ## information for low-level code only. This works thanks to compiler
     ## magic.
-    
-  hostOS* {.magic: "HostOS"}: string = ""
+
+  hostOS* {.magic: "HostOS".}: string = ""
     ## a string that describes the host operating system. Possible values:
     ## "windows", "macosx", "linux", "netbsd", "freebsd", "openbsd", "solaris",
     ## "aix", "standalone".
-        
-  hostCPU* {.magic: "HostCPU"}: string = ""
+
+  hostCPU* {.magic: "HostCPU".}: string = ""
     ## a string that describes the host CPU. Possible values:
-    ## "i386", "alpha", "powerpc", "sparc", "amd64", "mips", "arm".
-  
+    ## "i386", "alpha", "powerpc", "powerpc64", "sparc", "amd64", "mips", "arm".
+
   seqShallowFlag = low(int)
 
 proc compileOption*(option: string): bool {.
@@ -2120,7 +2120,7 @@ elif hostOS != "standalone":
       inc(i)
   {.pop.}
 
-proc echo*(x: varargs[string, `$`]) {.magic: "Echo", tags: [WriteIOEffect], benign.}
+proc echo*(x: varargs[expr, `$`]) {.magic: "Echo", tags: [WriteIOEffect], benign.}
   ## Writes and flushes the parameters to the standard output.
   ##
   ## Special built-in that takes a variable number of arguments. Each argument
@@ -2135,7 +2135,7 @@ proc echo*(x: varargs[string, `$`]) {.magic: "Echo", tags: [WriteIOEffect], beni
   ## <manual.html#nosideeffect-pragma>`_ you can use `debugEcho <#debugEcho>`_
   ## instead.
 
-proc debugEcho*(x: varargs[string, `$`]) {.magic: "Echo", noSideEffect, 
+proc debugEcho*(x: varargs[expr, `$`]) {.magic: "Echo", noSideEffect, 
                                            tags: [], raises: [].}
   ## Same as `echo <#echo>`_, but as a special semantic rule, ``debugEcho``
   ## pretends to be free of side effects, so that it can be used for debugging
diff --git a/lib/system/platforms.nim b/lib/system/platforms.nim
new file mode 100644
index 000000000..3ec6a270e
--- /dev/null
+++ b/lib/system/platforms.nim
@@ -0,0 +1,74 @@
+#
+#
+#            Nim's Runtime Library
+#        (c) Copyright 2014 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## Platform detection for Nim. This module is included by the system module!
+## Do not import it directly!
+
+type
+  CpuPlatform* {.pure.} = enum ## the CPU this program will run on.
+    none,                      ## unknown CPU
+    i386,                      ## 32 bit x86 compatible CPU
+    m68k,                      ## M68k based processor
+    alpha,                     ## Alpha processor
+    powerpc,                   ## 32 bit PowerPC
+    powerpc64,                 ## 64 bit PowerPC
+    sparc,                     ## Sparc based processor
+    ia64,                      ## Intel Itanium
+    amd64,                     ## x86_64 (AMD64); 64 bit x86 compatible CPU
+    mips,                      ## Mips based processor
+    arm,                       ## ARM based processor
+    vm,                        ## Some Virtual machine: Nim's VM or JavaScript
+    avr                        ## AVR based processor
+
+  OsPlatform* {.pure.} = enum ## the OS this program will run on.
+    none, dos, windows, os2, linux, morphos, skyos, solaris,
+    irix, netbsd, freebsd, openbsd, aix, palmos, qnx, amiga,
+    atari, netware, macos, macosx, haiku, js, nimVM, standalone
+
+const
+  targetOS* = when defined(windows): OsPlatform.windows
+              elif defined(dos): OsPlatform.dos
+              elif defined(os2): OsPlatform.os2
+              elif defined(linux): OsPlatform.linux
+              elif defined(morphos): OsPlatform.morphos
+              elif defined(skyos): OsPlatform.skyos
+              elif defined(solaris): OsPlatform.solaris
+              elif defined(irix): OsPlatform.irix
+              elif defined(netbsd): OsPlatform.netbsd
+              elif defined(freebsd): OsPlatform.freebsd
+              elif defined(openbsd): OsPlatform.openbsd
+              elif defined(aix): OsPlatform.aix
+              elif defined(palmos): OsPlatform.palmos
+              elif defined(qnx): OsPlatform.qnx
+              elif defined(amiga): OsPlatform.amiga
+              elif defined(atari): OsPlatform.atari
+              elif defined(netware): OsPlatform.netware
+              elif defined(macosx): OsPlatform.macosx
+              elif defined(macos): OsPlatform.macos
+              elif defined(haiku): OsPlatform.haiku
+              elif defined(js): OsPlatform.js
+              elif defined(nimrodVM): OsPlatform.nimVM
+              elif defined(standalone): OsPlatform.standalone
+              else: OsPlatform.none
+    ## the OS this program will run on.
+
+  targetCPU* = when defined(i386): CpuPlatform.i386
+               elif defined(m68k): CpuPlatform.m68k
+               elif defined(alpha): CpuPlatform.alpha
+               elif defined(powerpc): CpuPlatform.powerpc
+               elif defined(powerpc64): CpuPlatform.powerpc64
+               elif defined(sparc): CpuPlatform.sparc
+               elif defined(ia64): CpuPlatform.ia64
+               elif defined(amd64): CpuPlatform.amd64
+               elif defined(mips): CpuPlatform.mips
+               elif defined(arm): CpuPlatform.arm
+               elif defined(vm): CpuPlatform.vm
+               elif defined(avr): CpuPlatform.avr
+               else: CpuPlatform.none
+    ## the CPU this program will run on.
diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim
index ba973e9b5..440d040a5 100644
--- a/lib/system/sysstr.nim
+++ b/lib/system/sysstr.nim
@@ -251,7 +251,7 @@ proc nimIntToStr(x: int): string {.compilerRtl.} =
     swap(result[j], result[i-j-1])
 
 proc nimFloatToStr(f: float): string {.compilerproc.} =
-  var buf: array [0..64, char]
+  var buf: array[0..64, char]
   var n: int = c_sprintf(buf, "%.16g", f)
   var hasDot = false
   for i in 0..n-1:
@@ -292,7 +292,7 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
   var
     i = start
     sign = 1.0
-    t: array[128, char]
+    t: array[500, char] # flaviu says: 325 is the longest reasonable literal
     ti = 0
     hasdigits = false
 
diff --git a/lib/windows/windows.nim b/lib/windows/windows.nim
index 9008d63e3..f0895217b 100644
--- a/lib/windows/windows.nim
+++ b/lib/windows/windows.nim
@@ -6743,13 +6743,13 @@ const
   EXCEPTION_READ_FAULT* = 0   # Access violation was caused by a read

   EXCEPTION_WRITE_FAULT* = 1  # Access violation was caused by a write

 

-when defined(cpuia64):

+when hostCPU == "ia64":

   const

     EXCEPTION_EXECUTE_FAULT* = 2 # Access violation was caused by an instruction fetch

 else:

   const

     EXCEPTION_EXECUTE_FAULT* = 8

-when defined(cpupowerpc32):

+when hostCPU == "powerpc":

   # ppc

   const

     CONTEXT_CONTROL* = 1

@@ -6758,7 +6758,7 @@ when defined(cpupowerpc32):
     CONTEXT_DEBUG_REGISTERS* = 8

     CONTEXT_FULL* = CONTEXT_CONTROL or CONTEXT_FLOATING_POINT or CONTEXT_INTEGER

     CONTEXT_DEBUGGER* = CONTEXT_FULL

-when defined(cpui386):

+when hostCPU == "i386":

   # x86

   # The doc refered me to winnt.h, so I had to look...

   const

@@ -6776,7 +6776,7 @@ when defined(cpui386):
         CONTEXT_DEBUG_REGISTERS or CONTEXT_EXTENDED_REGISTERS # our own invention

     FLAG_TRACE_BIT* = 0x00000100

     CONTEXT_DEBUGGER* = CONTEXT_FULL or CONTEXT_FLOATING_POINT

-when defined(cpux86_64):

+when hostCPU == "amd64":

   const

     INITIAL_MXCSR* = 0x00001F80 # initial MXCSR value

     INITIAL_FPCSR* = 0x0000027F # initial FPCSR value

@@ -7778,7 +7778,7 @@ elif defined(x86_64):
       LastExceptionToRip*: DWORD64

       LastExceptionFromRip*: DWORD64

 

-elif defined(powerpc32):

+elif hostCPU == "powerpc":

   # ppc

   # Floating point registers returned when CONTEXT_FLOATING_POINT is set

   # Integer registers returned when CONTEXT_INTEGER is set.

diff --git a/todo.txt b/todo.txt
index 077f5c9cb..6068c049b 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,12 +1,16 @@
 version 0.10
 ============
 
+  Repetition renders the ridiculous reasonable.
+
 - introduce ``--experimental`` switch
+- c2nim depends on the compiler
 - make nimble part of the distribution
 - split idetools into separate tool
 - split docgen into separate tool
 
 
+
 Concurrency
 -----------
 
@@ -33,7 +37,6 @@ Misc
 Bugs
 ====
 
-- fix the bug that keeps 'defer' template from working
 - VM: Pegs do not work at compile-time
 - VM: ptr/ref T cannot work in general
 - scopes are still broken for generic instantiation!
diff --git a/web/news.txt b/web/news.txt
index fd9ac77c2..76541560c 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -28,6 +28,9 @@ News
     fails to match.
   - The "symmetric set difference" operator (``-+-``) never worked and has been
     removed.
+  - ``defer`` is a keyword now.
+  - The ``using`` language feature now needs to be activated via the new
+    ``{.experimental.}`` pragma that enables experimental language features.
 
   Language Additions
   ------------------
@@ -38,6 +41,9 @@ News
   - ``deepCopy`` has been added to the language.
   - The builtin ``procCall`` can be used to get ``super``-like functionality
     for multi methods.
+  - There is a new pragma ``{.experimental.}`` that enables experimental
+    language features per module, or you can enable this features on a global
+    level with the ``--experimental`` command line option.
 
 
   Compiler Additions