diff options
-rwxr-xr-x | lib/system.nim | 3 | ||||
-rwxr-xr-x | rod/ast.nim | 5 | ||||
-rwxr-xr-x | rod/ccgexprs.nim | 7 | ||||
-rwxr-xr-x | rod/evals.nim | 13 | ||||
-rwxr-xr-x | rod/semexprs.nim | 2 | ||||
-rw-r--r-- | tests/accept/compile/tcan_inherit_generic.nim | 10 | ||||
-rw-r--r-- | tests/accept/compile/tcan_specialise_generic.nim | 11 | ||||
-rw-r--r-- | tests/accept/compile/tspecialised_is_equivalent.nim | 15 | ||||
-rw-r--r-- | tests/accept/run/tmacro4.nim | 19 |
9 files changed, 73 insertions, 12 deletions
diff --git a/lib/system.nim b/lib/system.nim index a43b0435b..09b85d32b 100755 --- a/lib/system.nim +++ b/lib/system.nim @@ -88,8 +88,7 @@ proc new*[T](a: var ref T, finalizer: proc (x: ref T)) {. ## the object! This means that for each object of type `T` the finalizer ## will be called! -proc reset*(obj: var T) {.magic: "Reset", noSideEffect.} -proc reset*(obj: ref T) {.noSideEffect.} = reset(obj^) +proc reset*[T](obj: var T) {.magic: "Reset", noSideEffect.} ## resets an object `obj` to its initial (binary zero) value. This needs to ## be called before any possible `object branch transition`:idx:. diff --git a/rod/ast.nim b/rod/ast.nim index 91eb37506..e19192f1f 100755 --- a/rod/ast.nim +++ b/rod/ast.nim @@ -331,8 +331,9 @@ type mPlusSet, mMinusSet, mSymDiffSet, mConStrStr, mConArrArr, mConArrT, mConTArr, mConTT, mSlice, mAppendStrCh, mAppendStrStr, mAppendSeqElem, mInRange, mInSet, mRepr, mExit, mSetLengthStr, mSetLengthSeq, mAssert, - mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast, mNewString, mArray, - mOpenArray, mRange, mSet, mSeq, mOrdinal, mInt, mInt8, mInt16, mInt32, + mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast, mNewString, mReset, + mArray, mOpenArray, mRange, mSet, mSeq, + mOrdinal, mInt, mInt8, mInt16, mInt32, mInt64, mFloat, mFloat32, mFloat64, mBool, mChar, mString, mCstring, mPointer, mEmptySet, mIntSetBaseType, mNil, mExpr, mStmt, mTypeDesc, mIsMainModule, mCompileDate, mCompileTime, mNimrodVersion, mNimrodMajor, diff --git a/rod/ccgexprs.nim b/rod/ccgexprs.nim index 8da08347c..32cc8fb32 100755 --- a/rod/ccgexprs.nim +++ b/rod/ccgexprs.nim @@ -931,6 +931,12 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) = dest.r = ropef("$1->data[$1->Sup.len-1]", [rdLoc(a)]) genAssignment(p, dest, b, {needToCopy, afDestIsNil}) +proc genReset(p: BProc, n: PNode) = + var a: TLoc + InitLocExpr(p, n.sons[1], a) + appcg(p, cpsStmts, "#genericReset((void*)$1, $2);$n", + [addrLoc(a), genTypeInfo(p.module, skipTypes(a.t, abstractVarRange))]) + proc genNew(p: BProc, e: PNode) = var a, b: TLoc @@ -1449,6 +1455,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = mInSet: genSetOp(p, e, d, op) of mNewString, mCopyStr, mCopyStrLast, mExit: genCall(p, e, d) + of mReset: genReset(p, e) of mEcho: genEcho(p, e) of mArrToSeq: genArrToSeq(p, e, d) of mNLen..mNError: diff --git a/rod/evals.nim b/rod/evals.nim index f25db3d8a..31c0e629a 100755 --- a/rod/evals.nim +++ b/rod/evals.nim @@ -98,6 +98,9 @@ proc isSpecial(n: PNode): bool {.inline.} = # XXX this does not work yet! Better to compile too much than to compile to # few programs +proc myreset(n: PNode) {.inline.} = + when defined(system.reset): reset(n^) + proc evalIf(c: PEvalContext, n: PNode): PNode = var i = 0 var length = sonsLen(n) @@ -361,7 +364,7 @@ proc evalAsgn(c: PEvalContext, n: PNode): PNode = var x = result result = evalAux(c, n.sons[1], {}) if isSpecial(result): return - when defined(system.reset): reset(x) + myreset(x) x.kind = result.kind x.typ = result.typ case x.kind @@ -479,17 +482,13 @@ proc evalNew(c: PEvalContext, n: PNode): PNode = var a = result var t = skipTypes(n.sons[1].typ, abstractVar) if a.kind == nkEmpty: InternalError(n.info, "first parameter is empty") - # changing the node kind is ugly and suggests deep problems: + myreset(a) a.kind = nkRefTy a.info = n.info a.typ = t a.sons = nil addSon(a, getNullValue(t.sons[0], n.info)) result = emptyNode - when false: - var t = skipTypes(n.sons[1].typ, abstractVar) - result = newNodeIT(nkRefTy, n.info, t) - addSon(result, getNullValue(t.sons[0], n.info)) proc evalDeref(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode = result = evalAux(c, n.sons[0], {efLValue}) @@ -646,7 +645,7 @@ proc evalNewSeq(c: PEvalContext, n: PNode): PNode = var b = result var t = skipTypes(n.sons[1].typ, abstractVar) if a.kind == nkEmpty: InternalError(n.info, "first parameter is empty") - # changing the node kind is ugly and suggests deep problems: + myreset(a) a.kind = nkBracket a.info = n.info a.typ = t diff --git a/rod/semexprs.nim b/rod/semexprs.nim index cf9900155..5bd9bd2b8 100755 --- a/rod/semexprs.nim +++ b/rod/semexprs.nim @@ -392,7 +392,7 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) = const FakeVarParams = {mNew, mNewFinalize, mInc, ast.mDec, mIncl, mExcl, mSetLengthStr, mSetLengthSeq, mAppendStrCh, mAppendStrStr, mSwap, - mAppendSeqElem, mNewSeq} + mAppendSeqElem, mNewSeq, mReset} checkMinSonsLen(n, 1) var t = n.sons[0].typ if (n.sons[0].kind == nkSym) and (n.sons[0].sym.magic in FakeVarParams): diff --git a/tests/accept/compile/tcan_inherit_generic.nim b/tests/accept/compile/tcan_inherit_generic.nim new file mode 100644 index 000000000..fa92c7986 --- /dev/null +++ b/tests/accept/compile/tcan_inherit_generic.nim @@ -0,0 +1,10 @@ +## +## can_inherit_generic Nimrod Module +## +## Created by Eric Doughty-Papassideris on 2011-02-16. +## Copyright (c) 2011 FWA. All rights reserved. + +type + TGen[T] = object + TSpef[T] = object of TGen[T] + diff --git a/tests/accept/compile/tcan_specialise_generic.nim b/tests/accept/compile/tcan_specialise_generic.nim new file mode 100644 index 000000000..f98a8bf95 --- /dev/null +++ b/tests/accept/compile/tcan_specialise_generic.nim @@ -0,0 +1,11 @@ +## +## can_specialise_generic Nimrod Module +## +## Created by Eric Doughty-Papassideris on 2011-02-16. +## Copyright (c) 2011 FWA. All rights reserved. + +type + TGen[T] = object + TSpef = object of TGen[string] + + diff --git a/tests/accept/compile/tspecialised_is_equivalent.nim b/tests/accept/compile/tspecialised_is_equivalent.nim new file mode 100644 index 000000000..60b976e90 --- /dev/null +++ b/tests/accept/compile/tspecialised_is_equivalent.nim @@ -0,0 +1,15 @@ +## +## specialised_is_equivalent Nimrod Module +## +## Created by Eric Doughty-Papassideris on 2011-02-16. +## Copyright (c) 2011 FWA. All rights reserved. + +type + TGen[T] = tuple[a: T] + TSpef = tuple[a: string] + +var + a: TGen[string] + b: TSpef +a = b + diff --git a/tests/accept/run/tmacro4.nim b/tests/accept/run/tmacro4.nim new file mode 100644 index 000000000..f90a8a434 --- /dev/null +++ b/tests/accept/run/tmacro4.nim @@ -0,0 +1,19 @@ +discard """ + output: "after" +""" + +import + macros, strutils + +macro test_macro*(n: stmt): stmt = + result = newNimNode(nnkStmtList) + var ass : PNimrodNode = newNimNode(nnkAsgn) + add(ass, newIdentNode("str")) + add(ass, newStrLitNode("after")) + add(result, ass) +when isMainModule: + var str: string = "before" + test_macro(str): + var i : integer = 123 + echo str + |