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
commit 6a8a409f1b
19 changed files with 86 additions and 203 deletions

View file

@ -310,7 +310,7 @@ type
TSymKinds* = set[TSymKind] TSymKinds* = set[TSymKind]
TMagic* = enum # symbols that require compiler magic: TMagic* = enum # symbols that require compiler magic:
mNone, mDefined, mDefinedInScope, mLow, mHigh, mSizeOf, mIs, mNone, mDefined, mDefinedInScope, mLow, mHigh, mSizeOf, mIs, mOf,
mEcho, mShallowCopy, mEcho, mShallowCopy,
mUnaryLt, mSucc, mUnaryLt, mSucc,
mPred, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mLengthOpenArray, mPred, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mLengthOpenArray,
@ -346,6 +346,7 @@ type
mOrdinal, mInt, mInt8, mInt16, mInt32, mOrdinal, mInt, mInt8, mInt16, mInt32,
mInt64, mFloat, mFloat32, mFloat64, mBool, mChar, mString, mCstring, mInt64, mFloat, mFloat32, mFloat64, mBool, mChar, mString, mCstring,
mPointer, mEmptySet, mIntSetBaseType, mNil, mExpr, mStmt, mTypeDesc, mPointer, mEmptySet, mIntSetBaseType, mNil, mExpr, mStmt, mTypeDesc,
mVoidType,
mIsMainModule, mCompileDate, mCompileTime, mNimrodVersion, mNimrodMajor, mIsMainModule, mCompileDate, mCompileTime, mNimrodVersion, mNimrodMajor,
mNimrodMinor, mNimrodPatch, mCpuEndian, mHostOS, mHostCPU, mAppType, mNimrodMinor, mNimrodPatch, mCpuEndian, mHostOS, mHostCPU, mAppType,
mNaN, mInf, mNegInf, mNaN, mInf, mNegInf,

View file

@ -962,7 +962,7 @@ proc genNewSeq(p: BProc, e: PNode) =
genTypeInfo(p.module, seqType), rdLoc(b)]) genTypeInfo(p.module, seqType), rdLoc(b)])
genAssignment(p, a, c, {}) 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 var
a: TLoc a: TLoc
dest, t: PType 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)]) r = ropecg(p.module, "#isObj($1.m_type, $2)", [r, genTypeInfo(p.module, dest)])
putIntoDest(p, d, getSysType(tyBool), r) putIntoDest(p, d, getSysType(tyBool), r)
proc genIs(p: BProc, n: PNode, d: var TLoc) = proc genOf(p: BProc, n: PNode, d: var TLoc) =
genIs(p, n.sons[1], n.sons[2].typ, d) genOf(p, n.sons[1], n.sons[2].typ, d)
proc genNewFinalize(p: BProc, e: PNode) = proc genNewFinalize(p: BProc, e: PNode) =
var var
@ -1438,7 +1438,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
filen = makeCString(ToFilename(e.info)) filen = makeCString(ToFilename(e.info))
appcg(p, cpsStmts, "#internalAssert($1, $2, $3);$n", appcg(p, cpsStmts, "#internalAssert($1, $2, $3);$n",
[filen, line, rdLoc(d)]) [filen, line, rdLoc(d)])
of mIs: genIs(p, e, d) of mOf: genOf(p, e, d)
of mNew: genNew(p, e) of mNew: genNew(p, e)
of mNewFinalize: genNewFinalize(p, e) of mNewFinalize: genNewFinalize(p, e)
of mNewSeq: genNewSeq(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 paramLen = sonsLen(base.typ)
var disp = newNodeI(nkIfStmt, base.info) var disp = newNodeI(nkIfStmt, base.info)
var ands = getSysSym("and") var ands = getSysSym("and")
var iss = getSysSym("is") var iss = getSysSym("of")
for meth in countup(0, high(methods)): for meth in countup(0, high(methods)):
var curr = methods[meth] # generate condition: var curr = methods[meth] # generate condition:
var cond: PNode = nil var cond: PNode = nil

View file

@ -615,7 +615,7 @@ proc evalHigh(c: PEvalContext, n: PNode): PNode =
of tyString: result = newIntNodeT(len(result.strVal) - 1, n) of tyString: result = newIntNodeT(len(result.strVal) - 1, n)
else: InternalError(n.info, "evalHigh") 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], {}) result = evalAux(c, n.sons[1], {})
if isSpecial(result): return if isSpecial(result): return
result = newIntNodeT(ord(inheritanceDiff(result.typ, n.sons[2].typ) >= 0), n) 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) var m = getMagic(n)
case m case m
of mNone: result = evalCall(c, n) 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 mSizeOf: internalError(n.info, "sizeof() should have been evaluated")
of mHigh: result = evalHigh(c, n) of mHigh: result = evalHigh(c, n)
of mAssert: result = evalAssert(c, n) of mAssert: result = evalAssert(c, n)

View file

@ -82,8 +82,10 @@ type
errInvalidIndexValueForTuple, errCommandExpectsFilename, errXExpected, errInvalidIndexValueForTuple, errCommandExpectsFilename, errXExpected,
errInvalidSectionStart, errGridTableNotImplemented, errGeneralParseError, errInvalidSectionStart, errGridTableNotImplemented, errGeneralParseError,
errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile, errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile,
errCannotRenderX, errVarVarTypeNotAllowed, errIsExpectsTwoArguments, errCannotRenderX, errVarVarTypeNotAllowed,
errIsExpectsObjectTypes, errXcanNeverBeOfThisSubtype, errTooManyIterations,
errXExpectsTwoArguments,
errXExpectsObjectTypes, errXcanNeverBeOfThisSubtype, errTooManyIterations,
errCannotInterpretNodeX, errFieldXNotFound, errInvalidConversionFromTypeX, errCannotInterpretNodeX, errFieldXNotFound, errInvalidConversionFromTypeX,
errAssertionFailed, errCannotGenerateCodeForX, errXRequiresOneArgument, errAssertionFailed, errCannotGenerateCodeForX, errXRequiresOneArgument,
errUnhandledExceptionX, errCyclicTree, errXisNoMacroOrTemplate, errUnhandledExceptionX, errCyclicTree, errXisNoMacroOrTemplate,
@ -298,8 +300,8 @@ const
errXisNoValidIndexFile: "\'$1\' is no valid index file", errXisNoValidIndexFile: "\'$1\' is no valid index file",
errCannotRenderX: "cannot render reStructuredText element \'$1\'", errCannotRenderX: "cannot render reStructuredText element \'$1\'",
errVarVarTypeNotAllowed: "type \'var var\' is not allowed", errVarVarTypeNotAllowed: "type \'var var\' is not allowed",
errIsExpectsTwoArguments: "\'is\' expects two arguments", errXExpectsTwoArguments: "\'$1\' expects two arguments",
errIsExpectsObjectTypes: "\'is\' expects object types", errXExpectsObjectTypes: "\'$1\' expects object types",
errXcanNeverBeOfThisSubtype: "\'$1\' can never be of this subtype", errXcanNeverBeOfThisSubtype: "\'$1\' can never be of this subtype",
errTooManyIterations: "interpretation requires too many iterations", errTooManyIterations: "interpretation requires too many iterations",
errCannotInterpretNodeX: "cannot interpret node kind \'$1\'", errCannotInterpretNodeX: "cannot interpret node kind \'$1\'",

View file

@ -154,7 +154,7 @@ proc getPrecedence(tok: TToken): int =
of '.': result = 5 of '.': result = 5
else: result = 1 else: result = 1
of tkDiv, tkMod, tkShl, tkShr: result = 8 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 tkDotDot: result = 5
of tkAnd: result = 3 of tkAnd: result = 3
of tkOr, tkXor: result = 2 of tkOr, tkXor: result = 2

