summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xlib/system.nim3
-rwxr-xr-xrod/ast.nim5
-rwxr-xr-xrod/ccgexprs.nim7
-rwxr-xr-xrod/evals.nim13
-rwxr-xr-xrod/semexprs.nim2
-rw-r--r--tests/accept/compile/tcan_inherit_generic.nim10
-rw-r--r--tests/accept/compile/tcan_specialise_generic.nim11
-rw-r--r--tests/accept/compile/tspecialised_is_equivalent.nim15
-rw-r--r--tests/accept/run/tmacro4.nim19
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
+