added 'reset' magic proc
This commit is contained in:
parent
032599c156
commit
bd4f0b94ae
9 changed files with 73 additions and 12 deletions
|
|
@ -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
|
## the object! This means that for each object of type `T` the finalizer
|
||||||
## will be called!
|
## will be called!
|
||||||
|
|
||||||
proc reset*(obj: var T) {.magic: "Reset", noSideEffect.}
|
proc reset*[T](obj: var T) {.magic: "Reset", noSideEffect.}
|
||||||
proc reset*(obj: ref T) {.noSideEffect.} = reset(obj^)
|
|
||||||
## resets an object `obj` to its initial (binary zero) value. This needs to
|
## resets an object `obj` to its initial (binary zero) value. This needs to
|
||||||
## be called before any possible `object branch transition`:idx:.
|
## be called before any possible `object branch transition`:idx:.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -331,8 +331,9 @@ type
|
||||||
mPlusSet, mMinusSet, mSymDiffSet, mConStrStr, mConArrArr, mConArrT,
|
mPlusSet, mMinusSet, mSymDiffSet, mConStrStr, mConArrArr, mConArrT,
|
||||||
mConTArr, mConTT, mSlice, mAppendStrCh, mAppendStrStr, mAppendSeqElem,
|
mConTArr, mConTT, mSlice, mAppendStrCh, mAppendStrStr, mAppendSeqElem,
|
||||||
mInRange, mInSet, mRepr, mExit, mSetLengthStr, mSetLengthSeq, mAssert,
|
mInRange, mInSet, mRepr, mExit, mSetLengthStr, mSetLengthSeq, mAssert,
|
||||||
mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast, mNewString, mArray,
|
mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast, mNewString, mReset,
|
||||||
mOpenArray, mRange, mSet, mSeq, mOrdinal, mInt, mInt8, mInt16, mInt32,
|
mArray, mOpenArray, mRange, mSet, mSeq,
|
||||||
|
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,
|
||||||
mIsMainModule, mCompileDate, mCompileTime, mNimrodVersion, mNimrodMajor,
|
mIsMainModule, mCompileDate, mCompileTime, mNimrodVersion, mNimrodMajor,
|
||||||
|
|
|
||||||
|
|
@ -931,6 +931,12 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
|
||||||
dest.r = ropef("$1->data[$1->Sup.len-1]", [rdLoc(a)])
|
dest.r = ropef("$1->data[$1->Sup.len-1]", [rdLoc(a)])
|
||||||
genAssignment(p, dest, b, {needToCopy, afDestIsNil})
|
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) =
|
proc genNew(p: BProc, e: PNode) =
|
||||||
var
|
var
|
||||||
a, b: TLoc
|
a, b: TLoc
|
||||||
|
|
@ -1449,6 +1455,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
mInSet:
|
mInSet:
|
||||||
genSetOp(p, e, d, op)
|
genSetOp(p, e, d, op)
|
||||||
of mNewString, mCopyStr, mCopyStrLast, mExit: genCall(p, e, d)
|
of mNewString, mCopyStr, mCopyStrLast, mExit: genCall(p, e, d)
|
||||||
|
of mReset: genReset(p, e)
|
||||||
of mEcho: genEcho(p, e)
|
of mEcho: genEcho(p, e)
|
||||||
of mArrToSeq: genArrToSeq(p, e, d)
|
of mArrToSeq: genArrToSeq(p, e, d)
|
||||||
of mNLen..mNError:
|
of mNLen..mNError:
|
||||||
|
|
|
||||||
|
|
@ -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
|
# XXX this does not work yet! Better to compile too much than to compile to
|
||||||
# few programs
|
# few programs
|
||||||
|
|
||||||
|
proc myreset(n: PNode) {.inline.} =
|
||||||
|
when defined(system.reset): reset(n^)
|
||||||
|
|
||||||
proc evalIf(c: PEvalContext, n: PNode): PNode =
|
proc evalIf(c: PEvalContext, n: PNode): PNode =
|
||||||
var i = 0
|
var i = 0
|
||||||
var length = sonsLen(n)
|
var length = sonsLen(n)
|
||||||
|
|
@ -361,7 +364,7 @@ proc evalAsgn(c: PEvalContext, n: PNode): PNode =
|
||||||
var x = result
|
var x = result
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
when defined(system.reset): reset(x)
|
myreset(x)
|
||||||
x.kind = result.kind
|
x.kind = result.kind
|
||||||
x.typ = result.typ
|
x.typ = result.typ
|
||||||
case x.kind
|
case x.kind
|
||||||
|
|
@ -479,17 +482,13 @@ proc evalNew(c: PEvalContext, n: PNode): PNode =
|
||||||
var a = result
|
var a = result
|
||||||
var t = skipTypes(n.sons[1].typ, abstractVar)
|
var t = skipTypes(n.sons[1].typ, abstractVar)
|
||||||
if a.kind == nkEmpty: InternalError(n.info, "first parameter is empty")
|
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.kind = nkRefTy
|
||||||
a.info = n.info
|
a.info = n.info
|
||||||
a.typ = t
|
a.typ = t
|
||||||
a.sons = nil
|
a.sons = nil
|
||||||
addSon(a, getNullValue(t.sons[0], n.info))
|
addSon(a, getNullValue(t.sons[0], n.info))
|
||||||
result = emptyNode
|
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 =
|
proc evalDeref(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
result = evalAux(c, n.sons[0], {efLValue})
|
result = evalAux(c, n.sons[0], {efLValue})
|
||||||
|
|
@ -646,7 +645,7 @@ proc evalNewSeq(c: PEvalContext, n: PNode): PNode =
|
||||||
var b = result
|
var b = result
|
||||||
var t = skipTypes(n.sons[1].typ, abstractVar)
|
var t = skipTypes(n.sons[1].typ, abstractVar)
|
||||||
if a.kind == nkEmpty: InternalError(n.info, "first parameter is empty")
|
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.kind = nkBracket
|
||||||
a.info = n.info
|
a.info = n.info
|
||||||
a.typ = t
|
a.typ = t
|
||||||
|
|
|
||||||
|
|
@ -392,7 +392,7 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) =
|
||||||
const
|
const
|
||||||
FakeVarParams = {mNew, mNewFinalize, mInc, ast.mDec, mIncl, mExcl,
|
FakeVarParams = {mNew, mNewFinalize, mInc, ast.mDec, mIncl, mExcl,
|
||||||
mSetLengthStr, mSetLengthSeq, mAppendStrCh, mAppendStrStr, mSwap,
|
mSetLengthStr, mSetLengthSeq, mAppendStrCh, mAppendStrStr, mSwap,
|
||||||
mAppendSeqElem, mNewSeq}
|
mAppendSeqElem, mNewSeq, mReset}
|
||||||
checkMinSonsLen(n, 1)
|
checkMinSonsLen(n, 1)
|
||||||
var t = n.sons[0].typ
|
var t = n.sons[0].typ
|
||||||
if (n.sons[0].kind == nkSym) and (n.sons[0].sym.magic in FakeVarParams):
|
if (n.sons[0].kind == nkSym) and (n.sons[0].sym.magic in FakeVarParams):
|
||||||
|
|
|
||||||
10
tests/accept/compile/tcan_inherit_generic.nim
Normal file
10
tests/accept/compile/tcan_inherit_generic.nim
Normal file
|
|
@ -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]
|
||||||
|
|
||||||
11
tests/accept/compile/tcan_specialise_generic.nim
Normal file
11
tests/accept/compile/tcan_specialise_generic.nim
Normal file
|
|
@ -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]
|
||||||
|
|
||||||
|
|
||||||
15
tests/accept/compile/tspecialised_is_equivalent.nim
Normal file
15
tests/accept/compile/tspecialised_is_equivalent.nim
Normal file
|
|
@ -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
|
||||||
|
|
||||||
19
tests/accept/run/tmacro4.nim
Normal file
19
tests/accept/run/tmacro4.nim
Normal file
|
|
@ -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
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue