preparation for new 'is' operator; breaks bootstrapping again, sorry (use generated C code)

This commit is contained in:
Araq
2011-07-31 00:21:32 +02:00
parent 2d62738bbb
commit 6a8a409f1b
19 changed files with 86 additions and 203 deletions

View File

@@ -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,

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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\'",

View File

@@ -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

View File

@@ -202,20 +202,39 @@ proc semSizeof(c: PContext, n: PNode): PNode =
n.typ = getSysType(tyInt)
result = n
proc semIs(c: PContext, n: PNode): PNode =
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, errIsExpectsObjectTypes)
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, errIsExpectsTwoArguments)
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, 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, 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:

View File

@@ -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)

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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)]

View File

@@ -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

View File

@@ -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?

View File

@@ -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
------------------