summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgexprs.nim8
-rw-r--r--compiler/ccgstmts.nim9
-rw-r--r--compiler/llstream.nim41
-rw-r--r--compiler/msgs.nim8
-rw-r--r--compiler/parser.nim4
-rw-r--r--compiler/platform.nim2
-rw-r--r--compiler/semexprs.nim37
-rw-r--r--compiler/seminst.nim13
-rw-r--r--compiler/semstmts.nim4
-rw-r--r--compiler/semtypes.nim2
-rw-r--r--compiler/treetab.nim5
-rw-r--r--compiler/types.nim10
-rw-r--r--compiler/vm.nim4
-rw-r--r--compiler/vmgen.nim3
-rw-r--r--config/nim.cfg14
-rw-r--r--doc/advopt.txt1
-rw-r--r--doc/basicopt.txt1
-rw-r--r--doc/manual/syntax.txt6
-rw-r--r--lib/impure/rdstdin.nim24
-rw-r--r--lib/nimbase.h11
-rw-r--r--lib/pure/terminal.nim28
-rw-r--r--lib/system.nim2
-rw-r--r--readme.md26
-rw-r--r--tests/closure/ttimeinfo.nim15
-rw-r--r--tests/generics/t1056.nim3
-rw-r--r--tests/stdlib/tmitems.nim2
-rw-r--r--tests/template/tparams_gensymed.nim19
-rw-r--r--tests/vm/tconsttable.nim19
-rw-r--r--todo.txt15
-rw-r--r--web/news.txt13
30 files changed, 240 insertions, 109 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 32678d472..9b45c4492 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -83,7 +83,9 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): PRope =
     else:
       result = toRope("NIM_NIL")
   of nkStrLit..nkTripleStrLit:
-    if skipTypes(ty, abstractVarRange).kind == tyString:
+    if n.strVal.isNil:
+      result = ropecg(p.module, "((#NimStringDesc*) NIM_NIL)", [])
+    elif skipTypes(ty, abstractVarRange).kind == tyString:
       var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId)
       if id == gBackendId:
         # string literal not found in the cache:
@@ -950,7 +952,7 @@ proc genEcho(p: BProc, n: PNode) =
   var a: TLoc
   for i in countup(0, n.len-1):
     initLocExpr(p, n.sons[i], a)
-    appf(args, ", ($1)->data", [rdLoc(a)])
+    appf(args, ", $1? ($1)->data:\"nil\"", [rdLoc(a)])
   linefmt(p, cpsStmts, "printf($1$2);$n",
           makeCString(repeatStr(n.len, "%s") & tnl), args)
 
@@ -2173,7 +2175,7 @@ proc genConstExpr(p: BProc, n: PNode): PRope =
     var cs: TBitSet
     toBitSet(n, cs)
     result = genRawSetData(cs, int(getSize(n.typ)))
-  of nkBracket, nkPar, nkClosure:
+  of nkBracket, nkPar, nkClosure, nkObjConstr:
     var t = skipTypes(n.typ, abstractInst)
     if t.kind == tySequence:
       result = genConstSeq(p, n, t)
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index f5a2c0ef4..18705c974 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -253,15 +253,6 @@ proc genConstStmt(p: BProc, t: PNode) =
     elif c.typ.kind in ConstantDataTypes and lfNoDecl notin c.loc.flags and
         c.ast.len != 0:
       if not emitLazily(c): requestConstImpl(p, c)
-      when false:
-        # generate the data:
-        fillLoc(c.loc, locData, c.typ, mangleName(c), OnUnknown)
-        if sfImportc in c.flags: 
-          appf(p.module.s[cfsData], "extern NIM_CONST $1 $2;$n", 
-               [getTypeDesc(p.module, c.typ), c.loc.r])
-        else: 
-          appf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n", 
-               [getTypeDesc(p.module, c.typ), c.loc.r, genConstExpr(p, c.ast)])
 
 proc genIf(p: BProc, n: PNode, d: var TLoc) =
   #
diff --git a/compiler/llstream.nim b/compiler/llstream.nim
index be469548d..69475965d 100644
--- a/compiler/llstream.nim
+++ b/compiler/llstream.nim
@@ -30,47 +30,32 @@ type
   
   PLLStream* = ref TLLStream
 
