summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-07-08 21:03:47 +0200
committerAraq <rumpf_a@web.de>2012-07-08 21:03:47 +0200
commit4fbba0a65ad310ba9498f1cf9f79eb0826b19f81 (patch)
treedece3596fbdf153263f5672b4011139f70a4df6a
parent36247e0947699a56d5bc51d48188b6dda1815587 (diff)
downloadNim-4fbba0a65ad310ba9498f1cf9f79eb0826b19f81.tar.gz
changed integer promotion rules; breaks bootstrapping and lots of code
-rwxr-xr-xcompiler/ast.nim3
-rwxr-xr-xcompiler/ccgexprs.nim5
-rwxr-xr-xcompiler/ecmasgen.nim3
-rwxr-xr-xcompiler/magicsys.nim55
-rw-r--r--compiler/saturate.nim79
-rwxr-xr-xcompiler/semcall.nim14
-rwxr-xr-xcompiler/semdata.nim5
-rwxr-xr-xcompiler/semexprs.nim61
-rwxr-xr-xcompiler/semfold.nim161
-rw-r--r--compiler/semmagic.nim6
-rwxr-xr-xcompiler/semtypes.nim3
-rwxr-xr-xcompiler/sigmatch.nim59
-rwxr-xr-xcompiler/transf.nim1
-rwxr-xr-xcompiler/types.nim12
-rwxr-xr-xdoc/manual.txt82
-rwxr-xr-xlib/core/typeinfo.nim2
-rwxr-xr-xlib/impure/db_postgres.nim6
-rwxr-xr-xlib/impure/db_sqlite.nim10
-rwxr-xr-xlib/impure/graphics.nim9
-rwxr-xr-xlib/impure/re.nim16
-rw-r--r--lib/pure/oids.nim3
-rwxr-xr-xlib/pure/osproc.nim26
-rwxr-xr-xlib/pure/sockets.nim22
-rwxr-xr-xlib/pure/times.nim44
-rwxr-xr-xlib/system.nim16
-rwxr-xr-xlib/system/ansi_c.nim3
-rwxr-xr-xlib/system/repr.nim7
-rwxr-xr-xlib/system/sysio.nim8
-rwxr-xr-xlib/windows/windows.nim98
-rwxr-xr-xlib/wrappers/gtk/gtk2.nim2
-rwxr-xr-xlib/wrappers/gtk/pango.nim4
-rwxr-xr-xlib/wrappers/sdl/sdl.nim10
-rwxr-xr-xlib/wrappers/sdl/sdl_image.nim6
-rwxr-xr-xlib/wrappers/sdl/sdl_mixer.nim6
-rwxr-xr-xlib/wrappers/sdl/sdl_mixer_nosmpeg.nim6
-rwxr-xr-xlib/wrappers/sdl/sdl_net.nim6
-rwxr-xr-xlib/wrappers/sdl/sdl_ttf.nim6
-rwxr-xr-xlib/wrappers/sdl/smpeg.nim6
-rwxr-xr-xlib/wrappers/zip/zlib.nim9
-rwxr-xr-xtests/compile/tnewlibs.nim2
-rwxr-xr-xtodo.txt13
-rwxr-xr-xweb/news.txt7
42 files changed, 642 insertions, 260 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 511d6f116..e3528dece 100755
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -224,7 +224,8 @@ type
     sfMainModule,     # module is the main module
     sfSystemModule,   # module is the system module
     sfNoReturn,       # proc never returns (an exit proc)
-    sfAddrTaken,      # the variable's address is taken (ex- or implicitely)
+    sfAddrTaken,      # the variable's address is taken (ex- or implicitely);
+                      # *OR*: a proc is indirectly called (used as first class)
     sfCompilerProc,   # proc is a compiler proc, that is a C proc that is
                       # needed for the code generator
     sfProcvar,        # proc can be passed to a proc var
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 1e1bf8072..78a107bbb 100755
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -1037,8 +1037,9 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
   InitLocExpr(p, e.sons[1], a)
   var t = skipTypes(e.sons[1].typ, abstractVarRange)
   case t.kind
-  of tyInt..tyInt64:
-    putIntoDest(p, d, e.typ, ropecg(p.module, "#reprInt($1)", [rdLoc(a)]))
+  of tyInt..tyInt64, tyUInt..tyUInt64:
+    putIntoDest(p, d, e.typ, 
+                ropecg(p.module, "#reprInt((NI64)$1)", [rdLoc(a)]))
   of tyFloat..tyFloat128:
     putIntoDest(p, d, e.typ, ropecg(p.module, "#reprFloat($1)", [rdLoc(a)]))
   of tyBool:
diff --git a/compiler/ecmasgen.nim b/compiler/ecmasgen.nim
index 30a697d8e..9b3601ae4 100755
--- a/compiler/ecmasgen.nim
+++ b/compiler/ecmasgen.nim
@@ -1066,7 +1066,8 @@ proc createVar(p: var TProc, typ: PType, indirect: bool): PRope =
     result = nil
 
 proc isIndirect(v: PSym): bool = 
-  result = (sfAddrTaken in v.flags) and (mapType(v.typ) != etyObject)
+  result = (sfAddrTaken in v.flags) and (mapType(v.typ) != etyObject) and
+    v.kind notin {skProc, skConverter, skMethod, skIterator}
 
 proc genVarInit(p: var TProc, v: PSym, n: PNode, r: var TCompRes) = 
   var 
diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim
index 09c99c027..fcfc35ff1 100755
--- a/compiler/magicsys.nim
+++ b/compiler/magicsys.nim
@@ -74,24 +74,51 @@ proc getSysType(kind: TTypeKind): PType =
     InternalError("wanted: " & $kind & " got: " & $result.kind)
   if result == nil: InternalError("type not found: " & $kind)
 
-when false:
-  var
-    intTypeCache: array[-5..64, PType]
+var
+  intTypeCache: array[-5..64, PType]
 
-  proc getIntLitType*(literal: PNode): PType =
-    # we cache some common integer literal types for performance:
-    let value = literal.intVal
-    if value >= low(intTypeCache) and value <= high(intTypeCache):
-      result = intTypeCache[value.int]
-      if result == nil:
-        let ti = getSysType(tyInt)
-        result = copyType(ti, ti.owner, false)
-        result.n = literal
-        intTypeCache[value.int] = result
-    else:
+proc getIntLitType*(literal: PNode): PType =
+  # we cache some common integer literal types for performance:
+  let value = literal.intVal
+  if value >= low(intTypeCache) and value <= high(intTypeCache):
+    result = intTypeCache[value.int]
+    if result == nil:
       let ti = getSysType(tyInt)
       result = copyType(ti, ti.owner, false)
       result.n = literal
+      intTypeCache[value.int] = result
+  else:
+    let ti = getSysType(tyInt)
+    result = copyType(ti, ti.owner, false)
+    result.n = literal
+
+proc setIntLitType*(result: PNode) =
+  let i = result.intVal
+  case platform.IntSize
+  of 8: result.typ = getIntLitType(result)
+  of 4:
+    if i >= low(int32) and i <= high(int32):
+      result.typ = getIntLitType(result)
+    else:
+      result.typ = getSysType(tyInt64)
+  of 2:
+    if i >= low(int16) and i <= high(int16):
+      result.typ = getIntLitType(result)
+    elif i >= low(int32) and i <= high(int32):
+      result.typ = getSysType(tyInt32)
+    else:
+      result.typ = getSysType(tyInt64)
+  of 1:
+    # 8 bit CPUs are insane ...
+    if i >= low(int8) and i <= high(int8):
+      result.typ = getIntLitType(result)
+    elif i >= low(int16) and i <= high(int16):
+      result.typ = getSysType(tyInt16)
+    elif i >= low(int32) and i <= high(int32):
+      result.typ = getSysType(tyInt32)
+    else:
+      result.typ = getSysType(tyInt64)
+  else: InternalError(result.info, "invalid int size")
 
 proc getCompilerProc(name: string): PSym = 
   var ident = getIdent(name, hashIgnoreStyle(name))
diff --git a/compiler/saturate.nim b/compiler/saturate.nim
new file mode 100644
index 000000000..e0968843b
--- /dev/null
+++ b/compiler/saturate.nim
@@ -0,0 +1,79 @@
+#
+#
+#           The Nimrod Compiler
+#        (c) Copyright 2012 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## Saturated arithmetic routines. XXX Make part of the stdlib?
+
+proc `|+|`*(a, b: biggestInt): biggestInt =
+  ## saturated addition.
+  result = a +% b
+  if (result xor a) >= 0'i64 or (result xor b) >= 0'i64:
+    return result
+  if a < 0 or b < 0:
+    result = low(result)
+  else:
+    result = high(result)
+
+proc `|-|`*(a, b: biggestInt): biggestInt =
+  result = a -% b
+  if (result xor a) >= 0'i64 or (result xor not b) >= 0'i64:
+    return result
+  if b > 0:
+    result = low(result)
+  else:
+    result = high(result)
+
+proc `|abs|`*(a: biggestInt): biggestInt =
+  if a != low(a):
+    if a >= 0: result = a
+    else: result = -a
+  else:
+    result = low(a)
+
+proc `|div|`*(a, b: biggestInt): biggestInt =
+  # (0..5) div (0..4) == (0..5) div (1..4) == (0 div 4) .. (5 div 1)
+  if b == 0'i64:
+    # make the same as ``div 1``:
+    result = a
+  elif a == low(a) and b == -1'i64:
+    result = high(result)
+  else:
+    result = a div b
+
+proc `|mod|`*(a, b: biggestInt): biggestInt =
+  if b == 0'i64:
+    result = a
+  else:
+    result = a mod b
+
+proc `|*|`*(a, b: biggestInt): biggestInt =
+  var
+    resAsFloat, floatProd: float64
+  result = a *% b
+  floatProd = toBiggestFloat(a) # conversion
+  floatProd = floatProd * toBiggestFloat(b)
+  resAsFloat = toBiggestFloat(result)
+
+  # Fast path for normal case: small multiplicands, and no info
+  # is lost in either method.
+  if resAsFloat == floatProd: return result
+
+  # Somebody somewhere lost info. Close enough, or way off? Note
+  # that a != 0 and b != 0 (else resAsFloat == floatProd == 0).
+  # The difference either is or isn't significant compared to the
+  # true value (of which floatProd is a good approximation).
+
+  # abs(diff)/abs(prod) <= 1/32 iff
+  #   32 * abs(diff) <= abs(prod) -- 5 good bits is "close enough"
+  if 32.0 * abs(resAsFloat - floatProd) <= abs(floatProd):
+    return result
+  
+  if floatProd >= 0.0:
+    result = high(result)
+  else:
+    result = low(result)
diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index f0c9f42b0..8ba582a33 100755
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -18,8 +18,8 @@ proc sameMethodDispatcher(a, b: PSym): bool =
     if aa.kind == nkSym and bb.kind == nkSym and aa.sym == bb.sym: 
       result = true
   
-proc resolveOverloads(c: PContext, n, orig: PNode,
-                         filter: TSymKinds): TCandidate =
+proc resolveOverloads(c: PContext, n, orig: PNode, 
+                      filter: TSymKinds): TCandidate =
   var initialBinding: PNode
   var f = n.sons[0]
   if f.kind == nkBracketExpr:
@@ -67,9 +67,17 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
       not sameMethodDispatcher(best.calleeSym, alt.calleeSym):
     if best.state != csMatch:
       InternalError(n.info, "x.state is not csMatch")
+    #writeMatches(best)
+    #writeMatches(alt)
+    var args = "("
+    for i in countup(1, sonsLen(n) - 1):
+      if i > 1: add(args, ", ")
+      add(args, typeToString(n.sons[i].typ))
+    add(args, ")")
+
     LocalError(n.Info, errGenerated, msgKindToString(errAmbiguousCallXYZ) % [
       getProcHeader(best.calleeSym), getProcHeader(alt.calleeSym),
-      best.calleeSym.Name.s])
+      args])
 
 proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
   assert x.state == csMatch
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index c28c8c7a1..9eff8c4f4 100755
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -213,6 +213,11 @@ proc markUsed*(n: PNode, s: PSym) =
     if sfDeprecated in s.flags: Message(n.info, warnDeprecated, s.name.s)
     if sfError in s.flags: LocalError(n.info, errWrongSymbolX, s.name.s)
 
