summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xcompiler/ast.nim3
-rwxr-xr-xcompiler/ccgexprs.nim8
-rwxr-xr-xcompiler/cgmeth.nim2
-rwxr-xr-xcompiler/evals.nim6
-rwxr-xr-xcompiler/msgs.nim10
-rwxr-xr-xcompiler/parser.nim2
-rwxr-xr-xcompiler/semexprs.nim24
-rwxr-xr-xcompiler/semtypes.nim7
-rwxr-xr-xcompiler/types.nim3
-rwxr-xr-xdoc/grammar.txt2
-rwxr-xr-xdoc/manual.txt32
-rwxr-xr-xdoc/tut2.txt4
-rwxr-xr-xinstall.sh164
-rwxr-xr-xlib/system.nim3
-rwxr-xr-xlib/system/excpt.nim2
-rw-r--r--tests/accept/run/teventemitter.nim2
-rwxr-xr-xtests/accept/run/tofopr.nim (renamed from tests/accept/run/tisopr.nim)4
-rwxr-xr-xtodo.txt4
-rwxr-xr-xweb/news.txt5
19 files changed, 85 insertions, 202 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 58ef9f6c2..817b37d60 100755
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -310,7 +310,7 @@ type
   TSymKinds* = set[TSymKind]
 
   TMagic* = enum # symbols that require compiler magic:
-    mNone, mDefined, mDefinedInScope, mLow, mHigh, mSizeOf, mIs, 
+    mNone, mDefined, mDefinedInScope, mLow, mHigh, mSizeOf, mIs, mOf,
     mEcho, mShallowCopy,
     mUnaryLt, mSucc, 
     mPred, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mLengthOpenArray, 
@@ -346,6 +346,7 @@ type
     mOrdinal, mInt, mInt8, mInt16, mInt32, 
     mInt64, mFloat, mFloat32, mFloat64, mBool, mChar, mString, mCstring, 
     mPointer, mEmptySet, mIntSetBaseType, mNil, mExpr, mStmt, mTypeDesc, 
+    mVoidType,
     mIsMainModule, mCompileDate, mCompileTime, mNimrodVersion, mNimrodMajor, 
     mNimrodMinor, mNimrodPatch, mCpuEndian, mHostOS, mHostCPU, mAppType, 
     mNaN, mInf, mNegInf, 
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index e92673909..1e30df7ad 100755
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -962,7 +962,7 @@ proc genNewSeq(p: BProc, e: PNode) =
                genTypeInfo(p.module, seqType), rdLoc(b)])
   genAssignment(p, a, c, {})
 
-proc genIs(p: BProc, x: PNode, typ: PType, d: var TLoc) =
+proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
   var
     a: TLoc
     dest, t: PType
@@ -987,8 +987,8 @@ proc genIs(p: BProc, x: PNode, typ: PType, d: var TLoc) =
     r = ropecg(p.module, "#isObj($1.m_type, $2)", [r, genTypeInfo(p.module, dest)])
   putIntoDest(p, d, getSysType(tyBool), r)
 
-proc genIs(p: BProc, n: PNode, d: var TLoc) =
-  genIs(p, n.sons[1], n.sons[2].typ, d)
+proc genOf(p: BProc, n: PNode, d: var TLoc) =
+  genOf(p, n.sons[1], n.sons[2].typ, d)
 
 proc genNewFinalize(p: BProc, e: PNode) =
   var
@@ -1438,7 +1438,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
       filen = makeCString(ToFilename(e.info))
       appcg(p, cpsStmts, "#internalAssert($1, $2, $3);$n",
            [filen, line, rdLoc(d)])
-  of mIs: genIs(p, e, d)
+  of mOf: genOf(p, e, d)
   of mNew: genNew(p, e)
   of mNewFinalize: genNewFinalize(p, e)
   of mNewSeq: genNewSeq(p, e)
diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim
index dd1ab944e..2751e0900 100755
--- a/compiler/cgmeth.nim
+++ b/compiler/cgmeth.nim
@@ -127,7 +127,7 @@ proc genDispatcher(methods: TSymSeq, relevantCols: TIntSet): PSym =
   var paramLen = sonsLen(base.typ)
   var disp = newNodeI(nkIfStmt, base.info)
   var ands = getSysSym("and")
-  var iss = getSysSym("is")
+  var iss = getSysSym("of")
   for meth in countup(0, high(methods)):
     var curr = methods[meth]      # generate condition:
     var cond: PNode = nil