-proc llStreamOpen*(data: string): PLLStream
-proc llStreamOpen*(f: var File): PLLStream
-proc llStreamOpen*(filename: string, mode: FileMode): PLLStream
-proc llStreamOpen*(): PLLStream
-proc llStreamOpenStdIn*(): PLLStream
-proc llStreamClose*(s: PLLStream)
-proc llStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int
-proc llStreamReadLine*(s: PLLStream, line: var string): bool
-proc llStreamReadAll*(s: PLLStream): string
-proc llStreamWrite*(s: PLLStream, data: string)
-proc llStreamWrite*(s: PLLStream, data: char)
-proc llStreamWrite*(s: PLLStream, buf: pointer, buflen: int)
-proc llStreamWriteln*(s: PLLStream, data: string)
-# implementation
-
-proc llStreamOpen(data: string): PLLStream = 
+proc llStreamOpen*(data: string): PLLStream = 
   new(result)
   result.s = data
   result.kind = llsString
 
-proc llStreamOpen(f: var File): PLLStream = 
+proc llStreamOpen*(f: var File): PLLStream = 
   new(result)
   result.f = f
   result.kind = llsFile
 
-proc llStreamOpen(filename: string, mode: FileMode): PLLStream = 
+proc llStreamOpen*(filename: string, mode: FileMode): PLLStream = 
   new(result)
   result.kind = llsFile
   if not open(result.f, filename, mode): result = nil
   
-proc llStreamOpen(): PLLStream = 
+proc llStreamOpen*(): PLLStream = 
   new(result)
   result.kind = llsNone
 
-proc llStreamOpenStdIn(): PLLStream = 
+proc llStreamOpenStdIn*(): PLLStream = 
   new(result)
   result.kind = llsStdIn
   result.s = ""
   result.lineOffset = -1
 
-proc llStreamClose(s: PLLStream) = 
+proc llStreamClose*(s: PLLStream) = 
   case s.kind
   of llsNone, llsString, llsStdIn: 
     discard
@@ -130,7 +115,7 @@ proc llReadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int =
     copyMem(buf, addr(s.s[s.rd]), result)
     inc(s.rd, result)
 
-proc llStreamRead(s: PLLStream, buf: pointer, bufLen: int): int = 
+proc llStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int = 
   case s.kind
   of llsNone: 
     result = 0
@@ -144,7 +129,7 @@ proc llStreamRead(s: PLLStream, buf: pointer, bufLen: int): int =
   of llsStdIn: 
     result = llReadFromStdin(s, buf, bufLen)
   
-proc llStreamReadLine(s: PLLStream, line: var string): bool =
+proc llStreamReadLine*(s: PLLStream, line: var string): bool =
   setLen(line, 0)
   case s.kind
   of llsNone:
@@ -168,7 +153,7 @@ proc llStreamReadLine(s: PLLStream, line: var string): bool =
   of llsStdIn:
     result = readLine(stdin, line)
     
-proc llStreamWrite(s: PLLStream, data: string) = 
+proc llStreamWrite*(s: PLLStream, data: string) = 
   case s.kind
   of llsNone, llsStdIn: 
     discard
@@ -178,11 +163,11 @@ proc llStreamWrite(s: PLLStream, data: string) =
   of llsFile: 
     write(s.f, data)
   
-proc llStreamWriteln(s: PLLStream, data: string) = 
+proc llStreamWriteln*(s: PLLStream, data: string) = 
   llStreamWrite(s, data)
   llStreamWrite(s, "\n")
 
-proc llStreamWrite(s: PLLStream, data: char) = 
+proc llStreamWrite*(s: PLLStream, data: char) = 
   var c: char
   case s.kind
   of llsNone, llsStdIn: 
@@ -194,7 +179,7 @@ proc llStreamWrite(s: PLLStream, data: char) =
     c = data
     discard writeBuffer(s.f, addr(c), sizeof(c))
 
-proc llStreamWrite(s: PLLStream, buf: pointer, buflen: int) = 
+proc llStreamWrite*(s: PLLStream, buf: pointer, buflen: int) = 
   case s.kind
   of llsNone, llsStdIn: 
     discard
@@ -206,7 +191,7 @@ proc llStreamWrite(s: PLLStream, buf: pointer, buflen: int) =
   of llsFile: 
     discard writeBuffer(s.f, buf, buflen)
   
-proc llStreamReadAll(s: PLLStream): string = 
+proc llStreamReadAll*(s: PLLStream): string = 
   const 
     bufSize = 2048
   case s.kind
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index b58561d30..be69f1ea5 100644
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -113,7 +113,7 @@ type
     warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel, 
     warnUnknownSubstitutionX, warnLanguageXNotSupported,
     warnFieldXNotSupported, warnCommentXIgnored, 
-    warnNilStatement, warnAnalysisLoophole,
+    warnNilStatement, warnTypelessParam,
     warnDifferentHeaps, warnWriteToForeignHeap, warnUnsafeCode,
     warnEachIdentIsTuple, warnShadowIdent, 
     warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2,