View file

@ -202,20 +202,39 @@ proc semSizeof(c: PContext, n: PNode): PNode =
n.typ = getSysType(tyInt) n.typ = getSysType(tyInt)
result = n result = n
proc semIs(c: PContext, n: PNode): PNode = proc semOf(c: PContext, n: PNode): PNode =
if sonsLen(n) == 3: if sonsLen(n) == 3:
#LocalError(n.info, errXcanNeverBeOfThisSubtype, " CAME HERE")
n.sons[1] = semExprWithType(c, n.sons[1], {efAllowType}) n.sons[1] = semExprWithType(c, n.sons[1], {efAllowType})
n.sons[2] = semExprWithType(c, n.sons[2], {efAllowType}) n.sons[2] = semExprWithType(c, n.sons[2], {efAllowType})
var a = skipTypes(n.sons[1].typ, abstractPtrs) var a = skipTypes(n.sons[1].typ, abstractPtrs)
var b = skipTypes(n.sons[2].typ, abstractPtrs) var b = skipTypes(n.sons[2].typ, abstractPtrs)
if b.kind != tyObject or a.kind != tyObject: 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] while b != nil and b.id != a.id: b = b.sons[0]
if b == nil: if b == nil:
GlobalError(n.info, errXcanNeverBeOfThisSubtype, typeToString(a)) GlobalError(n.info, errXcanNeverBeOfThisSubtype, typeToString(a))
n.typ = getSysType(tyBool) n.typ = getSysType(tyBool)
else: 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 result = n
proc semOpAux(c: PContext, n: PNode) = 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 mHigh: result = semLowHigh(c, setMs(n, s), mHigh)
of mSizeOf: result = semSizeof(c, setMs(n, s)) of mSizeOf: result = semSizeof(c, setMs(n, s))
of mIs: result = semIs(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 mEcho: result = semEcho(c, setMs(n, s))
of mShallowCopy: of mShallowCopy:
if sonsLen(n) == 3: if sonsLen(n) == 3:

View file

@ -220,15 +220,15 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
var var
elem: PType elem: PType
isConcrete: bool 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) GlobalError(n.info, errCannotInstantiateX, s.name.s)
result = newOrPrevType(tyGenericInvokation, prev, c) 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): if sonsLen(n) != sonsLen(s.typ):
GlobalError(n.info, errWrongNumberOfArguments) GlobalError(n.info, errWrongNumberOfArguments)
addSon(result, s.typ) addSon(result, s.typ)
isConcrete = true # iterate over arguments: 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) elem = semTypeNode(c, n.sons[i], nil)
if elem.kind == tyGenericParam: isConcrete = false if elem.kind == tyGenericParam: isConcrete = false
addSon(result, elem) addSon(result, elem)
@ -704,6 +704,7 @@ proc processMagicType(c: PContext, m: PSym) =
of mExpr: setMagicType(m, tyExpr, 0) of mExpr: setMagicType(m, tyExpr, 0)
of mStmt: setMagicType(m, tyStmt, 0) of mStmt: setMagicType(m, tyStmt, 0)
of mTypeDesc: setMagicType(m, tyTypeDesc, 0) of mTypeDesc: setMagicType(m, tyTypeDesc, 0)
of mVoidType: setMagicType(m, tyEmpty, 0)
of mArray, mOpenArray, mRange, mSet, mSeq, mOrdinal: nil of mArray, mOpenArray, mRange, mSet, mSeq, mOrdinal: nil
else: GlobalError(m.info, errTypeExpected) else: GlobalError(m.info, errTypeExpected)

View file