diff --git a/compiler/evals.nim b/compiler/evals.nim
index 9aa67de3e..1ccf0d599 100755
--- a/compiler/evals.nim
+++ b/compiler/evals.nim
@@ -614,8 +614,8 @@ proc evalHigh(c: PEvalContext, n: PNode): PNode =
   of tyOpenArray, tySequence: result = newIntNodeT(sonsLen(result), n)
   of tyString: result = newIntNodeT(len(result.strVal) - 1, n)
   else: InternalError(n.info, "evalHigh")
-  
-proc evalIs(c: PEvalContext, n: PNode): PNode = 
+
+proc evalOf(c: PEvalContext, n: PNode): PNode = 
   result = evalAux(c, n.sons[1], {})
   if isSpecial(result): return 
   result = newIntNodeT(ord(inheritanceDiff(result.typ, n.sons[2].typ) >= 0), n)
@@ -755,7 +755,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
   var m = getMagic(n)
   case m
   of mNone: result = evalCall(c, n)
-  of mIs: result = evalIs(c, n)
+  of mOf: result = evalOf(c, n)
   of mSizeOf: internalError(n.info, "sizeof() should have been evaluated")
   of mHigh: result = evalHigh(c, n)
   of mAssert: result = evalAssert(c, n)
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index 27b5c7f67..c3aa30891 100755
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -82,8 +82,10 @@ type
     errInvalidIndexValueForTuple, errCommandExpectsFilename, errXExpected, 
     errInvalidSectionStart, errGridTableNotImplemented, errGeneralParseError, 
     errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile, 
-    errCannotRenderX, errVarVarTypeNotAllowed, errIsExpectsTwoArguments, 
-    errIsExpectsObjectTypes, errXcanNeverBeOfThisSubtype, errTooManyIterations, 
+    errCannotRenderX, errVarVarTypeNotAllowed, 
+    
+    errXExpectsTwoArguments, 
+    errXExpectsObjectTypes, errXcanNeverBeOfThisSubtype, errTooManyIterations, 
     errCannotInterpretNodeX, errFieldXNotFound, errInvalidConversionFromTypeX, 
     errAssertionFailed, errCannotGenerateCodeForX, errXRequiresOneArgument, 
     errUnhandledExceptionX, errCyclicTree, errXisNoMacroOrTemplate, 
@@ -298,8 +300,8 @@ const
     errXisNoValidIndexFile: "\'$1\' is no valid index file", 
     errCannotRenderX: "cannot render reStructuredText element \'$1\'", 
     errVarVarTypeNotAllowed: "type \'var var\' is not allowed",
-    errIsExpectsTwoArguments: "\'is\' expects two arguments", 
-    errIsExpectsObjectTypes: "\'is\' expects object types",
+    errXExpectsTwoArguments: "\'$1\' expects two arguments", 
+    errXExpectsObjectTypes: "\'$1\' expects object types",
     errXcanNeverBeOfThisSubtype: "\'$1\' can never be of this subtype", 
     errTooManyIterations: "interpretation requires too many iterations", 
     errCannotInterpretNodeX: "cannot interpret node kind \'$1\'", 
diff --git a/compiler/parser.nim b/compiler/parser.nim
index aca891863..003bd9219 100755
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -154,7 +154,7 @@ proc getPrecedence(tok: TToken): int =
     of '.': result = 5
     else: result = 1
   of tkDiv, tkMod, tkShl, tkShr: result = 8
-  of tkIn, tkNotIn, tkIs, tkIsNot, tkNot: result = 4
+  of tkIn, tkNotIn, tkIs, tkIsNot, tkNot, tkOf: result = 4
   of tkDotDot: result = 5
   of tkAnd: result = 3
   of tkOr, tkXor: result = 2
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 28076754f..ac375e793 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -202,20 +202,39 @@ proc semSizeof(c: PContext, n: PNode): PNode =
   n.typ = getSysType(tyInt)
   result = n
 
+proc semOf(c: PContext, n: PNode): PNode = 
+  if sonsLen(n) == 3: 
+    #LocalError(n.info, errXcanNeverBeOfThisSubtype, " CAME HERE")
+    n.sons[1] = semExprWithType(c, n.sons[1], {efAllowType})
+    n.sons[2] = semExprWithType(c, n.sons[2], {efAllowType})
+    var a = skipTypes(n.sons[1].typ, abstractPtrs)
+    var b = skipTypes(n.sons[2].typ, abstractPtrs)
+    if b.kind != tyObject or a.kind != tyObject: 
+      GlobalError(n.info, errXExpectsObjectTypes, "of")
+    while b != nil and b.id != a.id: b = b.sons[0]
+    if b == nil:
+      GlobalError(n.info, errXcanNeverBeOfThisSubtype, typeToString(a))
+    n.typ = getSysType(tyBool)
+  else: 
+    GlobalError(n.info, errXExpectsTwoArguments, "of")
+  result = n
+
 proc semIs(c: PContext, n: PNode): PNode = 