@@ -311,7 +311,7 @@ const
     errXOnlyAtModuleScope: "\'$1\' is only allowed at top level", 
     errXNeedsParamObjectType: "'$1' needs a parameter that has an object type",
     errTemplateInstantiationTooNested: "template/macro instantiation too nested",
-    errInstantiationFrom: "instantiation from here", 
+    errInstantiationFrom: "template/generic instantiation from here", 
     errInvalidIndexValueForTuple: "invalid index value for tuple subscript", 
     errCommandExpectsFilename: "command expects a filename argument",
     errMainModuleMustBeSpecified: "please, specify a main module in the project configuration file",
@@ -376,7 +376,7 @@ const
     warnFieldXNotSupported: "field \'$1\' not supported [FieldXNotSupported]", 
     warnCommentXIgnored: "comment \'$1\' ignored [CommentXIgnored]", 
     warnNilStatement: "'nil' statement is deprecated; use an empty 'discard' statement instead [NilStmt]", 
-    warnAnalysisLoophole: "thread analysis incomplete due to unknown call '$1' [AnalysisLoophole]",
+    warnTypelessParam: "'$1' has no type. Typeless parameters are deprecated; only allowed for 'template' [TypelessParam]",
     warnDifferentHeaps: "possible inconsistency of thread local heaps [DifferentHeaps]",
     warnWriteToForeignHeap: "write to foreign heap [WriteToForeignHeap]",
     warnUnsafeCode: "unsafe code: '$1' [UnsafeCode]",
@@ -418,7 +418,7 @@ const
     "RedefinitionOfLabel", "UnknownSubstitutionX",
     "LanguageXNotSupported", "FieldXNotSupported",
     "CommentXIgnored", "NilStmt",
-    "AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap",
+    "TypelessParam", "DifferentHeaps", "WriteToForeignHeap",
     "UnsafeCode", "EachIdentIsTuple", "ShadowIdent", 
     "ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit",
     "GcMem", "Destructor", "LockLevel", "User"]
diff --git a/compiler/parser.nim b/compiler/parser.nim
index aae0ce7f9..f249b37c8 100644
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -198,8 +198,8 @@ proc isSigilLike(tok: TToken): bool {.inline.} =
 
 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] == '>'))