+proc markIndirect*(c: PContext, s: PSym) =
+  if s.kind in {skProc, skConverter, skMethod, skIterator}:
+    incl(s.flags, sfAddrTaken)
+    # XXX add to 'c' for global analysis
+
 proc useSym*(sym: PSym): PNode =
   result = newSymNode(sym)
   markUsed(result, sym)
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 22af8b4e0..7aa723c52 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -74,8 +74,10 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
         smoduleId != c.module.id and smoduleId != c.friendModule.id: 
       LocalError(n.info, errXCannotBePassedToProcVar, s.name.s)
     result = symChoice(c, n, s)
-    if result.kind == nkSym and isGenericRoutine(result.sym):
-      LocalError(n.info, errInstantiateXExplicitely, s.name.s)
+    if result.kind == nkSym:
+      markIndirect(c, result.sym)
+      if isGenericRoutine(result.sym):
+        LocalError(n.info, errInstantiateXExplicitely, s.name.s)
   of skConst:
     markUsed(n, s)
     case skipTypes(s.typ, abstractInst).kind
@@ -129,10 +131,11 @@ proc checkConversionBetweenObjects(info: TLineInfo, castDest, src: PType) =
   if diff == high(int):
     GlobalError(info, errGenerated, MsgKindToString(errIllegalConvFromXtoY) % [
         src.typeToString, castDest.typeToString])
-  
+
+const 
+  IntegralTypes = {tyBool, tyEnum, tyChar, tyInt..tyUInt64}
+
 proc checkConvertible(info: TLineInfo, castDest, src: PType) = 
-  const 
-    IntegralTypes = {tyBool, tyEnum, tyChar, tyInt..tyUInt64}
   if sameType(castDest, src) and castDest.sym == src.sym: 
     # don't annoy conversions that may be needed on another processor:
     if castDest.kind notin {tyInt..tyUInt64, tyNil}:
@@ -177,8 +180,8 @@ proc isCastable(dst, src: PType): bool =
     result = false
   else: 
     result = (ds >= ss) or
-        (skipTypes(dst, abstractInst).kind in {tyInt..tyFloat128}) or
-        (skipTypes(src, abstractInst).kind in {tyInt..tyFloat128})
+        (skipTypes(dst, abstractInst).kind in IntegralTypes) or
+        (skipTypes(src, abstractInst).kind in IntegralTypes)
   
 proc semConv(c: PContext, n: PNode, s: PSym): PNode = 
   if sonsLen(n) != 2: GlobalError(n.info, errConvNeedsOneArg)
@@ -190,10 +193,12 @@ proc semConv(c: PContext, n: PNode, s: PSym): PNode =
   if op.kind != nkSymChoice: 
     checkConvertible(result.info, result.typ, op.typ)
   else: 
-    for i in countup(0, sonsLen(op) - 1): 
-      if sameType(result.typ, op.sons[i].typ): 
-        markUsed(n, op.sons[i].sym)
-        return op.sons[i]
+    for i in countup(0, sonsLen(op) - 1):
+      let it = op.sons[i]
+      if sameType(result.typ, it.typ): 
+        markUsed(n, it.sym)
+        markIndirect(c, it.sym)
+        return it
     localError(n.info, errUseQualifier, op.sons[0].sym.name.s)
 
 proc semCast(c: PContext, n: PNode): PNode = 
@@ -222,7 +227,7 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
       n.typ = getSysType(tyInt)
     of tyArrayConstr, tyArray: 
       n.typ = n.sons[1].typ.sons[0] # indextype
-    of tyInt..tyInt64, tyChar, tyBool, tyEnum: 
+    of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32: 
       n.typ = n.sons[1].typ
     else: GlobalError(n.info, errInvalidArgForX, opToStr[m])
   result = n
@@ -498,6 +503,24 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
   if n.kind notin nkCallKinds or n.sons[0].kind != nkSym: return
   var callee = n.sons[0].sym
   
+  # constant folding that is necessary for correctness of semantic pass:
+  if callee.magic != mNone and callee.magic in ctfeWhitelist and n.typ != nil:
+    var call = newNodeIT(nkCall, n.info, n.typ)
+    call.add(n.sons[0])
+    var allConst = true
+    for i in 1 .. < n.len:
+      let a = getConstExpr(c.module, n.sons[i])
+      if a != nil: call.add(a)
+      else:
+        allConst = false
+        call.add(n.sons[i])
+    if allConst:
+      result = semfold.getConstExpr(c.module, call)
+      if result.isNil: result = n
+      else: return result
+    result.typ = semfold.getIntervalType(callee.magic, call)
+    
+  # optimization pass: not necessary for correctness of the semantic pass
   if {sfNoSideEffect, sfCompileTime} * callee.flags != {} and
      {sfForward, sfImportc} * callee.flags == {}:
     if sfCompileTime notin callee.flags and 
@@ -901,7 +924,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
     if skipTypes(n.sons[1].typ, {tyGenericInst, tyRange, tyOrdinal}).kind in
         {tyInt..tyInt64}: 
       var idx = getOrdValue(n.sons[1])
-      if (idx >= 0) and (idx < sonsLen(arr)): n.typ = arr.sons[int(idx)]
+      if idx >= 0 and idx < sonsLen(arr): n.typ = arr.sons[int(idx)]
       else: GlobalError(n.info, errInvalidIndexValueForTuple)
     else: 
       GlobalError(n.info, errIndexTypesDoNotMatch)
@@ -1301,15 +1324,9 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
     nil
   of nkNilLit: 
     result.typ = getSysType(tyNil)
-  of nkIntLit: 
-    # XXX this is stupid:
-    if result.typ == nil: 
-      let i = result.intVal
-      if i >= low(int32) and i <= high(int32):
-        result.typ = getSysType(tyInt)
-      else:
-        result.typ = getSysType(tyInt64)
-  of nkInt8Lit: 
+  of nkIntLit:
+    if result.typ == nil: setIntLitType(result)
+  of nkInt8Lit:
     if result.typ == nil: result.typ = getSysType(tyInt8)
   of nkInt16Lit: 
     if result.typ == nil: result.typ = getSysType(tyInt16)
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index ce9e03513..061a29fad 100755
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -13,7 +13,7 @@
 import 
   strutils, lists, options, ast, astalgo, trees, treetab, nimsets, times, 
   nversion, platform, math, msgs, os, condsyms, idents, renderer, types,
-  commands, magicsys
+  commands, magicsys, saturate
 
 proc getConstExpr*(m: PSym, n: PNode): PNode
   # evaluates the constant expression or returns nil if it is no constant
@@ -26,12 +26,19 @@ proc newStrNodeT*(strVal: string, n: PNode): PNode
 
 # implementation
 
-proc newIntNodeT(intVal: BiggestInt, n: PNode): PNode = 
-  if skipTypes(n.typ, abstractVarRange).kind == tyChar: 
+proc newIntNodeT(intVal: BiggestInt, n: PNode): PNode =
+  case skipTypes(n.typ, abstractVarRange).kind
+  of tyInt:
+    result = newIntNode(nkIntLit, intVal)
+    result.typ = getIntLitType(result)
+    # hrm, this is not correct: 1 + high(int) shouldn't produce tyInt64 ...
+    #setIntLitType(result)
+  of tyChar:
     result = newIntNode(nkCharLit, intVal)
-  else: 
+    result.typ = n.typ
+  else:
     result = newIntNode(nkIntLit, intVal)
-  result.typ = n.typ
+    result.typ = n.typ
   result.info = n.info
 
 proc newFloatNodeT(floatVal: BiggestFloat, n: PNode): PNode = 
@@ -67,6 +74,150 @@ proc ordinalValToString(a: PNode): string =
   else:
     result = $x
 
+proc isFloatRange(t: PType): bool {.inline.} =
+  result = t.kind == tyRange and t.sons[0].kind in {tyFloat..tyFloat128}
+
+proc isIntRange(t: PType): bool {.inline.} =
+  result = t.kind == tyRange and t.sons[0].kind in {
+      tyInt..tyInt64, tyUInt8..tyUInt32}
+
+proc pickIntRange(a, b: PType): PType =
+  if isIntRange(a): result = a
+  elif isIntRange(b): result = b
+  else: result = a
+
+proc isIntRangeOrLit(t: PType): bool =
+  result = isIntRange(t) or isIntLit(t)
+
+proc pickMinInt(n: PNode): biggestInt =
+  if n.kind in {nkIntLit..nkUInt64Lit}:
+    result = n.intVal
+  elif isIntLit(n.typ):
+    result = n.typ.n.intVal
+  elif isIntRange(n.typ):
+    result = firstOrd(n.typ)
+  else:
+    InternalError(n.info, "pickMinInt")
+
+proc pickMaxInt(n: PNode): biggestInt =
+  if n.kind in {nkIntLit..nkUInt64Lit}:
+    result = n.intVal
+  elif isIntLit(n.typ):
+    result = n.typ.n.intVal
+  elif isIntRange(n.typ):
+    result = lastOrd(n.typ)
+  else:
+    InternalError(n.info, "pickMaxInt")
+
+proc makeRange(typ: PType, first, last: biggestInt): PType = 
+  var n = newNode(nkRange)
+  addSon(n, newIntNode(nkIntLit, min(first, last)))
+  addSon(n, newIntNode(nkIntLit, max(first, last)))
+  result = newType(tyRange, typ.owner)
+  result.n = n
+  addSon(result, skipTypes(typ, {tyRange}))
+
+proc makeRangeF(typ: PType, first, last: biggestFloat): PType =
+  var n = newNode(nkRange)
+  addSon(n, newFloatNode(nkFloatLit, min(first.float, last.float)))
+  addSon(n, newFloatNode(nkFloatLit, max(first.float, last.float)))
+  result = newType(tyRange, typ.owner)
+  result.n = n
+  addSon(result, skipTypes(typ, {tyRange}))
+
+proc getIntervalType*(m: TMagic, n: PNode): PType =
+  # Nimrod requires interval arithmetic for ``range`` types. Lots of tedious
+  # work but the feature is very nice for reducing explicit conversions.
+  result = n.typ
+  
+  template commutativeOp(opr: expr) {.immediate.} =
+    let a = n.sons[1]
+    let b = n.sons[2]
+    if isIntRangeOrLit(a.typ) and isIntRangeOrLit(b.typ):
+      result = makeRange(pickIntRange(a.typ, b.typ),
+                         opr(pickMinInt(a), pickMinInt(b)),
+                         opr(pickMaxInt(a), pickMaxInt(b)))
+  
+  template binaryOp(opr: expr) {.immediate.} =
+    let a = n.sons[1]
+    let b = n.sons[2]
+    if isIntRange(a.typ) and b.kind in {nkIntLit..nkUInt64Lit}:
+      result = makeRange(a.typ,
+                         opr(pickMinInt(a), pickMinInt(b)),
+                         opr(pickMaxInt(a), pickMaxInt(b)))
+  
+  case m
+  of mUnaryMinusI, mUnaryMinusI64:
+    let a = n.sons[1].typ
+    if isIntRange(a):
+      # (1..3) * (-1) == (-3.. -1)
+      result = makeRange(a, 0|-|lastOrd(a), 0|-|firstOrd(a))
+  of mUnaryMinusF64:
+    let a = n.sons[1].typ
+    if isFloatRange(a):
+      result = makeRangeF(a, -getFloat(a.n.sons[1]),
+                             -getFloat(a.n.sons[0]))
+  of mAbsF64:
+    let a = n.sons[1].typ
+    if isFloatRange(a):
+      # abs(-5.. 1) == (1..5)
+      result = makeRangeF(a, abs(getFloat(a.n.sons[1])),
+                             abs(getFloat(a.n.sons[0])))
+  of mAbsI, mAbsI64:
+    let a = n.sons[1].typ
+    if isIntRange(a):
+      result = makeRange(a, `|abs|`(getInt(a.n.sons[1])),
+                            `|abs|`(getInt(a.n.sons[0])))
+  of mSucc:
+    let a = n.sons[1].typ
+    let b = n.sons[2].typ
+    if isIntRange(a) and isIntLit(b):
+      # (-5.. 1) + 6 == (-5 + 6)..(-1 + 6)
+      result = makeRange(a, pickMinInt(n.sons[1]) |+| pickMinInt(n.sons[2]),
+                            pickMaxInt(n.sons[1]) |+| pickMaxInt(n.sons[2]))
+  of mPred:
+    let a = n.sons[1].typ
+    let b = n.sons[2].typ
+    if isIntRange(a) and isIntLit(b):
+      result = makeRange(a, pickMinInt(n.sons[1]) |-| pickMinInt(n.sons[2]),
+                            pickMaxInt(n.sons[1]) |-| pickMaxInt(n.sons[2]))
+  of mAddI, mAddI64, mAddU, mAddU64:
+    commutativeOp(`|+|`)
+  of mMulI, mMulI64, mMulU, mMulU64:
+    commutativeOp(`|*|`)
+  of mSubI, mSubI64, mSubU, mSubU64:
+    binaryOp(`|-|`)
+  of mBitandI, mBitandI64:
+    var a = n.sons[1]
+    var b = n.sons[2]
+    # symmetrical:
+    if b.kind notin {nkIntLit..nkUInt64Lit}: swap(a, b)
+    if b.kind in {nkIntLit..nkUInt64Lit}:
+      let x = b.intVal|+|1
+      if (x and -x) == x and x >= 0:
+        result = makeRange(a.typ, 0, b.intVal)
+  of mModI, mModI64, mModU, mModU64:
+    # so ... if you ever wondered about modulo's signedness; this defines it:
+    let a = n.sons[1]
+    let b = n.sons[2]
+    if b.kind in {nkIntLit..nkUInt64Lit}:
+      if b.intVal >= 0:
+        result = makeRange(a.typ, 0, b.intVal-1)
+      else:
+        result = makeRange(a.typ, b.intVal+1, 0)
+  of mDivI, mDivI64, mDivU, mDivU64:
+    binaryOp(`|div|`)
+  of mMinI, mMinI64:
+    commutativeOp(min)
+  of mMaxI, mMaxI64:
+    commutativeOp(max)
+  else: nil
+  
+discard """
+  mShlI, mShlI64,
+  mShrI, mShrI64, mAddF64, mSubF64, mMulF64, mDivF64, mMaxF64, mMinF64
+"""
+
 proc evalOp(m: TMagic, n, a, b, c: PNode): PNode = 
   # b and c may be nil
   result = nil
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim
index b7e890e67..e3cc7d610 100644
--- a/compiler/semmagic.nim
+++ b/compiler/semmagic.nim
@@ -40,6 +40,11 @@ proc semTypeTraits(c: PContext, n: PNode): PNode =
     # pass unmodified to evals
     result = n
 