+  GlobalError(n.info, errXExpectsTwoArguments, "is")
   if sonsLen(n) == 3: 
+    #LocalError(n.info, errXcanNeverBeOfThisSubtype, " CAME HERE")
     n.sons[1] = semExprWithType(c, n.sons[1], {efAllowType})
     n.sons[2] = semExprWithType(c, n.sons[2], {efAllowType})
     var a = skipTypes(n.sons[1].typ, abstractPtrs)
     var b = skipTypes(n.sons[2].typ, abstractPtrs)
     if b.kind != tyObject or a.kind != tyObject: 
-      GlobalError(n.info, errIsExpectsObjectTypes)
+      GlobalError(n.info, errXExpectsObjectTypes, "is")
     while b != nil and b.id != a.id: b = b.sons[0]
     if b == nil:
       GlobalError(n.info, errXcanNeverBeOfThisSubtype, typeToString(a))
     n.typ = getSysType(tyBool)
   else: 
-    GlobalError(n.info, errIsExpectsTwoArguments)
+    GlobalError(n.info, errXExpectsTwoArguments, "is")
   result = n
 
 proc semOpAux(c: PContext, n: PNode) = 
@@ -884,6 +903,7 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
   of mHigh: result = semLowHigh(c, setMs(n, s), mHigh)
   of mSizeOf: result = semSizeof(c, setMs(n, s))
   of mIs: result = semIs(c, setMs(n, s))
+  of mOf: result = semOf(c, setMs(n, s))
   of mEcho: result = semEcho(c, setMs(n, s))
   of mShallowCopy:
     if sonsLen(n) == 3:
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index fb7f46007..400844902 100755
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -220,15 +220,15 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
   var 
     elem: PType
     isConcrete: bool
-  if (s.typ == nil) or (s.typ.kind != tyGenericBody): 
+  if s.typ == nil or s.typ.kind != tyGenericBody: 
     GlobalError(n.info, errCannotInstantiateX, s.name.s)
   result = newOrPrevType(tyGenericInvokation, prev, c)
-  if (s.typ.containerID == 0): InternalError(n.info, "semtypes.semGeneric")
+  if s.typ.containerID == 0: InternalError(n.info, "semtypes.semGeneric")
   if sonsLen(n) != sonsLen(s.typ): 
     GlobalError(n.info, errWrongNumberOfArguments)
   addSon(result, s.typ)
   isConcrete = true           # iterate over arguments:
-  for i in countup(1, sonsLen(n) - 1): 
+  for i in countup(1, sonsLen(n)-1): 
     elem = semTypeNode(c, n.sons[i], nil)
     if elem.kind == tyGenericParam: isConcrete = false
     addSon(result, elem)
@@ -704,6 +704,7 @@ proc processMagicType(c: PContext, m: PSym) =
   of mExpr: setMagicType(m, tyExpr, 0)
   of mStmt: setMagicType(m, tyStmt, 0)
   of mTypeDesc: setMagicType(m, tyTypeDesc, 0)
+  of mVoidType: setMagicType(m, tyEmpty, 0)
   of mArray, mOpenArray, mRange, mSet, mSeq, mOrdinal: nil 
   else: GlobalError(m.info, errTypeExpected)
   
diff --git a/compiler/types.nim b/compiler/types.nim
index 2e4262ecc..bfa20066f 100755
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -361,11 +361,10 @@ proc canFormAcycleNode(marker: var TIntSet, n: PNode, startId: int): bool =
           if result: return 
   
 proc canFormAcycleAux(marker: var TIntSet, typ: PType, startId: int): bool = 
-  var t: PType
   result = false
   if typ == nil: return 
   if tfAcyclic in typ.flags: return 
-  t = skipTypes(typ, abstractInst)
+  var t = skipTypes(typ, abstractInst)
   if tfAcyclic in t.flags: return 
   case t.kind
   of tyTuple, tyObject, tyRef, tySequence, tyArray, tyArrayConstr, tyOpenArray: 