+  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.
diff --git a/compiler/platform.nim b/compiler/platform.nim
index 8360a9dcc..a21e73248 100644
--- a/compiler/platform.nim
+++ b/compiler/platform.nim
@@ -138,7 +138,7 @@ const
       props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
      (name: "VxWorks", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
       objExt: ".o", newLine: "\x0A", pathSep: ";", dirSep: "\\",
-      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
+      scriptExt: ".sh", curDir: ".", exeExt: ".vxe", extSep: ".",
       props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
      (name: "JS", parDir: "..", 
       dllFrmt: "lib$1.so", altDirSep: "/", 
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index eeada0006..40413e3eb 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -103,28 +103,31 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
       result = newSymNode(s, n.info)
   of skMacro: result = semMacroExpr(c, n, n, s, flags)
   of skTemplate: result = semTemplateExpr(c, n, s, flags)
-  of skVar, skLet, skResult, skParam, skForVar:
+  of skParam:
+    markUsed(n.info, s)
+    styleCheckUse(n.info, s)
+    if s.typ.kind == tyStatic and s.typ.n != nil:
+      # XXX see the hack in sigmatch.nim ...
+      return s.typ.n
+    elif sfGenSym in s.flags:
+      if c.p.wasForwarded:
+        # gensym'ed parameters that nevertheless have been forward declared
+        # need a special fixup:
+        let realParam = c.p.owner.typ.n[s.position+1]
+        internalAssert realParam.kind == nkSym and realParam.sym.kind == skParam
+        return newSymNode(c.p.owner.typ.n[s.position+1].sym, n.info)
+      elif c.p.owner.kind == skMacro:
+        # gensym'ed macro parameters need a similar hack (see bug #1944):
+        var u = searchInScopes(c, s.name)
+        internalAssert u != nil and u.kind == skParam and u.owner == s.owner
+        return newSymNode(u, n.info)
+    result = newSymNode(s, n.info)
+  of skVar, skLet, skResult, skForVar:
     markUsed(n.info, s)
     styleCheckUse(n.info, s)
     # if a proc accesses a global variable, it is not side effect free:
     if sfGlobal in s.flags:
       incl(c.p.owner.flags, sfSideEffect)
-    elif s.kind == skParam:
-      if s.typ.kind == tyStatic and s.typ.n != nil:
-        # XXX see the hack in sigmatch.nim ...
-        return s.typ.n
-      elif sfGenSym in s.flags:
-        if c.p.wasForwarded:
-          # gensym'ed parameters that nevertheless have been forward declared
-          # need a special fixup:
-          let realParam = c.p.owner.typ.n[s.position+1]
-          internalAssert realParam.kind == nkSym and realParam.sym.kind == skParam
-          return newSymNode(c.p.owner.typ.n[s.position+1].sym, n.info)
-        elif c.p.owner.kind == skMacro:
-          # gensym'ed macro parameters need a similar hack (see bug #1944):
-          var u = searchInScopes(c, s.name)
-          internalAssert u != nil and u.kind == skParam and u.owner == s.owner
-          return newSymNode(u, n.info)
     result = newSymNode(s, n.info)
     # We cannot check for access to outer vars for example because it's still
     # not sure the symbol really ends up being used:
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index 81a4465c5..e02d6d1e5 100644
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -77,11 +77,16 @@ proc removeDefaultParamValues(n: PNode) =
 proc freshGenSyms(n: PNode, owner: PSym, symMap: var TIdTable) =
   # we need to create a fresh set of gensym'ed symbols:
   if n.kind == nkSym and sfGenSym in n.sym.flags:
-    var x = PSym(idTableGet(symMap, n.sym))
+    let s = n.sym
+    var x = PSym(idTableGet(symMap, s))
     if x == nil:
-      x = copySym(n.sym, false)
-      x.owner = owner
-      idTablePut(symMap, n.sym, x)
+      if s.kind == skParam:
+        x = owner.typ.n[s.position+1].sym
+        internalAssert x.kind == skParam
+      else:
+        x = copySym(s, false)
+        x.owner = owner
+        idTablePut(symMap, s, x)
     n.sym = x
   else:
     for i in 0 .. <safeLen(n): freshGenSyms(n.sons[i], owner, symMap)
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index b4790e421..6e5b272de 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -825,9 +825,9 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
     if gp.len == 0 or (gp.len == 1 and tfRetType in gp[0].typ.flags):
       pushProcCon(c, s)
       addResult(c, s.typ.sons[0], n.info, skProc)
+      addResultNode(c, n)
       let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
       n.sons[bodyPos] = transformBody(c.module, semBody, s)
-      addResultNode(c, n)
       popProcCon(c)
     elif efOperand notin flags:
       localError(n.info, errGenericLambdaNotAllowed)
@@ -860,9 +860,9 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode =
   addParams(c, n.typ.n, skProc)
   pushProcCon(c, s)
   addResult(c, n.typ.sons[0], n.info, skProc)
+  addResultNode(c, n)
   let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
   n.sons[bodyPos] = transformBody(c.module, semBody, n.sons[namePos].sym)
-  addResultNode(c, n)
   popProcCon(c)
   popOwner()
   closeScope(c)
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 7908742db..d052700b2 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -911,6 +911,8 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
     if not hasType and not hasDefault:
       if isType: localError(a.info, "':' expected")
       let tdef = if kind in {skTemplate, skMacro}: tyExpr else: tyAnything
+      if tdef == tyAnything:
+        message(a.info, warnTypelessParam, renderTree(n))
       typ = newTypeS(tdef, c)
 
     if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue
diff --git a/compiler/treetab.nim b/compiler/treetab.nim
index 63f3fc6e2..8d66d56c7 100644
--- a/compiler/treetab.nim
+++ b/compiler/treetab.nim
@@ -28,8 +28,9 @@ proc hashTree(n: PNode): THash =
   of nkFloatLit..nkFloat64Lit:
     if (n.floatVal >= - 1000000.0) and (n.floatVal <= 1000000.0): 
       result = result !& toInt(n.floatVal)
-  of nkStrLit..nkTripleStrLit: 
-    result = result !& hash(n.strVal)
+  of nkStrLit..nkTripleStrLit:
+    if not n.strVal.isNil:
+      result = result !& hash(n.strVal)
   else: 
     for i in countup(0, sonsLen(n) - 1): 
       result = result !& hashTree(n.sons[i])
diff --git a/compiler/types.nim b/compiler/types.nim
index 78d390f13..3711a9668 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -1029,16 +1029,18 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
 
 proc typeAllowedNode(marker: var IntSet, n: PNode, kind: TSymKind,
                      flags: TTypeAllowedFlags = {}): PType =
-  if n != nil: 
+  if n != nil:
     result = typeAllowedAux(marker, n.typ, kind, flags)
     #if not result: debug(n.typ)
     if result == nil:
       case n.kind
-      of nkNone..nkNilLit: 
+      of nkNone..nkNilLit:
         discard
       else:
         for i in countup(0, sonsLen(n) - 1):
-          result = typeAllowedNode(marker, n.sons[i], kind, flags)
+          let it = n.sons[i]
+          if it.kind == nkRecCase and kind == skConst: return n.typ
+          result = typeAllowedNode(marker, it, kind, flags)
           if result != nil: break
 
 proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]],