@ -361,11 +361,10 @@ proc canFormAcycleNode(marker: var TIntSet, n: PNode, startId: int): bool =
if result: return if result: return
proc canFormAcycleAux(marker: var TIntSet, typ: PType, startId: int): bool = proc canFormAcycleAux(marker: var TIntSet, typ: PType, startId: int): bool =
var t: PType
result = false result = false
if typ == nil: return if typ == nil: return
if tfAcyclic in typ.flags: return if tfAcyclic in typ.flags: return
t = skipTypes(typ, abstractInst) var t = skipTypes(typ, abstractInst)
if tfAcyclic in t.flags: return if tfAcyclic in t.flags: return
case t.kind case t.kind
of tyTuple, tyObject, tyRef, tySequence, tyArray, tyArrayConstr, tyOpenArray: of tyTuple, tyObject, tyRef, tySequence, tyArray, tyArrayConstr, tyOpenArray:

View file

@ -3,7 +3,7 @@ module ::= ([COMMENT] [SAD] stmt)*
comma ::= ',' [COMMENT] [IND] comma ::= ',' [COMMENT] [IND]
operator ::= OP1 | OP2 | OP3 | OP4 | OP5 | OP6 | OP7 | OP8 | OP9 operator ::= OP1 | OP2 | OP3 | OP4 | OP5 | OP6 | OP7 | OP8 | OP9
| 'or' | 'xor' | 'and' | 'or' | 'xor' | 'and'
| 'is' | 'isnot' | 'in' | 'notin' | 'is' | 'isnot' | 'in' | 'notin' | 'of'
| 'div' | 'mod' | 'shl' | 'shr' | 'not' | '..' | 'div' | 'mod' | 'shl' | 'shr' | 'not' | '..'
prefixOperator ::= operator prefixOperator ::= operator

View file