diff --git a/doc/grammar.txt b/doc/grammar.txt
index 91d334715..3e8c89a2e 100755
--- a/doc/grammar.txt
+++ b/doc/grammar.txt
@@ -3,7 +3,7 @@ module ::= ([COMMENT] [SAD] stmt)*
 comma ::= ',' [COMMENT] [IND]
 operator ::= OP1 | OP2 | OP3 | OP4 | OP5 | OP6 | OP7 | OP8 | OP9
            | 'or' | 'xor' | 'and'
-           | 'is' | 'isnot' | 'in' | 'notin'
+           | 'is' | 'isnot' | 'in' | 'notin' | 'of'
            | 'div' | 'mod' | 'shl' | 'shr' | 'not' | '..'
 
 prefixOperator ::= operator
diff --git a/doc/manual.txt b/doc/manual.txt
index f12ed7f0c..26c69eeaa 100755
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -358,7 +358,7 @@ combination of the following characters::
        !     ?     ^     .     :     \

 

 These keywords are also operators:

-``and or not xor shl shr div mod in notin is isnot``.

+``and or not xor shl shr div mod in notin is isnot of``.

 

 `=`:tok:, `:`:tok:, `::`:tok: are not available as general operators; they

 are used for other notational purposes. 

@@ -392,19 +392,19 @@ operators, the precedence depends on the first character the operator consists
 of. All binary operators are left-associative, except binary operators starting

 with (or only consisting of) ``^``.

 

-================  ==============================================  ==================  ===============

-Precedence level    Operators                                     First characters    Terminal symbol

-================  ==============================================  ==================  ===============

-  9 (highest)                                                     ``$  ^``            OP9

-  8               ``*    /    div   mod   shl  shr  %``           ``* % \  /``        OP8

-  7               ``+    -``                                      ``+  ~  |``         OP7

-  6               ``&``                                           ``&``               OP6

-  5               ``..``                                          ``.``               OP5

-  4               ``==  <= < >= > !=  in not_in is isnot not``    ``= <  > !``        OP4

-  3               ``and``                                                             OP3

-  2               ``or xor``                                                          OP2

-  1 (lowest)                                                      `` @  : ? ``        OP1

-================  ==============================================  ==================  ===============

+================  ===============================================  ==================  ===============

+Precedence level    Operators                                      First characters    Terminal symbol

+================  ===============================================  ==================  ===============

+  9 (highest)                                                      ``$  ^``            OP9

+  8               ``*    /    div   mod   shl  shr  %``            ``* % \  /``        OP8

+  7               ``+    -``                                       ``+  ~  |``         OP7

+  6               ``&``                                            ``&``               OP6

+  5               ``..``                                           ``.``               OP5

+  4               ``==  <= < >= > !=  in not_in is isnot not of``  ``= <  > !``        OP4

+  3               ``and``                                                              OP3

+  2               ``or xor``                                                           OP2

+  1 (lowest)                                                       ``@  : ?``          OP1

+================  ===============================================  ==================  ===============

 

 

 The grammar's start symbol is ``module``.

@@ -824,7 +824,7 @@ is compatible with the way the C compiler does it.
 

 Objects provide many features that tuples do not. Object provide inheritance

 and information hiding. Objects have access to their type at runtime, so that

-the ``is`` operator can be used to determine the object's type.

+the ``of`` operator can be used to determine the object's type.

 

 .. code-block:: nimrod

 

@@ -839,7 +839,7 @@ the ``is`` operator can be used to determine the object's type.
   var

     student: TStudent

     person: TPerson

-  assert(student is TStudent) # is true

+  assert(student of TStudent) # is true

 

 Object fields that should be visible from outside the defining module, have to

 be marked by ``*``. In contrast to tuples, different object types are

diff --git a/doc/tut2.txt b/doc/tut2.txt
index ac9fd1282..5d757c28b 100755
--- a/doc/tut2.txt
+++ b/doc/tut2.txt
@@ -49,7 +49,7 @@ programmer should provide a proc to initialize the object (this is called
 a *constructor*).
 
 Objects have access to their type at runtime. There is an
-``is`` operator that can be used to check the object's type:
+``of`` operator that can be used to check the object's type:
 
 .. code-block:: nimrod
 
@@ -64,7 +64,7 @@ Objects have access to their type at runtime. There is an
   var
     student: TStudent
     person: TPerson
-  assert(student is TStudent) # is true
+  assert(student of TStudent) # is true
 
 Object fields that should be visible from outside the defining module, have to
 be marked by ``*``. In contrast to tuples, different object types are