@@ -1118,7 +1120,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
       result = typeAllowedAux(marker, t.sons[i], kind, flags)
       if result != nil: break
   of tyObject, tyTuple:
-    if kind == skConst and t.kind == tyObject: return t
+    if kind == skConst and t.kind == tyObject and t.sons[0] != nil: return t
     let flags = flags+{taField}
     for i in countup(0, sonsLen(t) - 1):
       result = typeAllowedAux(marker, t.sons[i], kind, flags)
diff --git a/compiler/vm.nim b/compiler/vm.nim
index b682b4e25..090498f10 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -1438,7 +1438,9 @@ proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode =
   # immediate macros can bypass any type and arity checking so we check the
   # arity here too:
   if sym.typ.len > n.safeLen and sym.typ.len > 1:
-    globalError(n.info, "got $#, but expected $# argument(s)" % [$ <n.safeLen, $ <sym.typ.len])
+    globalError(n.info, "in call '$#' got $#, but expected $# argument(s)" % [
+        n.renderTree,
+        $ <n.safeLen, $ <sym.typ.len])
 
   setupGlobalCtx(module)
   var c = globalCtx
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index fe6526a34..70f81bc72 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -604,7 +604,8 @@ proc genNarrowU(c: PCtx; n: PNode; dest: TDest) =
   let t = skipTypes(n.typ, abstractVar-{tyTypeDesc})
   # uint is uint64 in the VM, we we only need to mask the result for
   # other unsigned types:
-  if t.kind in {tyUInt8..tyUInt32, tyInt8..tyInt32}:
+  if t.kind in {tyUInt8..tyUInt32, tyInt8..tyInt32} or
+      (t.kind == tyInt and t.size == 4):
     c.gABC(n, opcNarrowU, dest, TRegister(t.size*8))
 
 proc genBinaryABCnarrow(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
diff --git a/config/nim.cfg b/config/nim.cfg
index e4ea43a59..8f5d7e8e7 100644
--- a/config/nim.cfg
+++ b/config/nim.cfg
@@ -112,6 +112,20 @@ hint[LineTooLong]=off
   gcc.cpp.options.always = "-w -fpermissive"
 @end
 
+# Configuration for the VxWorks
+# This has been tested with VxWorks 6.9 only
+@if vxworks:
+  # For now we only support compiling RTPs applications (i.e. no DKMs)
+  gcc.options.always = "-mrtp -fno-strict-aliasing -D_C99 -D_HAS_C9X -std=c99 -fasm -Wall -Wno-write-strings"
+  # The linker config must add the VxWorks common library for the selected
+  # processor which is usually found in:
+  # "$WIND_BASE/target/lib/usr/lib/PROCESSOR_FAMILY/PROCESSOR_TYPE/common",
+  # where PROCESSOR_FAMILY and PROCESSOR_TYPE are those supported by the VxWorks
+  # compiler (e.g. ppc/PPC32 or mips/MIPSI64, etc)
+  # For now we only support the PowerPC CPU
+  gcc.options.linker %= "-L $WIND_BASE/target/lib/usr/lib/ppc/PPC32/common -mrtp -fno-strict-aliasing -D_C99 -D_HAS_C9X -std=c99 -fasm -Wall -Wno-write-strings"
+@end
+
 gcc.options.speed = "-O3 -fno-strict-aliasing"
 gcc.options.size = "-Os"
 gcc.options.debug = "-g3 -O0"
diff --git a/doc/advopt.txt b/doc/advopt.txt
index 78c3d571a..ae474afc6 100644
--- a/doc/advopt.txt
+++ b/doc/advopt.txt
@@ -66,7 +66,6 @@ Advanced options:
   --threadanalysis:on|off   turn thread analysis on|off
   --tlsEmulation:on|off     turn thread local storage emulation on|off
   --taintMode:on|off        turn taint mode on|off
-  --symbolFiles:on|off      turn symbol files on|off (experimental)
   --implicitStatic:on|off   turn implicit compile time evaluation on|off
   --patterns:on|off         turn pattern matching on|off
   --skipCfg                 do not read the general configuration file
diff --git a/doc/basicopt.txt b/doc/basicopt.txt
index e366b2718..27b10badc 100644
--- a/doc/basicopt.txt
+++ b/doc/basicopt.txt
@@ -14,7 +14,6 @@ Options:
   -p, --path:PATH           add path to search paths
   -d, --define:SYMBOL       define a conditional symbol
   -u, --undef:SYMBOL        undefine a conditional symbol
-  --symbol:SYMBOL           declare a conditional symbol
   -f, --forceBuild          force rebuilding of all modules
   --stackTrace:on|off       turn stack tracing on|off
   --lineTrace:on|off        turn line tracing on|off
diff --git a/doc/manual/syntax.txt b/doc/manual/syntax.txt
index c975e7f48..b40a8ce91 100644
--- a/doc/manual/syntax.txt
+++ b/doc/manual/syntax.txt
@@ -12,10 +12,8 @@ Binary operators have 11 different levels of precedence.
 Associativity
 -------------
 
-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.
+Binary operators whose first character is ``^`` are right-associative, all
+other binary operators are left-associative.
 
 Operators ending in ``>`` but longer than a single character are 
 called `arrow like`:idx:.
diff --git a/lib/impure/rdstdin.nim b/lib/impure/rdstdin.nim
index 258da2207..b188ead1f 100644
--- a/lib/impure/rdstdin.nim
+++ b/lib/impure/rdstdin.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nim's Runtime Library
-#        (c) Copyright 2012 Andreas Rumpf
+#        (c) Copyright 2015 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -13,6 +13,8 @@
 ## is used. This suffices because Windows' console already provides the 
 ## wanted functionality.
 
+{.deadCodeElim: on.}
+
 when defined(Windows):
   proc readLineFromStdin*(prompt: string): TaintedString {.
                           tags: [ReadIOEffect, WriteIOEffect].} = 
@@ -31,23 +33,23 @@ when defined(Windows):
     stdout.write(prompt)
     result = readLine(stdin, line)
 
-  proc getch(): cint {.header: "<conio.h>", importc: "_getch".}
-
   proc readPasswordFromStdin*(prompt: string, password: var TaintedString) =
     ## Reads a `password` from stdin without printing it. `password` must not
     ## be ``nil``!
+    proc getch(): cint {.header: "<conio.h>", importc: "_getch".}
+
     password.setLen(0)
     var c: char
     echo prompt
     while true:
-       c = getch().char
-       case c
-       of '\r', chr(0xA):
-          break
-       of '\b':
-          password.setLen(result.len - 1)
-       else:
-          password.add(c)
+      c = getch().char
+      case c
+      of '\r', chr(0xA):
+        break
+      of '\b':
+        password.setLen(password.len - 1)
+      else:
+        password.add(c)
 
 else:
   import readline, history, termios, unsigned
diff --git a/lib/nimbase.h b/lib/nimbase.h
index b72e60ac2..50c7968ac 100644
--- a/lib/nimbase.h
+++ b/lib/nimbase.h
@@ -379,7 +379,7 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); }
 #  define GC_GUARD
 #endif
 