+proc semOrd(c: PContext, n: PNode): PNode =
+  result = n
+  result.typ = makeRangeType(c, firstOrd(n.sons[1].typ),
+                                lastOrd(n.sons[1].typ), n.info)
+
 proc magicsAfterOverloadResolution(c: PContext, n: PNode, 
                                    flags: TExprFlags): PNode =
   case n[0].sym.magic
@@ -49,5 +54,6 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
     result = newStrNodeT(renderTree(n[1], {renderNoComments}), n)
     result.typ = getSysType(tyString)
   of mInstantiationInfo: result = semInstantiationInfo(c, n)
+  of mOrd: result = semOrd(c, n)
   else: result = n
 
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index c437ce2b5..10722d853 100755
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -132,7 +132,8 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
   var a = semConstExpr(c, n[1])
   var b = semConstExpr(c, n[2])
   if not sameType(a.typ, b.typ): GlobalError(n.info, errPureTypeMismatch)
-  if a.typ.kind notin {tyInt..tyInt64,tyEnum,tyBool,tyChar,tyFloat..tyFloat128}:
+  if a.typ.kind notin {tyInt..tyInt64,tyEnum,tyBool,tyChar,tyFloat..tyFloat128,
+                       tyUInt8..tyUInt32}:
     GlobalError(n.info, errOrdinalTypeExpected)
   if enumHasHoles(a.typ): 
     GlobalError(n.info, errEnumXHasHoles, a.typ.sym.name.s)
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 6819bb37f..4a7ba9587 100755
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -34,8 +34,13 @@ type
                              # for example
   
   TTypeRelation* = enum      # order is important!
-    isNone, isConvertible, isIntConv, isSubtype, 
-    isGeneric
+    isNone, isConvertible,
+    isIntConv,
+    isSubtype,
+    isSubrange,              # subrange of the wanted type; no type conversion
+                             # but apart from that counts as ``isSubtype``
+    isGeneric,
+    isFromIntLit,            # conversion *from* int literal; proven safe
     isEqual
   
 proc initCandidateAux(c: var TCandidate, callee: PType) {.inline.} = 
@@ -56,10 +61,6 @@ proc initCandidate*(c: var TCandidate, callee: PType) =
 
 proc put(t: var TIdTable, key, val: PType) {.inline.} =
   IdTablePut(t, key, val)
-  when false:
-    if val.kind == tyObject and isDefined"testme" and 
-        IdentEq(val.sym.name, "TTable"):
-      assert false
 
 proc initCandidate*(c: var TCandidate, callee: PSym, binding: PNode, calleeScope = -1) = 
   initCandidateAux(c, callee.typ)
@@ -100,7 +101,7 @@ proc cmpCandidates*(a, b: TCandidate): int =
   if (a.calleeScope != -1) and (b.calleeScope != -1):
     result = a.calleeScope - b.calleeScope
 
-proc writeMatches(c: TCandidate) = 
+proc writeMatches*(c: TCandidate) = 
   Writeln(stdout, "exact matches: " & $c.exactMatches)
   Writeln(stdout, "subtype matches: " & $c.subtypeMatches)
   Writeln(stdout, "conv matches: " & $c.convMatches)
@@ -160,15 +161,25 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
   if a.kind == f.kind: 
     result = isEqual
   else:
-    var k = skipTypes(a, {tyRange}).kind
-    if k == f.kind: result = isSubtype
-    elif k == tyInt and f.kind in {tyRange, tyInt8..tyUInt64}:
-      # and a.n != nil and a.n.intVal >= firstOrd(f) and
-      #                    a.n.intVal <= lastOrd(f):
+    let ab = skipTypes(a, {tyRange})
+    let k = ab.kind
+    if k == f.kind: result = isSubrange
+    elif k == tyInt and f.kind in {tyRange, tyInt8..tyInt64, 
+                                   tyUInt..tyUInt64} and
+        isIntLit(ab) and ab.n.intVal >= firstOrd(f) and
+                         ab.n.intVal <= lastOrd(f):
       # integer literal in the proper range; we want ``i16 + 4`` to stay an
       # ``int16`` operation so we declare the ``4`` pseudo-equal to int16
+      result = isFromIntLit
+    elif f.kind == tyInt and k in {tyInt8..tyInt32}:
       result = isIntConv
-    elif k >= min and k <= max: result = isConvertible
+    elif k >= min and k <= max: 
+      result = isConvertible
+    elif a.kind == tyRange and a.sons[0].kind in {tyInt..tyInt64, 
+                                                  tyUInt8..tyUInt32} and
+                         a.n[0].intVal >= firstOrd(f) and
+                         a.n[1].intVal <= lastOrd(f):
+      result = isConvertible
     else: result = isNone
     #elif f.kind == tyInt and k in {tyInt..tyInt32}: result = isIntConv
     #elif f.kind == tyUInt and k in {tyUInt..tyUInt32}: result = isIntConv
@@ -186,10 +197,10 @@ proc handleFloatRange(f, a: PType): TTypeRelation =
   if a.kind == f.kind: 
     result = isEqual
   else: 
-    var k = skipTypes(a, {tyRange}).kind
-    if k == f.kind: result = isSubtype
-    elif k == tyInt and f.kind >= tyFloat and f.kind <= tyFloat128:
-      result = isIntConv
+    let ab = skipTypes(a, {tyRange})
+    var k = ab.kind
+    if k == f.kind: result = isSubrange
+    elif isIntLit(ab): result = isConvertible
     elif k >= tyFloat and k <= tyFloat128: result = isConvertible
     else: result = isNone
   
@@ -229,7 +240,7 @@ proc tupleRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
 proc matchTypeClass(mapping: var TIdTable, f, a: PType): TTypeRelation =
   for i in countup(0, f.sonsLen - 1):
     let son = f.sons[i]
-    var match = son.kind == a.kind
+    var match = son.kind == skipTypes(a, {tyRange}).kind
 
     if not match:
       case son.kind
@@ -584,12 +595,17 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
   of isConvertible: 
     inc(m.convMatches)
     result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
-  of isIntConv: 
+  of isIntConv:
+    # too lazy to introduce another ``*matches`` field, so we conflate
+    # ``isIntConv`` and ``isIntLit`` here:
     inc(m.intConvMatches)
     result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
   of isSubtype: 
     inc(m.subtypeMatches)
     result = implicitConv(nkHiddenSubConv, f, copyTree(arg), m, c)
+  of isSubrange:
+    inc(m.subtypeMatches)
+    result = copyTree(arg)
   of isGeneric:
     inc(m.genericMatches)
     if m.calleeSym != nil and m.calleeSym.kind in {skMacro, skTemplate}:
@@ -601,6 +617,11 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
       if skipTypes(result.typ, abstractVar).kind in {tyTuple}:
         result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c) 
         # BUGFIX: use ``result.typ`` and not `f` here
+  of isFromIntLit:
+    # too lazy to introduce another ``*matches`` field, so we conflate
+    # ``isIntConv`` and ``isIntLit`` here:
+    inc(m.intConvMatches, 256)
+    result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
   of isEqual: 
     inc(m.exactMatches)
     result = copyTree(arg)
diff --git a/compiler/transf.nim b/compiler/transf.nim
index bf6354665..3c3ae12c9 100755
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -734,7 +734,6 @@ proc transform(c: PTransf, n: PNode): PTransNode =
   # we inline constants if they are not complex constants:
   if cnst != nil and not dontInlineConstant(n, cnst):
     result = PTransNode(cnst) # do not miss an optimization
-  warnNarrowingConversion(result.pnode)
 
 proc processTransf(context: PPassContext, n: PNode): PNode = 
   # Note: For interactive mode we cannot call 'passes.skipCodegen' and skip
diff --git a/compiler/types.nim b/compiler/types.nim
index 9b4b869e4..8005ba806 100755
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -102,6 +102,9 @@ proc getOrdValue(n: PNode): biggestInt =
     LocalError(n.info, errOrdinalTypeExpected)
     result = 0
 
+proc isIntLit*(t: PType): bool {.inline.} =
+  result = t.n != nil and t.n.kind == nkIntLit
+
 proc isCompatibleToCString(a: PType): bool = 
   if a.kind == tyArray: 
     if (firstOrd(a.sons[0]) == 0) and
@@ -400,8 +403,15 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
   result = ""
   if t == nil: return 
   if prefer == preferName and t.sym != nil and sfAnon notin t.sym.flags:
+    if t.kind == tyInt and isIntLit(t):
+      return t.sym.Name.s & "(" & $t.n.intVal & ")"
     return t.sym.Name.s
   case t.Kind
+  of tyInt:
+    if not isIntLit(t):
+      result = typeToStr[t.kind]
+    else:
+      result = "intLit(" & $t.n.intVal & ")"
   of tyGenericBody, tyGenericInst, tyGenericInvokation:
     result = typeToString(t.sons[0]) & '['
     for i in countup(1, sonsLen(t) -1 -ord(t.kind != tyGenericInvokation)):
@@ -536,7 +546,7 @@ proc lastOrd(t: PType): biggestInt =
   of tyUInt8: result = 0xFF
   of tyUInt16: result = 0xFFFF
   of tyUInt32: result = 0xFFFFFFFF
-  of tyUInt64: result = -1
+  of tyUInt64: result = 0x7FFFFFFFFFFFFFFF'i64
   of tyEnum: 
     assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
     result = t.n.sons[sonsLen(t.n) - 1].sym.position