diff --git a/install.sh b/install.sh
index 1fa9a1697..3611c93c5 100755
--- a/install.sh
+++ b/install.sh
@@ -132,158 +132,6 @@ if [ $# -eq 1 ] ; then
   chmod 644 $docdir/tut1.txt
   cp doc/tut2.txt $docdir/tut2.txt || exit 1
   chmod 644 $docdir/tut2.txt
-  cp doc/apis.html $docdir/apis.html || exit 1
-  chmod 644 $docdir/apis.html
-  cp doc/base64.html $docdir/base64.html || exit 1
-  chmod 644 $docdir/base64.html
-  cp doc/browsers.html $docdir/browsers.html || exit 1
-  chmod 644 $docdir/browsers.html
-  cp doc/c2nim.html $docdir/c2nim.html || exit 1
-  chmod 644 $docdir/c2nim.html
-  cp doc/cgi.html $docdir/cgi.html || exit 1
-  chmod 644 $docdir/cgi.html
-  cp doc/colors.html $docdir/colors.html || exit 1
-  chmod 644 $docdir/colors.html
-  cp doc/complex.html $docdir/complex.html || exit 1
-  chmod 644 $docdir/complex.html
-  cp doc/db_mysql.html $docdir/db_mysql.html || exit 1
-  chmod 644 $docdir/db_mysql.html
-  cp doc/db_postgres.html $docdir/db_postgres.html || exit 1
-  chmod 644 $docdir/db_postgres.html
-  cp doc/db_sqlite.html $docdir/db_sqlite.html || exit 1
-  chmod 644 $docdir/db_sqlite.html
-  cp doc/dynlib.html $docdir/dynlib.html || exit 1
-  chmod 644 $docdir/dynlib.html
-  cp doc/encodings.html $docdir/encodings.html || exit 1
-  chmod 644 $docdir/encodings.html
-  cp doc/endb.html $docdir/endb.html || exit 1
-  chmod 644 $docdir/endb.html
-  cp doc/filters.html $docdir/filters.html || exit 1
-  chmod 644 $docdir/filters.html
-  cp doc/graphics.html $docdir/graphics.html || exit 1
-  chmod 644 $docdir/graphics.html
-  cp doc/hashes.html $docdir/hashes.html || exit 1
-  chmod 644 $docdir/hashes.html
-  cp doc/htmlparser.html $docdir/htmlparser.html || exit 1
-  chmod 644 $docdir/htmlparser.html
-  cp doc/httpclient.html $docdir/httpclient.html || exit 1
-  chmod 644 $docdir/httpclient.html
-  cp doc/httpserver.html $docdir/httpserver.html || exit 1
-  chmod 644 $docdir/httpserver.html
-  cp doc/inboxes.html $docdir/inboxes.html || exit 1
-  chmod 644 $docdir/inboxes.html
-  cp doc/intern.html $docdir/intern.html || exit 1
-  chmod 644 $docdir/intern.html
-  cp doc/intsets.html $docdir/intsets.html || exit 1
-  chmod 644 $docdir/intsets.html
-  cp doc/json.html $docdir/json.html || exit 1
-  chmod 644 $docdir/json.html
-  cp doc/lexbase.html $docdir/lexbase.html || exit 1
-  chmod 644 $docdir/lexbase.html
-  cp doc/lib.html $docdir/lib.html || exit 1
-  chmod 644 $docdir/lib.html
-  cp doc/lists.html $docdir/lists.html || exit 1
-  chmod 644 $docdir/lists.html
-  cp doc/macros.html $docdir/macros.html || exit 1
-  chmod 644 $docdir/macros.html
-  cp doc/manual.html $docdir/manual.html || exit 1
-  chmod 644 $docdir/manual.html
-  cp doc/marshal.html $docdir/marshal.html || exit 1
-  chmod 644 $docdir/marshal.html
-  cp doc/math.html $docdir/math.html || exit 1
-  chmod 644 $docdir/math.html
-  cp doc/niminst.html $docdir/niminst.html || exit 1
-  chmod 644 $docdir/niminst.html
-  cp doc/nimrodc.html $docdir/nimrodc.html || exit 1
-  chmod 644 $docdir/nimrodc.html
-  cp doc/os.html $docdir/os.html || exit 1
-  chmod 644 $docdir/os.html
-  cp doc/osproc.html $docdir/osproc.html || exit 1
-  chmod 644 $docdir/osproc.html
-  cp doc/overview.html $docdir/overview.html || exit 1
-  chmod 644 $docdir/overview.html
-  cp doc/parsecfg.html $docdir/parsecfg.html || exit 1
-  chmod 644 $docdir/parsecfg.html
-  cp doc/parsecsv.html $docdir/parsecsv.html || exit 1
-  chmod 644 $docdir/parsecsv.html
-  cp doc/parseopt.html $docdir/parseopt.html || exit 1
-  chmod 644 $docdir/parseopt.html
-  cp doc/parsesql.html $docdir/parsesql.html || exit 1
-  chmod 644 $docdir/parsesql.html
-  cp doc/parseutils.html $docdir/parseutils.html || exit 1
-  chmod 644 $docdir/parseutils.html
-  cp doc/parsexml.html $docdir/parsexml.html || exit 1
-  chmod 644 $docdir/parsexml.html
-  cp doc/pegs.html $docdir/pegs.html || exit 1
-  chmod 644 $docdir/pegs.html
-  cp doc/queues.html $docdir/queues.html || exit 1
-  chmod 644 $docdir/queues.html
-  cp doc/rdstdin.html $docdir/rdstdin.html || exit 1
-  chmod 644 $docdir/rdstdin.html
-  cp doc/re.html $docdir/re.html || exit 1
-  chmod 644 $docdir/re.html
-  cp doc/redis.html $docdir/redis.html || exit 1
-  chmod 644 $docdir/redis.html
-  cp doc/ropes.html $docdir/ropes.html || exit 1
-  chmod 644 $docdir/ropes.html
-  cp doc/scgi.html $docdir/scgi.html || exit 1
-  chmod 644 $docdir/scgi.html
-  cp doc/sets.html $docdir/sets.html || exit 1
-  chmod 644 $docdir/sets.html
-  cp doc/smtp.html $docdir/smtp.html || exit 1
-  chmod 644 $docdir/smtp.html
-  cp doc/sockets.html $docdir/sockets.html || exit 1
-  chmod 644 $docdir/sockets.html
-  cp doc/sphinx.html $docdir/sphinx.html || exit 1
-  chmod 644 $docdir/sphinx.html
-  cp doc/ssl.html $docdir/ssl.html || exit 1
-  chmod 644 $docdir/ssl.html
-  cp doc/streams.html $docdir/streams.html || exit 1
-  chmod 644 $docdir/streams.html
-  cp doc/strtabs.html $docdir/strtabs.html || exit 1
-  chmod 644 $docdir/strtabs.html
-  cp doc/strutils.html $docdir/strutils.html || exit 1
-  chmod 644 $docdir/strutils.html
-  cp doc/system.html $docdir/system.html || exit 1
-  chmod 644 $docdir/system.html
-  cp doc/tables.html $docdir/tables.html || exit 1
-  chmod 644 $docdir/tables.html
-  cp doc/terminal.html $docdir/terminal.html || exit 1
-  chmod 644 $docdir/terminal.html
-  cp doc/theindex.html $docdir/theindex.html || exit 1
-  chmod 644 $docdir/theindex.html
-  cp doc/threads.html $docdir/threads.html || exit 1
-  chmod 644 $docdir/threads.html
-  cp doc/times.html $docdir/times.html || exit 1
-  chmod 644 $docdir/times.html
-  cp doc/tools.html $docdir/tools.html || exit 1
-  chmod 644 $docdir/tools.html
-  cp doc/tut1.html $docdir/tut1.html || exit 1
-  chmod 644 $docdir/tut1.html
-  cp doc/tut2.html $docdir/tut2.html || exit 1
-  chmod 644 $docdir/tut2.html
-  cp doc/typeinfo.html $docdir/typeinfo.html || exit 1
-  chmod 644 $docdir/typeinfo.html
-  cp doc/unicode.html $docdir/unicode.html || exit 1
-  chmod 644 $docdir/unicode.html
-  cp doc/unidecode.html $docdir/unidecode.html || exit 1
-  chmod 644 $docdir/unidecode.html
-  cp doc/web.html $docdir/web.html || exit 1
-  chmod 644 $docdir/web.html
-  cp doc/xmldom.html $docdir/xmldom.html || exit 1
-  chmod 644 $docdir/xmldom.html
-  cp doc/xmldomparser.html $docdir/xmldomparser.html || exit 1
-  chmod 644 $docdir/xmldomparser.html
-  cp doc/xmlgen.html $docdir/xmlgen.html || exit 1
-  chmod 644 $docdir/xmlgen.html
-  cp doc/xmlparser.html $docdir/xmlparser.html || exit 1
-  chmod 644 $docdir/xmlparser.html
-  cp doc/xmltree.html $docdir/xmltree.html || exit 1
-  chmod 644 $docdir/xmltree.html
-  cp doc/zipfiles.html $docdir/zipfiles.html || exit 1
-  chmod 644 $docdir/zipfiles.html
-  cp doc/zmq.html $docdir/zmq.html || exit 1
-  chmod 644 $docdir/zmq.html
   cp doc/mytest.cfg $docdir/mytest.cfg || exit 1
   chmod 644 $docdir/mytest.cfg
   cp doc/c2nim.pdf $docdir/c2nim.pdf || exit 1
@@ -380,10 +228,14 @@ if [ $# -eq 1 ] ; then
   chmod 644 $libdir/pure/dynlib.nim
   cp lib/pure/encodings.nim $libdir/pure/encodings.nim || exit 1
   chmod 644 $libdir/pure/encodings.nim
+  cp lib/pure/events.nim $libdir/pure/events.nim || exit 1
+  chmod 644 $libdir/pure/events.nim
   cp lib/pure/gentabs.nim $libdir/pure/gentabs.nim || exit 1
   chmod 644 $libdir/pure/gentabs.nim
   cp lib/pure/hashes.nim $libdir/pure/hashes.nim || exit 1
   chmod 644 $libdir/pure/hashes.nim
+  cp lib/pure/htmlgen.nim $libdir/pure/htmlgen.nim || exit 1
+  chmod 644 $libdir/pure/htmlgen.nim
   cp lib/pure/htmlparser.nim $libdir/pure/htmlparser.nim || exit 1
   chmod 644 $libdir/pure/htmlparser.nim
   cp lib/pure/httpclient.nim $libdir/pure/httpclient.nim || exit 1
@@ -396,6 +248,8 @@ if [ $# -eq 1 ] ; then
   chmod 644 $libdir/pure/lexbase.nim
   cp lib/pure/marshal.nim $libdir/pure/marshal.nim || exit 1
   chmod 644 $libdir/pure/marshal.nim
+  cp lib/pure/matchers.nim $libdir/pure/matchers.nim || exit 1
+  chmod 644 $libdir/pure/matchers.nim
   cp lib/pure/math.nim $libdir/pure/math.nim || exit 1
   chmod 644 $libdir/pure/math.nim
   cp lib/pure/md5.nim $libdir/pure/md5.nim || exit 1
@@ -422,8 +276,6 @@ if [ $# -eq 1 ] ; then
   chmod 644 $libdir/pure/pegs.nim
   cp lib/pure/redis.nim $libdir/pure/redis.nim || exit 1
   chmod 644 $libdir/pure/redis.nim
-  cp lib/pure/regexprs.nim $libdir/pure/regexprs.nim || exit 1
-  chmod 644 $libdir/pure/regexprs.nim
   cp lib/pure/romans.nim $libdir/pure/romans.nim || exit 1
   chmod 644 $libdir/pure/romans.nim
   cp lib/pure/ropes.nim $libdir/pure/ropes.nim || exit 1
@@ -450,8 +302,6 @@ if [ $# -eq 1 ] ; then
   chmod 644 $libdir/pure/xmldom.nim
   cp lib/pure/xmldomparser.nim $libdir/pure/xmldomparser.nim || exit 1
   chmod 644 $libdir/pure/xmldomparser.nim
-  cp lib/pure/xmlgen.nim $libdir/pure/xmlgen.nim || exit 1
-  chmod 644 $libdir/pure/xmlgen.nim
   cp lib/pure/xmlparser.nim $libdir/pure/xmlparser.nim || exit 1
   chmod 644 $libdir/pure/xmlparser.nim
   cp lib/pure/xmltree.nim $libdir/pure/xmltree.nim || exit 1
@@ -462,6 +312,8 @@ if [ $# -eq 1 ] ; then
   chmod 644 $libdir/pure/collections/lists.nim
   cp lib/pure/collections/queues.nim $libdir/pure/collections/queues.nim || exit 1
   chmod 644 $libdir/pure/collections/queues.nim
+  cp lib/pure/collections/sequtils.nim $libdir/pure/collections/sequtils.nim || exit 1
+  chmod 644 $libdir/pure/collections/sequtils.nim
   cp lib/pure/collections/sets.nim $libdir/pure/collections/sets.nim || exit 1
   chmod 644 $libdir/pure/collections/sets.nim
   cp lib/pure/collections/tables.nim $libdir/pure/collections/tables.nim || exit 1
diff --git a/lib/system.nim b/lib/system.nim
index 363d31578..33e350d7e 100755
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -43,6 +43,7 @@ type
   stmt* {.magic: Stmt.} ## meta type to denote a statement (for templates)
   typeDesc* {.magic: TypeDesc.} ## meta type to denote
                                 ## a type description (for templates)
+  void* {.magic: "VoidType".}  ## meta type to denote the absense of any type
 
 proc defined*[T](x: T): bool {.magic: "Defined", noSideEffect.}
   ## Special compile-time procedure that checks whether `x` is
@@ -649,6 +650,8 @@ template `not_in` * (x, y: expr): expr = not contains(y, x)
 proc `is` *[T, S](x: T, y: S): bool {.magic: "Is", noSideEffect.}
 template `is_not` *(x, y: expr): expr = not (x is y)
 
+proc `of` *[T, S](x: T, y: S): bool {.magic: "Of", noSideEffect.}
+
 proc cmp*[T](x, y: T): int {.procvar.} =
   ## Generic compare proc. Returns a value < 0 iff x < y, a value > 0 iff x > y
   ## and 0 iff x == y. This is useful for writing generic algorithms without
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index 9095c168b..2da768810 100755
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -199,7 +199,7 @@ proc raiseException(e: ref E_Base, ename: CString) {.compilerRtl.} =
   if excHandler != nil:
     pushCurrentException(e)
     c_longjmp(excHandler.context, 1)
-  elif e[] is EOutOfMemory:
+  elif e[] of EOutOfMemory:
     writeToStdErr(ename)
     quitOrDebug()
   else:
diff --git a/tests/accept/run/teventemitter.nim b/tests/accept/run/teventemitter.nim
index 166a0cb30..763f41943 100644
--- a/tests/accept/run/teventemitter.nim
+++ b/tests/accept/run/teventemitter.nim
@@ -4,7 +4,7 @@ type
   TEventArgs = object of TObject
 type
   TEventEmitter = object of TObject
-    events*: TTable[string, TDoublyLinkedList[proc(e : TEventArgs)]]
+    events*: TTable[string, TDoublyLinkedList[proc(e: TEventArgs)]]
 proc on*(emitter: var TEventEmitter, event: string, func: proc(e: TEventArgs)) =
   if not hasKey(emitter.events, event):
     var list: TDoublyLinkedList[proc(e: TEventArgs)]
diff --git a/tests/accept/run/tisopr.nim b/tests/accept/run/tofopr.nim
index 7e7a8f650..f9c21ad16 100755
--- a/tests/accept/run/tisopr.nim
+++ b/tests/accept/run/tofopr.nim
@@ -1,5 +1,5 @@
 discard """
-  file: "tisopr.nim"
+  file: "tofopr.nim"
   output: "falsetrue"
 """
 # Test is operator
@@ -12,7 +12,7 @@ type
   TOtherType = object of TMyType
    
 proc p(x: TMyType): bool = 
-  return x is TOtherType
+  return x of TOtherType
     
 var
   m: TMyType
diff --git a/todo.txt b/todo.txt
index 217a79551..6fbd4e68c 100755
--- a/todo.txt
+++ b/todo.txt
@@ -1,6 +1,7 @@
 Version 0.8.14
 ==============
 
+- ``when T is int`` for generic code
 - ``var T`` as a return type:
   * for iterators
   * add ``modGet`` for generics
@@ -78,7 +79,6 @@ Library
 Low priority
 ------------
 
-- ``when T is int`` for generic code
 - ``when validCode(proc())`` for generic code
 - find a way for easy constructors and destructors; (destructors are much more
   important than constructors)
@@ -90,7 +90,7 @@ Version 2
 
 - language change: inheritance should only work with reference types, so that
   the ``type`` field is not needed for objects! --> zero overhead aggregation
-  BETTER: ``is`` and safe object conversions only work with ref objects. Same
+  BETTER: ``of`` and safe object conversions only work with ref objects. Same
   for multi methods.
   
 - explicit nil types?
diff --git a/web/news.txt b/web/news.txt
index 5058d1355..d919fc6cd 100755
--- a/web/news.txt
+++ b/web/news.txt
@@ -31,11 +31,16 @@ Changes affecting backwards compatibility
 - Moved ``strutils.validEmailAddress`` to ``matchers.validEmailAddress``.
 - The pointer dereference operator ``^`` has been removed, so that ``^``
   can now be a user-defined operator.
+- The ``is`` operator is now the ``of`` operator.
+- The ``is`` operator is now used to check type equivalence in generic code.
 
 
 Language Additions
 ------------------
 
+- Added new ``is`` and ``of`` operators.
+
+
 Compiler Additions
 ------------------