-/* Test to see if nimrod and the C compiler agree on the size of a pointer.
+/* Test to see if Nim and the C compiler agree on the size of a pointer.
    On disagreement, your C compiler will say something like: 
    "error: 'assert_numbits' declared as an array with a negative size" */
 typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1];
@@ -390,3 +390,12 @@ typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(
 #else
 #  define NIM_EXTERNC
 #endif
+
+/* ---------------- platform specific includes ----------------------- */
+
+/* VxWorks related includes */
+#if defined(__VXWORKS__)
+#  include <sys/types.h>
+#  include <types/vxWind.h>
+#  include <tool/gnu/toolMacros.h>
+#endif
diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim
index 8607066f3..e0e2aa247 100644
--- a/lib/pure/terminal.nim
+++ b/lib/pure/terminal.nim
@@ -45,6 +45,21 @@ when defined(windows):
   var
     oldAttr = getAttributes()
 
+  proc winGetch(): cint {.header: "<conio.h>", importc: "_getch".}
+else:
+  import termios, unsigned
+
+  proc setRaw(fd: FileHandle, time: cint = TCSAFLUSH) =
+    var mode: Termios
+    discard fd.tcgetattr(addr mode)
+    mode.iflag = mode.iflag and not Tcflag(BRKINT or ICRNL or INPCK or ISTRIP or IXON)
+    mode.oflag = mode.oflag and not Tcflag(OPOST)
+    mode.cflag = (mode.cflag and not Tcflag(CSIZE or PARENB)) or CS8
+    mode.lflag = mode.lflag and not Tcflag(ECHO or ICANON or IEXTEN or ISIG)
+    mode.cc[VMIN] = 1.cuchar
+    mode.cc[VTIME] = 0.cuchar
+    discard fd.tcsetattr(time, addr mode)
+
 proc setCursorPos*(x, y: int) =
   ## sets the terminal's cursor to the (x,y) position. (0,0) is the
   ## upper left of the screen.
@@ -349,6 +364,19 @@ macro styledEcho*(m: varargs[expr]): stmt =
   result.add(newCall(bindSym"write", bindSym"stdout", newStrLitNode("\n")))
   result.add(newCall(bindSym"resetAttributes"))
 
+proc getch*(): char =
+  ## Read a single character from the terminal, blocking until it is entered.
+  ## The character is not printed to the terminal.
+  when defined(windows):
+    result = winGetch().char
+  else:
+    let fd = getFileHandle(stdin)
+    var oldMode: Termios
+    discard fd.tcgetattr(addr oldMode)
+    fd.setRaw()
+    result = stdin.readChar()
+    discard fd.tcsetattr(TCSADRAIN, addr oldMode)
+
 when isMainModule:
   system.addQuitProc(resetAttributes)
   write(stdout, "never mind")
diff --git a/lib/system.nim b/lib/system.nim
index 19836b68c..ef70a2672 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -3161,7 +3161,7 @@ when hostOS != "standalone":
       x[j+i] = item[j]
       inc(j)
 
-proc compiles*(x): bool {.magic: "Compiles", noSideEffect.} =
+proc compiles*(x: expr): bool {.magic: "Compiles", noSideEffect.} =
   ## Special compile-time procedure that checks whether `x` can be compiled
   ## without any semantic error.
   ## This can be used to check whether a type supports some operation:
diff --git a/readme.md b/readme.md
index d5968982b..b08fa2291 100644
--- a/readme.md
+++ b/readme.md
@@ -66,8 +66,24 @@ Copyright (c) 2006-2014 Andreas Rumpf.
 All rights reserved.
 
 # Build Status
-| |Linux|Windows|Mac|
-|---|---|---|---|
-| x86 | ![](http://178.62.143.63:8010/buildstatusimage?builder=linux-x32-builder) | ![](http://178.62.143.63:8010/buildstatusimage?builder=windows-x32-builder) | ![](http://178.62.143.63:8010/buildstatusimage?builder=mac-x32-builder)
-| x86_64 | ![](http://178.62.143.63:8010/buildstatusimage?builder=linux-x64-builder) | ![](http://178.62.143.63:8010/buildstatusimage?builder=windows-x64-builder) | ![](http://178.62.143.63:8010/buildstatusimage?builder=mac-x64-builder)
-| arm | ![](http://178.62.143.63:8010/buildstatusimage?builder=linux-arm5-builder) |
+[**Build Waterfall**][waterfall]
+
+|        | Linux                                                                                                  | Windows                               | Mac                           |
+| ------ | -----                                                                                                  | -------                               | ---                           |
+| x86    | ![linux-x86][linux-x86-img]                                                                            | ![windows-x86][windows-x86-img]       | ![mac-x86][mac-x86-img]       |
+| x86_64 | ![linux-x86_64][linux-x86_64-img]                                                                      | ![windows-x86_64][windows-x86_64-img] | ![mac-x86_64][mac-x86_64-img] |
+| arm    | ![linux-armv5][linux-arm5-img]<br/> ![linux-armv6][linux-arm6-img]<br/> ![linux-armv7][linux-arm7-img] |                                       |                               |
+
+[linux-x86-img]:      http://buildbot.nim-lang.org/buildstatusimage?builder=linux-x32-builder
+[linux-x86_64-img]:   http://buildbot.nim-lang.org/buildstatusimage?builder=linux-x64-builder
+[linux-arm5-img]:     http://buildbot.nim-lang.org/buildstatusimage?builder=linux-arm5-builder
+[linux-arm6-img]:     http://buildbot.nim-lang.org/buildstatusimage?builder=linux-arm6-builder
+[linux-arm7-img]:     http://buildbot.nim-lang.org/buildstatusimage?builder=linux-arm7-builder
+
+[windows-x86-img]:    http://buildbot.nim-lang.org/buildstatusimage?builder=windows-x32-builder
+[windows-x86_64-img]: http://buildbot.nim-lang.org/buildstatusimage?builder=windows-x64-builder
+
+[mac-x86-img]:        http://buildbot.nim-lang.org/buildstatusimage?builder=mac-x32-builder
+[mac-x86_64-img]:     http://buildbot.nim-lang.org/buildstatusimage?builder=mac-x64-builder
+
+[waterfall]: http://buildbot.nim-lang.org/waterfall
diff --git a/tests/closure/ttimeinfo.nim b/tests/closure/ttimeinfo.nim
new file mode 100644
index 000000000..3138ae72e
--- /dev/null
+++ b/tests/closure/ttimeinfo.nim
@@ -0,0 +1,15 @@
+# bug #2073
+
+import sequtils
+import times
+
+# 1
+proc f(n: int): TimeInfo =
+  TimeInfo(year: n, month: mJan, monthday: 1)
+
+echo toSeq(2000 || 2015).map(f)
+
+# 2
+echo toSeq(2000 || 2015).map(proc (n: int): TimeInfo =
+  TimeInfo(year: n, month: mJan, monthday: 1)
+)
diff --git a/tests/generics/t1056.nim b/tests/generics/t1056.nim
index 73a24a76a..b1fe25894 100644
--- a/tests/generics/t1056.nim
+++ b/tests/generics/t1056.nim
@@ -1,6 +1,5 @@
 discard """
   output: '''TMatrix[3, 3, system.int]
-3
 3'''
 """
 
@@ -22,5 +21,5 @@ proc echoMat2(a: TMat2) =
 var m = TMatrix[3,3,int](data: [1,2,3,4,5,6,7,8,9])
 
 echoMatrix m
-echoMat2 m
+#echoMat2 m
 
diff --git a/tests/stdlib/tmitems.nim b/tests/stdlib/tmitems.nim
index 2297f0ee9..bf67d2b7b 100644
--- a/tests/stdlib/tmitems.nim
+++ b/tests/stdlib/tmitems.nim
@@ -12,7 +12,7 @@ fpqeew
 [11, 12, 13]
 [11, 12, 13]
 { "key1": 11,  "key2": 12,  "key3": 13}
-[ 11,  12,  13]
+[11, 12, 13]
 <Students>
   <Student Name="Aprilfoo" />
   <Student Name="bar" />
diff --git a/tests/template/tparams_gensymed.nim b/tests/template/tparams_gensymed.nim
index 4178812af..33940874d 100644
--- a/tests/template/tparams_gensymed.nim
+++ b/tests/template/tparams_gensymed.nim
@@ -12,3 +12,22 @@ template genNodeKind(kind, name: expr): stmt =
       result.add(c)
 
 genNodeKind(nnkNone, None)
+
+
+# Test that generics in templates still work (regression to fix #1915)
+
+# bug #2004
+
+type Something = object
+
+proc testA(x: Something) = discard
+
+template def(name: expr) {.immediate.} =
+  proc testB[T](reallyUniqueName: T) =
+    `test name`(reallyUniqueName)
+def A
+
+var x: Something
+testB(x)
+
+
diff --git a/tests/vm/tconsttable.nim b/tests/vm/tconsttable.nim
new file mode 100644
index 000000000..64a74a59d
--- /dev/null
+++ b/tests/vm/tconsttable.nim
@@ -0,0 +1,19 @@
+discard """
+  output: '''is
+finally
+nice!'''
+"""
+
+import tables
+
+const
+  foo = {"ah": "finally", "this": "is", "possible.": "nice!"}.toTable()
+
+# protect against overly smart compiler:
+var x = "this"
+
+echo foo[x]
+x = "ah"
+echo foo[x]
+x = "possible."
+echo foo[x]
diff --git a/todo.txt b/todo.txt
index 17b8b3a21..252699bf1 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,11 +1,20 @@
-version 0.10
-============
+version 0.10.4
+==============
+
+- make 'nil' work for 'add' and 'len'
+- improve GC-unsafety warnings
+- get rid of 'mget'; aka priority of 'var' needs to be 'var{lvalue}'
+- improve documentation (theindex!)
+- fix the getUniqueType() bug
+
+
+version 1.0
+===========
 
 - nimsuggest: auto-completion needs to work in 'class' macros
 - improve the docs for inheritance
 - The bitwise 'not' operator will be renamed to 'bnot' to
   prevent 'not 4 == 5' from compiling. -> requires 'mixin' annotation for procs!
-- parameter lists without type end up in 'experimental'
 - iterators always require a return type
 - overloading of '='
 
diff --git a/web/news.txt b/web/news.txt
index ac7971f20..5cc3a6ed6 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -20,7 +20,9 @@ News
     ``addHandler``, ``getHandlers``, ``setLogFilter`` and ``getLogFilter``
     should be used instead.
   - ``nim idetools`` has been replaced by a separate tool `nimsuggest`_.
-
+  - *arrow like* operators are not right associative anymore.
+  - Typeless parameters are now only allowed in templates and macros. The old
+    way turned out to be too error-prone.
   
   Language Additions
   ------------------
@@ -30,6 +32,15 @@ News
   - Automatic dereferencing is now done for the first argument of a routine
     call if overloading resolution produces no match otherwise. This feature
     has to be enabled with the `experimental`_ pragma.
+  - Objects that do not use inheritance nor ``case`` can be put into ``const``
+    sections. This means that finally this is possible and produces rather
+    nice code:
+
+  .. code-block:: nim
+    import tables
+
+    const
+      foo = {"ah": "finally", "this": "is", "possible.": "nice!"}.toTable()
 
 
 2014-12-29 Version 0.10.2 released