diff --git a/doc/manual.txt b/doc/manual.txt
index 02c1294e5..f526d9d22 100755
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -570,9 +570,67 @@ operation                meaning
 

 `Automatic type conversion`:idx: is performed in expressions where different

 kinds of integer types are used: the smaller type is converted to the larger.

+
+A `narrowing type conversion`:idx: converts a larger to a smaller type (for
+example ``int32 -> int16``. A `widening type conversion`:idx: converts a 
+smaller type to a larger type (for example ``int16 -> int32``). In Nimrod only
+widening type conversion are *implicit*:
+
+.. code-block:: nimrod
+  var myInt16 = 5i16
+  var myInt: int
+  myInt16 + 34     # of type ``int16``
+  myInt16 + myInt  # of type ``int``
+  myInt16 + 2i32   # of type ``int32``
+
+However, ``int`` literals are implicitely convertible to a smaller integer type
+if the literal's value fits this smaller type and such a conversion is less
+expensive than other implicit conversions, so ``myInt16 + 34`` produces 
+an ``int16`` result.
+
 For further details, see `Convertible relation`_.

 

 

+Subrange types

+~~~~~~~~~~~~~~

+A `subrange`:idx: type is a range of values from an ordinal type (the base

+type). To define a subrange type, one must specify it's limiting values: the

+lowest and highest value of the type:

+

+.. code-block:: nimrod

+  type

+    TSubrange = range[0..5]

+

+

+``TSubrange`` is a subrange of an integer which can only hold the values 0

+to 5. Assigning any other value to a variable of type ``TSubrange`` is a

+checked runtime error (or static error if it can be statically

+determined). Assignments from the base type to one of its subrange types

+(and vice versa) are allowed.

+

+A subrange type has the same size as its base type (``int`` in the example).
+
+Nimrod requires `interval arithmetic`:idx: for subrange types over a set
+of built-in operators that involve constants: ``x mod 3`` is of 
+type ``range[0..2]``. The following built-in operators for integers are 
+affected by this rule: ``-``, ``+``, ``*``, ``min``, ``max``, ``succ``,
+``pred``, ``mod``, ``div``, ``and`` (bitwise and). 
+
+Bitwise and only produces a ``range`` if one of its operands is a 
+constant *x* so that (x+1) is a number of two.
+(Bitwise and then behaves as a ``mod`` operation.)
+
+This means that the following code is accepted:
+
+.. code-block:: nimrod
+  case (x and 3) + 7
+  of 7: echo "A"
+  of 8: echo "B"
+  of 9: echo "C"
+  of 10: echo "D"
+  # note: no ``else`` required as (x and 3) + 7 has the type: range[7..10]
+  

+

 Pre-defined floating point types

 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

@@ -729,26 +787,6 @@ ordinal value and its string value by using a tuple. It is also
 possible to only specify one of them.

 

 

-Subrange types

-~~~~~~~~~~~~~~

-A `subrange`:idx: type is a range of values from an ordinal type (the base

-type). To define a subrange type, one must specify it's limiting values: the

-lowest and highest value of the type:

-

-.. code-block:: nimrod

-  type

-    TSubrange = range[0..5]

-

-

-``TSubrange`` is a subrange of an integer which can only hold the values 0

-to 5. Assigning any other value to a variable of type ``TSubrange`` is a

-checked runtime error (or static error if it can be statically

-determined). Assignments from the base type to one of its subrange types

-(and vice versa) are allowed.

-

-A subrange type has the same size as its base type (``int`` in the example).

-

-

 String type

 ~~~~~~~~~~~

 All string literals are of the type `string`:idx:. A string in Nimrod is very

@@ -1798,7 +1836,9 @@ evaluated and if its value is in a *slicelist* the corresponding statements
 given *slicelist* the ``else`` part is executed. If there is no ``else``

 part and not all possible values that ``expr`` can hold occur in a 

 ``slicelist``, a static error occurs. This holds only for expressions of 

-ordinal types.

+ordinal types. "All possible values" of ``expr`` are determined by ``expr``'s
+type. 
+

 If the expression is not of an ordinal type, and no ``else`` part is

 given, control passes after the ``case`` statement.

 

diff --git a/lib/core/typeinfo.nim b/lib/core/typeinfo.nim
index 549e4724a..9030b7b53 100755
--- a/lib/core/typeinfo.nim
+++ b/lib/core/typeinfo.nim
@@ -59,7 +59,7 @@ type
     rawType: PNimType
 
   ppointer = ptr pointer
-  pbyteArray = ptr array[0.. 0xffff, byte]
+  pbyteArray = ptr array[0.. 0xffff, int8]
 
   TGenSeq {.pure.} = object
     len, space: int
diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim
index 506da9c84..19701f896 100755
--- a/lib/impure/db_postgres.nim
+++ b/lib/impure/db_postgres.nim
@@ -84,7 +84,7 @@ proc setupQuery(db: TDbConn, query: TSqlQuery,
   result = PQExec(db, q)
   if PQresultStatus(result) != PGRES_TUPLES_OK: dbError(db)
   
-proc setRow(res: PPGresult, r: var TRow, line, cols: int) =
+proc setRow(res: PPGresult, r: var TRow, line, cols: int32) =
   for col in 0..cols-1:
     setLen(r[col], 0)
     var x = PQgetvalue(res, line, col)
@@ -96,7 +96,7 @@ iterator FastRows*(db: TDbConn, query: TSqlQuery,
   ## fast, but potenially dangerous: If the for-loop-body executes another
   ## query, the results can be undefined. For Postgres it is safe though.
   var res = setupQuery(db, query, args)
-  var L = int(PQnfields(res))
+  var L = PQnfields(res)
   var result = newRow(L)
   for i in 0..PQntuples(res)-1:
     setRow(res, result, i, L)
@@ -107,7 +107,7 @@ proc getRow*(db: TDbConn, query: TSqlQuery,
              args: openarray[string]): TRow =
   ## retrieves a single row.
   var res = setupQuery(db, query, args)
-  var L = int(PQnfields(res))
+  var L = PQnfields(res)
   result = newRow(L)
   setRow(res, result, 0, L)
   PQclear(res)
diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim
index b6c8003b9..dbeb1e594 100755
--- a/lib/impure/db_sqlite.nim
+++ b/lib/impure/db_sqlite.nim
@@ -64,7 +64,7 @@ proc TryExec*(db: TDbConn, query: TSqlQuery,
   ## tries to execute the query and returns true if successful, false otherwise.
   var q = dbFormat(query, args)
   var stmt: sqlite3.PStmt
-  if prepare_v2(db, q, q.len, stmt, nil) == SQLITE_OK:
+  if prepare_v2(db, q, q.len.cint, stmt, nil) == SQLITE_OK:
     if step(stmt) == SQLITE_DONE:
       result = finalize(stmt) == SQLITE_OK
 
@@ -79,9 +79,9 @@ proc newRow(L: int): TRow =
 proc setupQuery(db: TDbConn, query: TSqlQuery, 
                 args: openarray[string]): PStmt = 
   var q = dbFormat(query, args)
-  if prepare_v2(db, q, q.len, result, nil) != SQLITE_OK: dbError(db)
+  if prepare_v2(db, q, q.len.cint, result, nil) != SQLITE_OK: dbError(db)
   
-proc setRow(stmt: PStmt, r: var TRow, cols: int) =
+proc setRow(stmt: PStmt, r: var TRow, cols: cint) =
   for col in 0..cols-1:
     setLen(r[col], column_bytes(stmt, col)) # set capacity
     setLen(r[col], 0)
@@ -94,7 +94,7 @@ iterator FastRows*(db: TDbConn, query: TSqlQuery,
   ## fast, but potenially dangerous: If the for-loop-body executes another
   ## query, the results can be undefined. For Sqlite it is safe though.
   var stmt = setupQuery(db, query, args)
-  var L = int(columnCount(stmt))
+  var L = (columnCount(stmt))
   var result = newRow(L)
   while step(stmt) == SQLITE_ROW: 
     setRow(stmt, result, L)
@@ -105,7 +105,7 @@ proc getRow*(db: TDbConn, query: TSqlQuery,
              args: openarray[string]): TRow =
   ## retrieves a single row.
   var stmt = setupQuery(db, query, args)
-  var L = int(columnCount(stmt))
+  var L = (columnCount(stmt))
   result = newRow(L)
   if step(stmt) == SQLITE_ROW: 
     setRow(stmt, result, L)
diff --git a/lib/impure/graphics.nim b/lib/impure/graphics.nim
index 348907f9a..1392fd903 100755
--- a/lib/impure/graphics.nim
+++ b/lib/impure/graphics.nim
@@ -35,14 +35,15 @@ type
 proc toSdlColor*(c: TColor): Sdl.TColor =
   ## Convert colors.TColor to SDL.TColor
   var x = c.extractRGB  
-  result.r = toU8(x.r)
-  result.g = toU8(x.g)
-  result.b = toU8(x.b)
+  result.r = x.r and 0xff
+  result.g = x.g and 0xff
+  result.b = x.b and 0xff
 
 proc createSdlColor*(sur: PSurface, c: TColor, alpha: int = 0): int32 =
   ## Creates a color using ``sdl.MapRGBA``.
   var x = c.extractRGB
-  return sdl.MapRGBA(sur.s.format, toU8(x.r), toU8(x.g), toU8(x.b), toU8(alpha))
+  return sdl.MapRGBA(sur.s.format, x.r and 0xff, x.g and 0xff, 
+                     x.b and 0xff, alpha and 0xff)
 
 proc toSdlRect*(r: TRect): sdl.TRect =
   ## Convert ``graphics.TRect`` to ``sdl.TRect``.
diff --git a/lib/impure/re.nim b/lib/impure/re.nim
index 1fe1582bd..f3a6e5a44 100755
--- a/lib/impure/re.nim
+++ b/lib/impure/re.nim
@@ -82,7 +82,7 @@ proc matchOrFind(s: string, pattern: TRegEx, matches: var openarray[string],
                  start, flags: cint): cint =
   var
     rawMatches: array[0..maxSubpatterns * 3 - 1, cint]
-    res = pcre.Exec(pattern.h, pattern.e, s, len(s), start, flags,
+    res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start, flags,
       cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3)
   if res < 0'i32: return res
   for i in 1..int(res)-1:
@@ -100,7 +100,7 @@ proc findBounds*(s: string, pattern: TRegEx, matches: var openarray[string],
   ## is written into `matches` and ``(-1,0)`` is returned.
   var
     rawMatches: array[0..maxSubpatterns * 3 - 1, cint]
-    res = pcre.Exec(pattern.h, pattern.e, s, len(s), start, 0'i32,
+    res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start, 0'i32,
       cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3)
   if res < 0'i32: return (-1, 0)
   for i in 1..int(res)-1:
@@ -119,7 +119,7 @@ proc findBounds*(s: string, pattern: TRegEx,
   ## ``(-1,0)`` is returned.
   var
     rawMatches: array[0..maxSubpatterns * 3 - 1, cint]
-    res = pcre.Exec(pattern.h, pattern.e, s, len(s), start, 0'i32,
+    res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start, 0'i32,
       cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3)
   if res < 0'i32: return (-1, 0)
   for i in 1..int(res)-1:
@@ -135,14 +135,14 @@ proc findBounds*(s: string, pattern: TRegEx,
   ## match, ``(-1,0)`` is returned.
   var
     rawMatches: array[0..3 - 1, cint]
-    res = pcre.Exec(pattern.h, nil, s, len(s), start, 0'i32,
+    res = pcre.Exec(pattern.h, nil, s, len(s).cint, start, 0'i32,
       cast[ptr cint](addr(rawMatches)), 3)
   if res < 0'i32: return (int(res), 0)
   return (int(rawMatches[0]), int(rawMatches[1]-1))
   
 proc matchOrFind(s: string, pattern: TRegEx, start, flags: cint): cint =
   var rawMatches: array [0..maxSubpatterns * 3 - 1, cint]
-  result = pcre.Exec(pattern.h, pattern.e, s, len(s), start, flags,
+  result = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start, flags,
                     cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3)
   if result >= 0'i32:
     result = rawMatches[1] - rawMatches[0]
@@ -180,7 +180,7 @@ proc find*(s: string, pattern: TRegEx, matches: var openarray[string],
   ## is written into ``matches`` and -1 is returned.
   var
     rawMatches: array[0..maxSubpatterns * 3 - 1, cint]
-    res = pcre.Exec(pattern.h, pattern.e, s, len(s), start, 0'i32,
+    res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start, 0'i32,
       cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3)
   if res < 0'i32: return res
   for i in 1..int(res)-1:
@@ -195,7 +195,7 @@ proc find*(s: string, pattern: TRegEx, start = 0): int =
   ## match, -1 is returned.
   var
     rawMatches: array[0..3 - 1, cint]
-    res = pcre.Exec(pattern.h, nil, s, len(s), start, 0'i32,
+    res = pcre.Exec(pattern.h, nil, s, len(s).cint, start, 0'i32,
       cast[ptr cint](addr(rawMatches)), 3)
   if res < 0'i32: return res
   return rawMatches[0]
@@ -205,7 +205,7 @@ iterator findAll*(s: string, pattern: TRegEx, start = 0): string =
   var i = int32(start)
   var rawMatches: array[0..maxSubpatterns * 3 - 1, cint]
   while true:
-    let res = pcre.Exec(pattern.h, pattern.e, s, len(s), i, 0'i32,
+    let res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, i, 0'i32,
       cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3)
     if res < 0'i32: break
     let a = rawMatches[0]
diff --git a/lib/pure/oids.nim b/lib/pure/oids.nim
index b84c3d53e..0fd1d8cd2 100644
--- a/lib/pure/oids.nim
+++ b/lib/pure/oids.nim
@@ -53,7 +53,8 @@ proc oidToString*(oid: TOid, str: cstring) =
   str[24] = '\0'
 
 var
-  incr, fuzz: int
+  incr: int 
+  fuzz: int32
 
 proc genOid*(): TOid =
   ## generates a new OID.
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index 808c0735e..6ed7e8d2c 100755
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -244,7 +244,7 @@ when defined(Windows) and not defined(useNimRtl):
     var s = PFileHandleStream(s)
     if s.atTheEnd: return 0
     var br: int32
-    var a = winlean.ReadFile(s.handle, buffer, bufLen, br, nil)
+    var a = winlean.ReadFile(s.handle, buffer, bufLen.cint, br, nil)
     # TRUE and zero bytes returned (EOF).
     # TRUE and n (>0) bytes returned (good data).
     # FALSE and bytes returned undefined (system error).
@@ -255,7 +255,7 @@ when defined(Windows) and not defined(useNimRtl):
   proc hsWriteData(s: PStream, buffer: pointer, bufLen: int) =
     var s = PFileHandleStream(s)
     var bytesWritten: int32
-    var a = winlean.writeFile(s.handle, buffer, bufLen, bytesWritten, nil)
+    var a = winlean.writeFile(s.handle, buffer, bufLen.cint, bytesWritten, nil)
     if a == 0: OSError()
 
   proc newFileHandleStream(handle: THandle): PFileHandleStream =
@@ -293,7 +293,7 @@ when defined(Windows) and not defined(useNimRtl):
 
   proc CreatePipeHandles(Rdhandle, WrHandle: var THandle) =
     var piInheritablePipe: TSecurityAttributes
-    piInheritablePipe.nlength = SizeOF(TSecurityAttributes)
+    piInheritablePipe.nlength = SizeOF(TSecurityAttributes).cint
     piInheritablePipe.lpSecurityDescriptor = nil
     piInheritablePipe.Binherithandle = 1
     if CreatePipe(Rdhandle, Wrhandle, piInheritablePipe, 1024) == 0'i32:
@@ -313,7 +313,7 @@ when defined(Windows) and not defined(useNimRtl):
       success: int
       hi, ho, he: THandle
     new(result)
-    SI.cb = SizeOf(SI)
+    SI.cb = SizeOf(SI).cint
     if poParentStreams notin options:
       SI.dwFlags = STARTF_USESTDHANDLES # STARTF_USESHOWWINDOW or
       CreatePipeHandles(SI.hStdInput, HI)
@@ -323,16 +323,16 @@ when defined(Windows) and not defined(useNimRtl):
         HE = HO
       else:
         CreatePipeHandles(HE, Si.hStdError)
-      result.inputHandle = hi
-      result.outputHandle = ho
-      result.errorHandle = he
+      result.inputHandle = TFileHandle(hi)
+      result.outputHandle = TFileHandle(ho)
+      result.errorHandle = TFileHandle(he)
     else:
       SI.hStdError = GetStdHandle(STD_ERROR_HANDLE)
       SI.hStdInput = GetStdHandle(STD_INPUT_HANDLE)
       SI.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE)
-      result.inputHandle = si.hStdInput
-      result.outputHandle = si.hStdOutput
-      result.errorHandle = si.hStdError
+      result.inputHandle = TFileHandle(si.hStdInput)
+      result.outputHandle = TFileHandle(si.hStdOutput)
+      result.errorHandle = TFileHandle(si.hStdError)
 
     var cmdl: cstring
     when false: # poUseShell in options:
@@ -394,7 +394,7 @@ when defined(Windows) and not defined(useNimRtl):
       discard TerminateProcess(p.FProcessHandle, 0)
 
   proc waitForExit(p: PProcess, timeout: int = -1): int =
-    discard WaitForSingleObject(p.FProcessHandle, timeout)
+    discard WaitForSingleObject(p.FProcessHandle, timeout.int32)
 
     var res: int32
     discard GetExitCodeProcess(p.FProcessHandle, res)
@@ -424,7 +424,7 @@ when defined(Windows) and not defined(useNimRtl):
       ProcInfo: TProcessInformation
       process: THandle
       L: int32
-    SI.cb = SizeOf(SI)
+    SI.cb = SizeOf(SI).cint
     SI.hStdError = GetStdHandle(STD_ERROR_HANDLE)
     SI.hStdInput = GetStdHandle(STD_INPUT_HANDLE)
     SI.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE)
@@ -454,7 +454,7 @@ when defined(Windows) and not defined(useNimRtl):
     for i in 0..readfds.len()-1:
       rfds[i] = readfds[i].FProcessHandle
     
-    var ret = waitForMultipleObjects(readfds.len, 
+    var ret = waitForMultipleObjects(readfds.len.int32, 
                                      addr(rfds), 0'i32, timeout)
     case ret
     of WAIT_TIMEOUT:
diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim
index 8c15c6adb..162e644d9 100755
--- a/lib/pure/sockets.nim
+++ b/lib/pure/sockets.nim
@@ -343,7 +343,7 @@ proc bindAddr*(socket: TSocket, port = TPort(0), address = "") =
     name.sin_port = sockets.htons(int16(port))
     name.sin_addr.s_addr = sockets.htonl(INADDR_ANY)
     if bindSocket(socket.fd, cast[ptr TSockAddr](addr(name)),
-                  sizeof(name)) < 0'i32:
+                  sizeof(name).TSockLen) < 0'i32:
       OSError()
   else:
     var hints: TAddrInfo
@@ -366,7 +366,7 @@ when false:
     name.sin_port = sockets.htons(int16(port))
     name.sin_addr.s_addr = sockets.htonl(INADDR_ANY)
     if bindSocket(cint(socket), cast[ptr TSockAddr](addr(name)),
-                  sizeof(name)) < 0'i32:
+                  sizeof(name).TSockLen) < 0'i32:
       OSError()
   
 proc getSockName*(socket: TSocket): TPort = 
@@ -378,7 +378,7 @@ proc getSockName*(socket: TSocket): TPort =
     name.sin_family = posix.AF_INET
   #name.sin_port = htons(cint16(port))
   #name.sin_addr.s_addr = htonl(INADDR_ANY)
-  var namelen: cint = sizeof(name)
+  var namelen = sizeof(name).TSockLen
   if getsockname(socket.fd, cast[ptr TSockAddr](addr(name)),
                  addr(namelen)) == -1'i32:
     OSError()
@@ -398,7 +398,7 @@ proc acceptAddr*(server: TSocket): tuple[client: TSocket, address: string] =
   ## **Warning:** This function might block even if socket is non-blocking
   ## when using SSL.
   var sockAddress: Tsockaddr_in
-  var addrLen: cint = sizeof(sockAddress)
+  var addrLen = sizeof(sockAddress).TSockLen
   var sock = accept(server.fd, cast[ptr TSockAddr](addr(sockAddress)),
                     addr(addrLen))
   
@@ -477,9 +477,9 @@ proc getServByName*(name, proto: string): TServent =
 proc getServByPort*(port: TPort, proto: string): TServent = 
   ## well-known getservbyport proc.
   when defined(Windows):
-    var s = winlean.getservbyport(ze(int16(port)), proto)
+    var s = winlean.getservbyport(ze(int16(port)).cint, proto)
   else:
-    var s = posix.getservbyport(ze(int16(port)), proto)
+    var s = posix.getservbyport(ze(int16(port)).cint, proto)
   if s == nil: OSError()
   result.name = $s.s_name
   result.aliases = cstringArrayToSeq(s.s_aliases)
@@ -492,11 +492,11 @@ proc getHostByAddr*(ip: string): THostEnt =
   myaddr.s_addr = inet_addr(ip)
   
   when defined(windows):
-    var s = winlean.gethostbyaddr(addr(myaddr), sizeof(myaddr),
+    var s = winlean.gethostbyaddr(addr(myaddr), sizeof(myaddr).cint,
                                   cint(sockets.AF_INET))
     if s == nil: OSError()
   else:
-    var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr), 
+    var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).cint, 
                                 cint(posix.AF_INET))
     if s == nil:
       raise newException(EOS, $hStrError(h_errno))
@@ -539,7 +539,7 @@ proc getHostByName*(name: string): THostEnt =
 proc getSockOptInt*(socket: TSocket, level, optname: int): int = 
   ## getsockopt for integer options.
   var res: cint
-  var size: cint = sizeof(res)
+  var size = sizeof(res).cint
   if getsockopt(socket.fd, cint(level), cint(optname), 
                 addr(res), addr(size)) < 0'i32:
     OSError()
@@ -549,7 +549,7 @@ proc setSockOptInt*(socket: TSocket, level, optname, optval: int) =
   ## setsockopt for integer options.
   var value = cint(optval)
   if setsockopt(socket.fd, cint(level), cint(optname), addr(value),  
-                sizeof(value)) < 0'i32:
+                sizeof(value).cint) < 0'i32:
     OSError()
 
 proc connect*(socket: TSocket, name: string, port = TPort(0), 
@@ -608,7 +608,7 @@ proc connect*(socket: TSocket, name: string, port = TPort(0),
       of AF_INET: s.sin_family = posix.AF_INET
       of AF_INET6: s.sin_family = posix.AF_INET6
       else: nil
-    if connect(socket.fd, cast[ptr TSockAddr](addr(s)), sizeof(s)) < 0'i32:
+    if connect(socket.fd, cast[ptr TSockAddr](addr(s)), sizeof(s).cint) < 0'i32:
       OSError()
 
 proc connectAsync*(socket: TSocket, name: string, port = TPort(0),
diff --git a/lib/pure/times.nim b/lib/pure/times.nim
index e6163ad8c..622c2655f 100755
--- a/lib/pure/times.nim
+++ b/lib/pure/times.nim
@@ -111,7 +111,7 @@ type
                               ## in the range 0 to 23.
     monthday*: range[1..31]   ## The day of the month, in the range 1 to 31.
     month*: TMonth            ## The current month.
-    year*: int                ## The current year.
+    year*: range[-10_000..10_000] ## The current year.
     weekday*: TWeekDay        ## The current day of the week.
     yearday*: range[0..365]   ## The number of days since January 1,
                               ## in the range 0 to 365.
@@ -122,7 +122,7 @@ type
     timezone*: int            ## The offset of the (non-DST) timezone in seconds
                               ## west of UTC.
 
-  TTimeInterval* = object
+  TTimeInterval* {.pure.} = object ## a time interval
     miliseconds*: int ## The number of miliseconds
     seconds*: int     ## The number of seconds
     minutes*: int     ## The number of minutes
@@ -150,11 +150,11 @@ proc `$` *(timeInfo: TTimeInfo): string
 proc `$` *(time: TTime): string
   ## converts a calendar time to a string representation.
 
-proc `-` *(a, b: TTime): int64{.
+proc `-`*(a, b: TTime): int64 {.
   rtl, extern: "ntDiffTime".}
   ## computes the difference of two calendar times. Result is in seconds.
 
-proc `<` * (a, b: TTime): bool {.
+proc `<`*(a, b: TTime): bool {.
   rtl, extern: "ntLtTime".} = 
   ## returns true iff ``a < b``, that is iff a happened before b.
   result = a - b < 0
@@ -175,8 +175,8 @@ proc getStartMilsecs*(): int {.deprecated.}
   ## get the miliseconds from the start of the program. **Deprecated since
   ## version 0.8.10.** Use ``epochTime`` or ``cpuTime`` instead.
 
-proc newInterval*(miliseconds, seconds, minutes, hours, days, months, 
-                  years: int = 0): TTimeInterval =
+proc initInterval*(miliseconds, seconds, minutes, hours, days, months, 
+                   years: int = 0): TTimeInterval =
   ## creates a new ``TTimeInterval``.
   result.miliseconds = miliseconds
   result.seconds = seconds
@@ -188,23 +188,20 @@ proc newInterval*(miliseconds, seconds, minutes, hours, days, months,
 
 proc isLeapYear(year: int): bool =
   if year mod 400 == 0:
-     return true
+    return true
   elif year mod 100 == 0: 
-     return false
+    return false
   elif year mod 4 == 0: 
-     return true
+    return true
   else:
-     return false
+    return false
 
 proc getDaysInMonth(month: TMonth, year: int): int =
   # http://www.dispersiondesign.com/articles/time/number_of_days_in_a_month
-  if month == mFeb: # Feb
-    if isLeapYear(year):
-      result = 29
-    else:
-      result = 28
-  elif month in [mApr, mJun, mSep, mNov]: result = 30
-  else: result = 31  
+  case month 
+  of mFeb: result = if isLeapYear(year): 29 else: 28
+  of mApr, mJun, mSep, mNov: result = 30
+  else: result = 31
 
 proc calculateSeconds(a: TTimeInfo, interval: TTimeInterval): float =
   var anew = a
@@ -228,9 +225,10 @@ proc calculateSeconds(a: TTimeInfo, interval: TTimeInterval): float =
 proc `+`*(a: TTimeInfo, interval: TTimeInterval): TTimeInfo =
   ## adds ``interval`` time.
   ##
-  ## **Note:** This has been only briefly tested and it may not be very accurate.
+  ## **Note:** This has been only briefly tested and it may not be
+  ## very accurate.
   let t = timeInfoToTime(a)
-  var secs = calculateSeconds(a, interval)
+  let secs = calculateSeconds(a, interval)
   if a.tzname == "UTC":
     result = getGMTime(TTime(float(t) + secs))
   else:
@@ -242,7 +240,7 @@ proc `-`*(a: TTimeInfo, interval: TTimeInterval): TTimeInfo =
   ## **Note:** This has been only briefly tested, it is inaccurate especially
   ## when you subtract so much that you reach the Julian calendar.
   let t = timeInfoToTime(a)
-  var secs = calculateSeconds(a, interval)
+  let secs = calculateSeconds(a, interval)
   if a.tzname == "UTC":
     result = getGMTime(TTime(float(t) - secs))
   else:
@@ -329,7 +327,7 @@ when not defined(ECMAScript):
   
   proc timeInfoToTM(t: TTimeInfo): structTM =
     const
-      weekDays: array [TWeekDay, int] = [1, 2, 3, 4, 5, 6, 0]
+      weekDays: array [TWeekDay, int8] = [1'i8,2'i8,3'i8,4'i8,5'i8,6'i8,0'i8]
     result.second = t.second
     result.minute = t.minute
     result.hour = t.hour
@@ -362,13 +360,13 @@ when not defined(ECMAScript):
     var a = t
     result = tmToTimeInfo(localtime(addr(a))[], true)
     # copying is needed anyway to provide reentrancity; thus
-    # the convertion is not expensive
+    # the conversion is not expensive
   
   proc getGMTime(t: TTime): TTimeInfo =
     var a = t
     result = tmToTimeInfo(gmtime(addr(a))[], false)
     # copying is needed anyway to provide reentrancity; thus
-    # the convertion is not expensive
+    # the conversion is not expensive
   
   proc TimeInfoToTime(timeInfo: TTimeInfo): TTime =
     var cTimeInfo = timeInfo # for C++ we have to make a copy,
diff --git a/lib/system.nim b/lib/system.nim
index e90ca56e1..69733d6a1 100755
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -182,8 +182,8 @@ when not defined(EcmaScript) and not defined(NimrodVM):
   include "system/hti"
 
 type
-  Byte* = Int8 ## this is an alias for ``int8``, that is a signed
-               ## int 8 bits wide.
+  Byte* = uInt8 ## this is an alias for ``uint8``, that is an unsigned
+                ## int 8 bits wide.
 
   Natural* = range[0..high(int)]
     ## is an int type ranging from zero to the maximum value
@@ -967,7 +967,7 @@ type
 type # these work for most platforms:
   cchar* {.importc: "char", nodecl.} = char
     ## This is the same as the type ``char`` in *C*.
-  cschar* {.importc: "signed char", nodecl.} = byte
+  cschar* {.importc: "signed char", nodecl.} = int8
     ## This is the same as the type ``signed char`` in *C*.
   cshort* {.importc: "short", nodecl.} = int16
     ## This is the same as the type ``short`` in *C*.
@@ -1156,6 +1156,10 @@ proc `$` *(x: int64): string {.magic: "Int64ToStr", noSideEffect.}
   ## The stingify operator for an integer argument. Returns `x`
   ## converted to a decimal string.
 
+proc `$` *(x: uint64): string {.noSideEffect.}
+  ## The stingify operator for an unsigned integer argument. Returns `x`
+  ## converted to a decimal string.
+
 proc `$` *(x: float): string {.magic: "FloatToStr", noSideEffect.}
   ## The stingify operator for a float argument. Returns `x`
   ## converted to a decimal string.
@@ -1177,7 +1181,7 @@ proc `$` *(x: string): string {.magic: "StrToStr", noSideEffect.}
   ## as it is. This operator is useful for generic code, so
   ## that ``$expr`` also works if ``expr`` is already a string.
 
-proc `$` *[T](x: ordinal[T]): string {.magic: "EnumToStr", noSideEffect.}
+proc `$` *[TEnum: enum](x: TEnum): string {.magic: "EnumToStr", noSideEffect.}
   ## The stingify operator for an enumeration argument. This works for
   ## any enumeration type thanks to compiler magic. If
   ## a ``$`` operator for a concrete enumeration is provided, this is
@@ -1850,7 +1854,7 @@ when not defined(EcmaScript) and not defined(NimrodVM):
   proc getFileSize*(f: TFile): int64
     ## retrieves the file size (in bytes) of `f`.
 
-  proc ReadBytes*(f: TFile, a: var openarray[byte], start, len: int): int
+  proc ReadBytes*(f: TFile, a: var openarray[int8], start, len: int): int
     ## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns
     ## the actual number of bytes that have been read which may be less than
     ## `len` (if not as many bytes are remaining), but not greater.
@@ -1865,7 +1869,7 @@ when not defined(EcmaScript) and not defined(NimrodVM):
     ## the actual number of bytes that have been read which may be less than
     ## `len` (if not as many bytes are remaining), but not greater.
 
-  proc writeBytes*(f: TFile, a: openarray[byte], start, len: int): int
+  proc writeBytes*(f: TFile, a: openarray[int8], start, len: int): int
     ## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns
     ## the number of actual written bytes, which may be less than `len` in case
     ## of an error.
diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim
index 3376b9413..7c2c234c2 100755
--- a/lib/system/ansi_c.nim
+++ b/lib/system/ansi_c.nim
@@ -71,7 +71,8 @@ proc c_fopen(filename, mode: cstring): C_TextFileStar {.
   importc: "fopen", nodecl.}
 proc c_fclose(f: C_TextFileStar) {.importc: "fclose", nodecl.}
 
-proc c_sprintf(buf, frmt: CString) {.nodecl, importc: "sprintf", varargs.}
+proc c_sprintf(buf, frmt: CString) {.nodecl, importc: "sprintf", varargs,
+                                     noSideEffect.}
   # we use it only in a way that cannot lead to security issues
 
 proc c_fread(buf: Pointer, size, n: int, f: C_BinaryFileStar): int {.
diff --git a/lib/system/repr.nim b/lib/system/repr.nim
index 83fa7aa1d..028887b4c 100755
--- a/lib/system/repr.nim
+++ b/lib/system/repr.nim
@@ -20,6 +20,11 @@ proc reprPointer(x: pointer): string {.compilerproc.} =
   c_sprintf(buf, "%p", x)
   return $buf
 
+proc `$`(x: uint64): string =
+  var buf: array [0..59, char]
+  c_sprintf(buf, "%llu", x)
+  return $buf
+
 proc reprStrAux(result: var string, s: string) =
   if cast[pointer](s) == nil:
     add result, "nil"
@@ -67,7 +72,7 @@ proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =
   result = $e & " (invalid data!)"
 
 type
-  pbyteArray = ptr array[0.. 0xffff, byte]
+  pbyteArray = ptr array[0.. 0xffff, int8]
 
 proc addSetElem(result: var string, elem: int, typ: PNimType) =
   case typ.kind
diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim
index ac0880f79..d5234e62f 100755
--- a/lib/system/sysio.nim
+++ b/lib/system/sysio.nim
@@ -222,17 +222,17 @@ proc fwrite(buf: Pointer, size, n: int, f: TFile): int {.
 proc readBuffer(f: TFile, buffer: pointer, len: int): int =
   result = fread(buffer, 1, len, f)
 
-proc ReadBytes(f: TFile, a: var openarray[byte], start, len: int): int =
+proc ReadBytes(f: TFile, a: var openarray[int8], start, len: int): int =
   result = readBuffer(f, addr(a[start]), len)
 
 proc ReadChars(f: TFile, a: var openarray[char], start, len: int): int =
   result = readBuffer(f, addr(a[start]), len)
 
-proc writeBytes(f: TFile, a: openarray[byte], start, len: int): int =
-  var x = cast[ptr array[0..1000_000_000, byte]](a)
+proc writeBytes(f: TFile, a: openarray[int8], start, len: int): int =
+  var x = cast[ptr array[0..1000_000_000, int8]](a)
   result = writeBuffer(f, addr(x[start]), len)
 proc writeChars(f: TFile, a: openarray[char], start, len: int): int =
-  var x = cast[ptr array[0..1000_000_000, byte]](a)
+  var x = cast[ptr array[0..1000_000_000, int8]](a)
   result = writeBuffer(f, addr(x[start]), len)
 proc writeBuffer(f: TFile, buffer: pointer, len: int): int =
   result = fwrite(buffer, 1, len, f)
diff --git a/lib/windows/windows.nim b/lib/windows/windows.nim
index d3ff5ad91..ff28ab255 100755
--- a/lib/windows/windows.nim
+++ b/lib/windows/windows.nim
@@ -13,8 +13,8 @@
 {.deadCodeElim: on.}

 

 type

-  WideChar* = int16

-  PWideChar* = ptr int16

+  WideChar* = uint16

+  PWideChar* = ptr uint16

 

 type  # WinNT.h -- Defines the 32-Bit Windows types and constants

   SHORT* = int16

@@ -72,7 +72,6 @@ type  # WinDef.h -- Basic Windows Type Definitions
 

   DWORD* = int32

   WINBOOL* = int32

-  BYTE* = char

   WORD* = int16

   # FLOAT* = float

   PFLOAT* = ptr FLOAT

@@ -296,13 +295,13 @@ type
 

 when defined(winUnicode):

   type

-    PTBYTE* = ptr int16

+    PTBYTE* = ptr uint16

     PTCH* = PWideChar

     PTCHAR* = PWideChar

     PTSTR* = PWideChar

 else:

   type

-    PTBYTE* = ptr int8

+    PTBYTE* = ptr byte

     PTCH* = cstring

     PTCHAR* = cstring

     PTSTR* = cstring

@@ -316,12 +315,12 @@ type
 

 when defined(winUnicode):

   type

-    TBYTE* = int16

+    TBYTE* = uint16

     TCHAR* = widechar

     BCHAR* = int16

 else:

   type

-    TBYTE* = int8

+    TBYTE* = uint8

     TCHAR* = char

     BCHAR* = int8

 type

@@ -7432,34 +7431,34 @@ type
   PDCB* = ptr DCB

 

 const

-  bm_DCB_fBinary* = 0x00000001

-  bp_DCB_fBinary* = 0

+  bm_DCB_fBinary* = 1

+  bp_DCB_fBinary* = 0'i32

   bm_DCB_fParity* = 0x00000002

-  bp_DCB_fParity* = 1

+  bp_DCB_fParity* = 1'i32

   bm_DCB_fOutxCtsFlow* = 0x00000004

-  bp_DCB_fOutxCtsFlow* = 2

+  bp_DCB_fOutxCtsFlow* = 2'i32

   bm_DCB_fOutxDsrFlow* = 0x00000008

-  bp_DCB_fOutxDsrFlow* = 3

+  bp_DCB_fOutxDsrFlow* = 3'i32

   bm_DCB_fDtrControl* = 0x00000030

-  bp_DCB_fDtrControl* = 4

+  bp_DCB_fDtrControl* = 4'i32

   bm_DCB_fDsrSensitivity* = 0x00000040

-  bp_DCB_fDsrSensitivity* = 6

+  bp_DCB_fDsrSensitivity* = 6'i32

   bm_DCB_fTXContinueOnXoff* = 0x00000080

-  bp_DCB_fTXContinueOnXoff* = 7

+  bp_DCB_fTXContinueOnXoff* = 7'i32

   bm_DCB_fOutX* = 0x00000100

-  bp_DCB_fOutX* = 8

+  bp_DCB_fOutX* = 8'i32

   bm_DCB_fInX* = 0x00000200

-  bp_DCB_fInX* = 9

+  bp_DCB_fInX* = 9'i32

   bm_DCB_fErrorChar* = 0x00000400

-  bp_DCB_fErrorChar* = 10

+  bp_DCB_fErrorChar* = 10'i32

   bm_DCB_fNull* = 0x00000800

-  bp_DCB_fNull* = 11

+  bp_DCB_fNull* = 11'i32

   bm_DCB_fRtsControl* = 0x00003000

-  bp_DCB_fRtsControl* = 12

+  bp_DCB_fRtsControl* = 12'i32

   bm_DCB_fAbortOnError* = 0x00004000

-  bp_DCB_fAbortOnError* = 14

+  bp_DCB_fAbortOnError* = 14'i32

   bm_DCB_fDummy2* = 0xFFFF8000'i32

-  bp_DCB_fDummy2* = 15

+  bp_DCB_fDummy2* = 15'i32

 

 proc fBinary*(a: var DCB): DWORD

 proc set_fBinary*(a: var DCB, fBinary: DWORD)

@@ -7575,21 +7574,21 @@ type
 

 const

   bm_COMSTAT_fCtsHold* = 0x00000001

-  bp_COMSTAT_fCtsHold* = 0

+  bp_COMSTAT_fCtsHold* = 0'i32

   bm_COMSTAT_fDsrHold* = 0x00000002

-  bp_COMSTAT_fDsrHold* = 1

+  bp_COMSTAT_fDsrHold* = 1'i32

   bm_COMSTAT_fRlsdHold* = 0x00000004

-  bp_COMSTAT_fRlsdHold* = 2

+  bp_COMSTAT_fRlsdHold* = 2'i32

   bm_COMSTAT_fXoffHold* = 0x00000008

-  bp_COMSTAT_fXoffHold* = 3

+  bp_COMSTAT_fXoffHold* = 3'i32

   bm_COMSTAT_fXoffSent* = 0x00000010

-  bp_COMSTAT_fXoffSent* = 4

+  bp_COMSTAT_fXoffSent* = 4'i32

   bm_COMSTAT_fEof* = 0x00000020

-  bp_COMSTAT_fEof* = 5

+  bp_COMSTAT_fEof* = 5'i32

   bm_COMSTAT_fTxim* = 0x00000040

-  bp_COMSTAT_fTxim* = 6

+  bp_COMSTAT_fTxim* = 6'i32

   bm_COMSTAT_fReserved* = 0xFFFFFF80'i32

-  bp_COMSTAT_fReserved* = 7

+  bp_COMSTAT_fReserved* = 7'i32

 

 proc fCtsHold*(a: var COMSTAT): DWORD

   # should be renamed to get_<x>?

@@ -9984,25 +9983,25 @@ type
 

 const

   bm_LDT_ENTRY_BaseMid* = 0x000000FF

-  bp_LDT_ENTRY_BaseMid* = 0

+  bp_LDT_ENTRY_BaseMid* = 0'i32

   bm_LDT_ENTRY_Type* = 0x00001F00

-  bp_LDT_ENTRY_Type* = 8

+  bp_LDT_ENTRY_Type* = 8'i32

   bm_LDT_ENTRY_Dpl* = 0x00006000

-  bp_LDT_ENTRY_Dpl* = 13

+  bp_LDT_ENTRY_Dpl* = 13'i32

   bm_LDT_ENTRY_Pres* = 0x00008000

-  bp_LDT_ENTRY_Pres* = 15

+  bp_LDT_ENTRY_Pres* = 15'i32

   bm_LDT_ENTRY_LimitHi* = 0x000F0000

-  bp_LDT_ENTRY_LimitHi* = 16

+  bp_LDT_ENTRY_LimitHi* = 16'i32

   bm_LDT_ENTRY_Sys* = 0x00100000

-  bp_LDT_ENTRY_Sys* = 20

+  bp_LDT_ENTRY_Sys* = 20'i32

   bm_LDT_ENTRY_Reserved_0* = 0x00200000

-  bp_LDT_ENTRY_Reserved_0* = 21

+  bp_LDT_ENTRY_Reserved_0* = 21'i32

   bm_LDT_ENTRY_Default_Big* = 0x00400000

-  bp_LDT_ENTRY_Default_Big* = 22

+  bp_LDT_ENTRY_Default_Big* = 22'i32

   bm_LDT_ENTRY_Granularity* = 0x00800000

-  bp_LDT_ENTRY_Granularity* = 23

+  bp_LDT_ENTRY_Granularity* = 23'i32

   bm_LDT_ENTRY_BaseHi* = 0xFF000000

-  bp_LDT_ENTRY_BaseHi* = 24

+  bp_LDT_ENTRY_BaseHi* = 24'i32

 

 type

   LOCALESIGNATURE* {.final, pure.} = object

@@ -22820,7 +22819,7 @@ proc SEXT_HIWORD*(L: int32): int32 =
 

 proc ZEXT_HIWORD*(L: int32): int32 =

   # return type might be wrong

-  result = ze(HIWORD(L))

+  result = HIWORD(L) and 0xffff'i32

 

 proc SEXT_LOWORD*(L: int32): int32 =

   result = LOWORD(L)

@@ -22869,13 +22868,13 @@ proc MAKEWPARAM*(L, h: int32): WPARAM =
   result = WPARAM(MAKELONG(L, h))

 

 proc GET_X_LPARAM*(lp: Windows.LParam): int32 =

-  result = int16(LOWORD(lp))

+  result = LOWORD(lp.int32)

 

 proc GET_Y_LPARAM*(lp: Windows.LParam): int32 =

-  result = int16(HIWORD(lp))

+  result = HIWORD(lp.int32)

 

 proc UNICODE_NULL*(): WCHAR =

-  result = 0'i16

+  result = 0'u16

 

 

 

@@ -23500,7 +23499,8 @@ proc ListView_EnsureVisible(hwndLV: HWND, i, fPartialOK: int32): LRESULT =
                        MAKELPARAM(fPartialOK, 0))

 

 proc ListView_FindItem(wnd: HWND, iStart: int32, lvfi: var LV_FINDINFO): int32 =

-  result = SendMessage(wnd, LVM_FINDITEM, WPARAM(iStart), cast[LPARAM](addr(lvfi)))

+  result = SendMessage(wnd, LVM_FINDITEM, WPARAM(iStart), 
+                       cast[LPARAM](addr(lvfi))).int32

 

 proc ListView_GetBkColor(wnd: HWND): LRESULT =

   result = SendMessage(wnd, LVM_GETBKCOLOR, 0, 0)

@@ -23534,7 +23534,7 @@ proc ListView_GetItemCount(wnd: HWND): LRESULT =
 

 proc ListView_GetItemPosition(hwndLV: HWND, i: int32, pt: var POINT): int32 =

   result = SendMessage(hwndLV, LVM_GETITEMPOSITION, WPARAM(int32(i)),

-                       cast[LPARAM](addr(pt)))

+                       cast[LPARAM](addr(pt))).int32

 

 proc ListView_GetItemSpacing(hwndLV: HWND, fSmall: int32): LRESULT =

   result = SendMessage(hwndLV, LVM_GETITEMSPACING, fSmall, 0)

@@ -23878,10 +23878,10 @@ proc GetLargestConsoleWindowSize(hConsoleOutput: HANDLE): COORD =
   result.x = toU16(res shr 16)

 

 proc Succeeded(Status: HRESULT): WINBOOL =

-  result = (Status and 0x80000000'i32)

+  result = (Status and 0x80000000).WinBool

 

 proc Failed(Status: HRESULT): WINBOOL =

-  result = (Status and 0x80000000'i32)

+  result = (Status and 0x80000000).WinBool

 

 proc IsError(Status: HRESULT): WINBOOL =

   result = ord((int(Status) shr 31) == SEVERITY_ERROR)

@@ -23920,7 +23920,7 @@ proc MAKELCID(LangId, SortId: int16): DWORD =
   result = toU32((ze(SortId) shl 16) or ze(LangId))

 

 proc MAKESORTLCID(LangId, SortId, SortVersion: int16): DWORD =

-  result = MAKELCID(LangId, SortId) or int(SortVersion shl 20'i32)

+  result = MAKELCID(LangId, SortId) or (SortVersion shl 20'i32)

 

 proc LANGIDFROMLCID(LocaleId: LCID): int16 =

   result = toU16(LocaleId)

diff --git a/lib/wrappers/gtk/gtk2.nim b/lib/wrappers/gtk/gtk2.nim
index 9f455e5ba..515b65002 100755
--- a/lib/wrappers/gtk/gtk2.nim
+++ b/lib/wrappers/gtk/gtk2.nim
@@ -16257,7 +16257,7 @@ proc COLUMN_REQUESTED_WIDTH*(column: PTreeViewColumn): int32 =
     MaxWidth = column.max_width
   else: 
     MaxWidth = column.requested_width
-  result = CLAMP(column.requested_width, MinWidth, MaxWidth)
+  result = CLAMP(column.requested_width, MinWidth, MaxWidth).int32
 
 proc DRAW_EXPANDERS*(tree_view: PTreeView): bool = 
   result = (not (FLAG_SET(tree_view, TREE_VIEW_IS_LIST))) and
diff --git a/lib/wrappers/gtk/pango.nim b/lib/wrappers/gtk/pango.nim
index cc6acb005..5d9fcd96f 100755
--- a/lib/wrappers/gtk/pango.nim
+++ b/lib/wrappers/gtk/pango.nim
@@ -878,10 +878,10 @@ proc get_tab*(tab_array: PTabArray, tab_index: gint,
 proc get_positions_in_pixels*(tab_array: PTabArray): gboolean{.cdecl, 
     dynlib: lib, importc: "pango_tab_array_get_positions_in_pixels".}
 proc ASCENT*(rect: TRectangle): int32 = 
-  result = - int(rect.y)
+  result = -rect.y
 
 proc DESCENT*(rect: TRectangle): int32 = 
-  result = int(rect.y) + int(rect.height)
+  result = (rect.y) + (rect.height)
 
 proc LBEARING*(rect: TRectangle): int32 = 
   result = rect.x
diff --git a/lib/wrappers/sdl/sdl.nim b/lib/wrappers/sdl/sdl.nim
index a48cb59ef..597a9b0b0 100755
--- a/lib/wrappers/sdl/sdl.nim
+++ b/lib/wrappers/sdl/sdl.nim
@@ -280,9 +280,9 @@ else:
   const 
     LibName = "libSDL.so(|.1|.0)"
 const 
-  MAJOR_VERSION* = 1'i8
-  MINOR_VERSION* = 2'i8
-  PATCHLEVEL* = 11'i8         # SDL.h constants
+  MAJOR_VERSION* = 1
+  MINOR_VERSION* = 2
+  PATCHLEVEL* = 11         # SDL.h constants
   INIT_TIMER* = 0x00000001
   INIT_AUDIO* = 0x00000010
   INIT_VIDEO* = 0x00000020
@@ -2523,8 +2523,8 @@ proc AllocSurface(flags: int32, width, height, depth: int,
                             AMask)
 
 proc MustLock(Surface: PSurface): bool = 
-  Result = ((surface[] .offset != 0) or
-      ((surface[] .flags and (HWSURFACE or ASYNCBLIT or RLEACCEL)) != 0))
+  Result = ((surface[].offset != 0) or
+      ((surface[].flags and (HWSURFACE or ASYNCBLIT or RLEACCEL)) != 0))
 
 proc LockMutex(mutex: Pmutex): int = 
   Result = mutexP(mutex)
diff --git a/lib/wrappers/sdl/sdl_image.nim b/lib/wrappers/sdl/sdl_image.nim
index cc770a07f..7df9aedd4 100755
--- a/lib/wrappers/sdl/sdl_image.nim
+++ b/lib/wrappers/sdl/sdl_image.nim
@@ -141,9 +141,9 @@ else:
   const 
     ImageLibName = "libSDL_image.so"
 const 
-  IMAGE_MAJOR_VERSION* = 1'i8
-  IMAGE_MINOR_VERSION* = 2'i8
-  IMAGE_PATCHLEVEL* = 5'i8
+  IMAGE_MAJOR_VERSION* = 1
+  IMAGE_MINOR_VERSION* = 2
+  IMAGE_PATCHLEVEL* = 5
 
 # This macro can be used to fill a version structure with the compile-time
 #  version of the SDL_image library. 
diff --git a/lib/wrappers/sdl/sdl_mixer.nim b/lib/wrappers/sdl/sdl_mixer.nim
index 09abe182f..9199a9271 100755
--- a/lib/wrappers/sdl/sdl_mixer.nim
+++ b/lib/wrappers/sdl/sdl_mixer.nim
@@ -161,9 +161,9 @@ else:
   const 
     MixerLibName = "libSDL_mixer.so"
 const 
-  MAJOR_VERSION* = 1'i8
-  MINOR_VERSION* = 2'i8
-  PATCHLEVEL* = 7'i8    # Backwards compatibility
+  MAJOR_VERSION* = 1
+  MINOR_VERSION* = 2
+  PATCHLEVEL* = 7    # Backwards compatibility
   
   CHANNELS* = 8           # Good default values for a PC soundcard
   DEFAULT_FREQUENCY* = 22050
diff --git a/lib/wrappers/sdl/sdl_mixer_nosmpeg.nim b/lib/wrappers/sdl/sdl_mixer_nosmpeg.nim
index 885e9845b..11f00e0a7 100755
--- a/lib/wrappers/sdl/sdl_mixer_nosmpeg.nim
+++ b/lib/wrappers/sdl/sdl_mixer_nosmpeg.nim
@@ -15,9 +15,9 @@ else:
   const 
     MixerLibName = "libSDL_mixer.so"
 const 
-  MAJOR_VERSION* = 1'i8
-  MINOR_VERSION* = 2'i8
-  PATCHLEVEL* = 7'i8    # Backwards compatibility
+  MAJOR_VERSION* = 1
+  MINOR_VERSION* = 2
+  PATCHLEVEL* = 7    # Backwards compatibility
    
   CHANNELS* = 8           # Good default values for a PC soundcard 
   DEFAULT_FREQUENCY* = 22050
diff --git a/lib/wrappers/sdl/sdl_net.nim b/lib/wrappers/sdl/sdl_net.nim
index bfd4f0a28..742a59314 100755
--- a/lib/wrappers/sdl/sdl_net.nim
+++ b/lib/wrappers/sdl/sdl_net.nim
@@ -122,9 +122,9 @@ else:
   const 
     NetLibName = "libSDL_net.so"
 const                         #* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL *
-  MAJOR_VERSION* = 1'i8
-  MINOR_VERSION* = 2'i8
-  PATCHLEVEL* = 5'i8     # SDL_Net.h constants
+  MAJOR_VERSION* = 1
+  MINOR_VERSION* = 2
+  PATCHLEVEL* = 5        # SDL_Net.h constants
                          #* Resolve a host name and port to an IP address in network form.
                          #   If the function succeeds, it will return 0.
                          #   If the host couldn't be resolved, the host portion of the returned
diff --git a/lib/wrappers/sdl/sdl_ttf.nim b/lib/wrappers/sdl/sdl_ttf.nim
index dd65af275..f501e31d8 100755
--- a/lib/wrappers/sdl/sdl_ttf.nim
+++ b/lib/wrappers/sdl/sdl_ttf.nim
@@ -165,9 +165,9 @@ else:
   const 
     ttfLibName = "libSDL_ttf.so(|.1|.0)"
 const 
-  MAJOR_VERSION* = 2'i8
-  MINOR_VERSION* = 0'i8
-  PATCHLEVEL* = 8'i8      # Backwards compatibility
+  MAJOR_VERSION* = 2
+  MINOR_VERSION* = 0
+  PATCHLEVEL* = 8      # Backwards compatibility
 
   STYLE_NORMAL* = 0x00000000
   STYLE_BOLD* = 0x00000001
diff --git a/lib/wrappers/sdl/smpeg.nim b/lib/wrappers/sdl/smpeg.nim
index a836379ac..33f317631 100755
--- a/lib/wrappers/sdl/smpeg.nim
+++ b/lib/wrappers/sdl/smpeg.nim
@@ -171,9 +171,9 @@ proc filter_deblocking*(): PFilter{.cdecl,
   # SMPEG.h
   #------------------------------------------------------------------------------
 const 
-  MAJOR_VERSION* = 0'i8
-  MINOR_VERSION* = 4'i8
-  PATCHLEVEL* = 2'i8
+  MAJOR_VERSION* = 0
+  MINOR_VERSION* = 4
+  PATCHLEVEL* = 2
 
 type 
   TVersion*{.final.} = object 
diff --git a/lib/wrappers/zip/zlib.nim b/lib/wrappers/zip/zlib.nim
index 9b49b9663..de52a06e1 100755
--- a/lib/wrappers/zip/zlib.nim
+++ b/lib/wrappers/zip/zlib.nim
@@ -160,19 +160,20 @@ proc inflateSyncPoint*(z: PZstream): int32{.cdecl, dynlib: libz,
 proc get_crc_table*(): pointer{.cdecl, dynlib: libz, importc: "get_crc_table".}
 
 proc deflateInit(strm: var TZStream, level: int32): int32 = 
-  result = deflateInitu(strm, level, ZLIB_VERSION(), sizeof(TZStream))
+  result = deflateInitu(strm, level, ZLIB_VERSION(), sizeof(TZStream).cint)
 
 proc inflateInit(strm: var TZStream): int32 = 
-  result = inflateInitu(strm, ZLIB_VERSION(), sizeof(TZStream))
+  result = inflateInitu(strm, ZLIB_VERSION(), sizeof(TZStream).cint)
 
 proc deflateInit2(strm: var TZStream, 
                   level, `method`, windowBits, memLevel,
                   strategy: int32): int32 = 
   result = deflateInit2u(strm, level, `method`, windowBits, memLevel, 
-                         strategy, ZLIB_VERSION(), sizeof(TZStream))
+                         strategy, ZLIB_VERSION(), sizeof(TZStream).cint)
 
 proc inflateInit2(strm: var TZStream, windowBits: int32): int32 = 
-  result = inflateInit2u(strm, windowBits, ZLIB_VERSION(), sizeof(TZStream))
+  result = inflateInit2u(strm, windowBits, ZLIB_VERSION(), 
+                         sizeof(TZStream).cint)
 
 proc zlibAllocMem*(AppData: Pointer, Items, Size: int): Pointer {.cdecl.} = 
   result = Alloc(Items * Size)
diff --git a/tests/compile/tnewlibs.nim b/tests/compile/tnewlibs.nim
index aca2e3c30..b208b78dd 100755
--- a/tests/compile/tnewlibs.nim
+++ b/tests/compile/tnewlibs.nim
@@ -10,7 +10,7 @@ import
   osproc,
   cairowin32, cairoxlib,
   gl, glut, glu, glx, glext, wingl,
-  lua, lualib, lauxlib, mysql, sqlite3, 
+  lua, lualib, lauxlib, mysql, sqlite3, db_mongo
   
 
 writeln(stdout, "test compilation of binding modules")
diff --git a/todo.txt b/todo.txt
index e32c03ee6..603c2d1ad 100755
--- a/todo.txt
+++ b/todo.txt
@@ -1,12 +1,11 @@
 version 0.9.0
 =============
 
+- deprecate ``var x, y = 0`` as it's confusing for tuple consistency
 - finish support for unsigned ints:
-  - document new type conversion rules
+  - support more unsigned operations
   - test codegen
-  - provide ``$`` for unsigned ints
 
-Debug GC session:
 - test sequence of closures; especially that the GC does not leak for those!
 
 New pragmas:
@@ -15,8 +14,6 @@ New pragmas:
 - document destructors
 
 - ``borrow`` needs to take type classes into account
-- make templates hygienic by default: try to gensym() everything in the 'block'
-  of a template; find a better solution for gensym instead of `*ident`
 - introduce ``;`` to the parser
 - make use of ``tyIter`` to fix the implicit items/pairs issue
 - ``=`` should be overloadable; requires specialization for ``=``
@@ -50,7 +47,10 @@ version 0.9.XX
   - document it
   - fix exception handling
 
+- make templates hygienic by default: try to gensym() everything in the 'block'
+  of a template; find a better solution for gensym instead of `*ident`
 - document nimdoc properly finally
+- make 'clamp' a magic for the range stuff
 - implement a warning message for shadowed 'result' variable
 - implement the high level optimizer
 - change overloading resolution
@@ -101,7 +101,7 @@ Library
     newSeq(result, a.len)
     for i in 0..a.len-1: result[i] = a[i]
     
-  --> ensure @[] calls the array version!
+  --> ensure @[] still calls the array version!
 
 
 Low priority
@@ -147,7 +147,6 @@ Further optimization ideas
 Version 2 and beyond
 ====================
 
-
 - shared memory heap: ``shared ref`` etc. The only hard part in the GC is to
   "stop the world". However, it may be worthwhile to generate explicit 
   (or implicit) syncGC() calls in loops. Automatic loop injection seems
diff --git a/web/news.txt b/web/news.txt
index d4a03488c..5529a9e33 100755
--- a/web/news.txt
+++ b/web/news.txt
@@ -87,7 +87,11 @@ Changes affecting backwards compatibility
 - Deprecated the ``ssl`` module.
 - Deprecated ``nimrod pretty`` as it never worked good enough and has some
   inherent problems.
-- The integer promotion rules changed.
+- The integer promotion rules changed; the compiler is now less picky in some
+  situations and more picky in other situations: In particular implicit 
+  conversions from ``int`` to ``int32`` are now forbidden.
+- ``system.byte`` is now an alias for ``uint8``; it used to be an alias 
+  to ``int8``.
 
 
 Compiler Additions
@@ -123,6 +127,7 @@ Language Additions
 - The apostrophe in type suffixes for numerical literal is now optional.
 - Unsigned integer types have been added.
 - The integer promotion rules changed.
+- Nimrod now tracks proper intervals for ``range`` over some built-in operators.
 
 
 2012-02-09 Version 0.8.14 released