@ -358,7 +358,7 @@ combination of the following characters::
! ? ^ . : \ ! ? ^ . : \
These keywords are also operators: 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 `=`:tok:, `:`:tok:, `::`:tok: are not available as general operators; they
are used for other notational purposes. 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 of. All binary operators are left-associative, except binary operators starting
with (or only consisting of) ``^``. with (or only consisting of) ``^``.
================ ============================================== ================== =============== ================ =============================================== ================== ===============
Precedence level Operators First characters Terminal symbol Precedence level Operators First characters Terminal symbol
================ ============================================== ================== =============== ================ =============================================== ================== ===============
9 (highest) ``$ ^`` OP9 9 (highest) ``$ ^`` OP9
8 ``* / div mod shl shr %`` ``* % \ /`` OP8 8 ``* / div mod shl shr %`` ``* % \ /`` OP8
7 ``+ -`` ``+ ~ |`` OP7 7 ``+ -`` ``+ ~ |`` OP7
6 ``&`` ``&`` OP6 6 ``&`` ``&`` OP6
5 ``..`` ``.`` OP5 5 ``..`` ``.`` OP5
4 ``== <= < >= > != in not_in is isnot not`` ``= < > !`` OP4 4 ``== <= < >= > != in not_in is isnot not of`` ``= < > !`` OP4
3 ``and`` OP3 3 ``and`` OP3
2 ``or xor`` OP2 2 ``or xor`` OP2
1 (lowest) `` @ : ? `` OP1 1 (lowest) ``@ : ?`` OP1
================ ============================================== ================== =============== ================ =============================================== ================== ===============
The grammar's start symbol is ``module``. 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 Objects provide many features that tuples do not. Object provide inheritance
and information hiding. Objects have access to their type at runtime, so that 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 .. code-block:: nimrod
@ -839,7 +839,7 @@ the ``is`` operator can be used to determine the object's type.
var var
student: TStudent student: TStudent
person: TPerson 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 Object fields that should be visible from outside the defining module, have to
be marked by ``*``. In contrast to tuples, different object types are 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*). a *constructor*).
Objects have access to their type at runtime. There is an 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 .. code-block:: nimrod
@ -64,7 +64,7 @@ Objects have access to their type at runtime. There is an
var var
student: TStudent student: TStudent
person: TPerson 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 Object fields that should be visible from outside the defining module, have to
be marked by ``*``. In contrast to tuples, different object types are 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 chmod 644 $docdir/tut1.txt
cp doc/tut2.txt $docdir/tut2.txt || exit 1 cp doc/tut2.txt $docdir/tut2.txt || exit 1
chmod 644 $docdir/tut2.txt 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 cp doc/mytest.cfg $docdir/mytest.cfg || exit 1
chmod 644 $docdir/mytest.cfg chmod 644 $docdir/mytest.cfg
cp doc/c2nim.pdf $docdir/c2nim.pdf || exit 1 cp doc/c2nim.pdf $docdir/c2nim.pdf || exit 1
@ -380,10 +228,14 @@ if [ $# -eq 1 ] ; then
chmod 644 $libdir/pure/dynlib.nim chmod 644 $libdir/pure/dynlib.nim
cp lib/pure/encodings.nim $libdir/pure/encodings.nim || exit 1 cp lib/pure/encodings.nim $libdir/pure/encodings.nim || exit 1
chmod 644 $libdir/pure/encodings.nim 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 cp lib/pure/gentabs.nim $libdir/pure/gentabs.nim || exit 1
chmod 644 $libdir/pure/gentabs.nim chmod 644 $libdir/pure/gentabs.nim
cp lib/pure/hashes.nim $libdir/pure/hashes.nim || exit 1 cp lib/pure/hashes.nim $libdir/pure/hashes.nim || exit 1
chmod 644 $libdir/pure/hashes.nim 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 cp lib/pure/htmlparser.nim $libdir/pure/htmlparser.nim || exit 1
chmod 644 $libdir/pure/htmlparser.nim chmod 644 $libdir/pure/htmlparser.nim
cp lib/pure/httpclient.nim $libdir/pure/httpclient.nim || exit 1 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 chmod 644 $libdir/pure/lexbase.nim
cp lib/pure/marshal.nim $libdir/pure/marshal.nim || exit 1 cp lib/pure/marshal.nim $libdir/pure/marshal.nim || exit 1
chmod 644 $libdir/pure/marshal.nim 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 cp lib/pure/math.nim $libdir/pure/math.nim || exit 1
chmod 644 $libdir/pure/math.nim chmod 644 $libdir/pure/math.nim
cp lib/pure/md5.nim $libdir/pure/md5.nim || exit 1 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 chmod 644 $libdir/pure/pegs.nim
cp lib/pure/redis.nim $libdir/pure/redis.nim || exit 1 cp lib/pure/redis.nim $libdir/pure/redis.nim || exit 1
chmod 644 $libdir/pure/redis.nim 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 cp lib/pure/romans.nim $libdir/pure/romans.nim || exit 1
chmod 644 $libdir/pure/romans.nim chmod 644 $libdir/pure/romans.nim
cp lib/pure/ropes.nim $libdir/pure/ropes.nim || exit 1 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 chmod 644 $libdir/pure/xmldom.nim
cp lib/pure/xmldomparser.nim $libdir/pure/xmldomparser.nim || exit 1 cp lib/pure/xmldomparser.nim $libdir/pure/xmldomparser.nim || exit 1
chmod 644 $libdir/pure/xmldomparser.nim 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 cp lib/pure/xmlparser.nim $libdir/pure/xmlparser.nim || exit 1
chmod 644 $libdir/pure/xmlparser.nim chmod 644 $libdir/pure/xmlparser.nim
cp lib/pure/xmltree.nim $libdir/pure/xmltree.nim || exit 1 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 chmod 644 $libdir/pure/collections/lists.nim
cp lib/pure/collections/queues.nim $libdir/pure/collections/queues.nim || exit 1 cp lib/pure/collections/queues.nim $libdir/pure/collections/queues.nim || exit 1
chmod 644 $libdir/pure/collections/queues.nim 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 cp lib/pure/collections/sets.nim $libdir/pure/collections/sets.nim || exit 1
chmod 644 $libdir/pure/collections/sets.nim chmod 644 $libdir/pure/collections/sets.nim
cp lib/pure/collections/tables.nim $libdir/pure/collections/tables.nim || exit 1 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) stmt* {.magic: Stmt.} ## meta type to denote a statement (for templates)
typeDesc* {.magic: TypeDesc.} ## meta type to denote typeDesc* {.magic: TypeDesc.} ## meta type to denote
## a type description (for templates) ## 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.} proc defined*[T](x: T): bool {.magic: "Defined", noSideEffect.}
## Special compile-time procedure that checks whether `x` is ## 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.} proc `is` *[T, S](x: T, y: S): bool {.magic: "Is", noSideEffect.}
template `is_not` *(x, y: expr): expr = not (x is y) 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.} = proc cmp*[T](x, y: T): int {.procvar.} =
## Generic compare proc. Returns a value < 0 iff x < y, a value > 0 iff x > y ## 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 ## 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: if excHandler != nil:
pushCurrentException(e) pushCurrentException(e)
c_longjmp(excHandler.context, 1) c_longjmp(excHandler.context, 1)
elif e[] is EOutOfMemory: elif e[] of EOutOfMemory:
writeToStdErr(ename) writeToStdErr(ename)
quitOrDebug() quitOrDebug()
else: else:

View file

@ -4,7 +4,7 @@ type
TEventArgs = object of TObject TEventArgs = object of TObject
type type
TEventEmitter = object of TObject 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)) = proc on*(emitter: var TEventEmitter, event: string, func: proc(e: TEventArgs)) =
if not hasKey(emitter.events, event): if not hasKey(emitter.events, event):
var list: TDoublyLinkedList[proc(e: TEventArgs)] var list: TDoublyLinkedList[proc(e: TEventArgs)]

View file

@ -1,5 +1,5 @@
discard """ discard """
file: "tisopr.nim" file: "tofopr.nim"
output: "falsetrue" output: "falsetrue"
""" """
# Test is operator # Test is operator
@ -12,7 +12,7 @@ type
TOtherType = object of TMyType TOtherType = object of TMyType
proc p(x: TMyType): bool = proc p(x: TMyType): bool =
return x is TOtherType return x of TOtherType
var var
m: TMyType m: TMyType

View file

@ -1,6 +1,7 @@
Version 0.8.14 Version 0.8.14
============== ==============
- ``when T is int`` for generic code
- ``var T`` as a return type: - ``var T`` as a return type:
* for iterators * for iterators
* add ``modGet`` for generics * add ``modGet`` for generics
@ -78,7 +79,6 @@ Library
Low priority Low priority
------------ ------------
- ``when T is int`` for generic code
- ``when validCode(proc())`` for generic code - ``when validCode(proc())`` for generic code
- find a way for easy constructors and destructors; (destructors are much more - find a way for easy constructors and destructors; (destructors are much more
important than constructors) important than constructors)
@ -90,7 +90,7 @@ Version 2
- language change: inheritance should only work with reference types, so that - language change: inheritance should only work with reference types, so that
the ``type`` field is not needed for objects! --> zero overhead aggregation 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. for multi methods.
- explicit nil types? - explicit nil types?

View file

@ -31,11 +31,16 @@ Changes affecting backwards compatibility
- Moved ``strutils.validEmailAddress`` to ``matchers.validEmailAddress``. - Moved ``strutils.validEmailAddress`` to ``matchers.validEmailAddress``.
- The pointer dereference operator ``^`` has been removed, so that ``^`` - The pointer dereference operator ``^`` has been removed, so that ``^``
can now be a user-defined operator. 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 Language Additions
------------------ ------------------
- Added new ``is`` and ``of`` operators.
Compiler Additions Compiler Additions
------------------ ------------------