make quote ast a ref type (#5246)

* make quote ast a ref type
* recursive set flag isRef for quoted ast
This commit is contained in:
Arne Döring
2017-01-19 16:39:18 +01:00
committed by Andreas Rumpf
parent b85898cd41
commit 130f30ddb2
2 changed files with 75 additions and 0 deletions

View File

@@ -401,6 +401,11 @@ template handleJmpBack() {.dirty.} =
globalError(c.debug[pc], errTooManyIterations)
dec(c.loopIterations)
proc recSetFlagIsRef(arg: PNode) =
arg.flags.incl(nfIsRef)
for i in 0 ..< arg.safeLen:
arg.sons[i].recSetFlagIsRef
proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
var pc = start
var tos = tos
@@ -926,6 +931,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
macroCall.add(newSymNode(prc))
for i in 1 .. rc-1: macroCall.add(regs[rb+i].regToNode)
let a = evalTemplate(macroCall, prc, genSymOwner)
a.recSetFlagIsRef
ensureKind(rkNode)
regs[ra].node = a
of opcTJmp:

69
tests/vm/tnimnode.nim Normal file
View File

@@ -0,0 +1,69 @@
import macros
proc assertEq(arg0,arg1: string): void =
if arg0 != arg1:
raiseAssert("strings not equal:\n" & arg0 & "\n" & arg1)
static:
# a simple assignment of stmtList to another variable
var node: NimNode
# an assignment of stmtList into an array
var nodeArray: array[1, NimNode]
# an assignment of stmtList into a seq
var nodeSeq = newSeq[NimNode](1)
proc checkNode(arg: NimNode; name: string): void {. compileTime .} =
echo "checking ", name
assertEq arg.lispRepr , "StmtList(DiscardStmt(Empty()))"
node = arg
nodeArray = [arg]
nodeSeq[0] = arg
arg.add newCall(ident"echo", newLit("Hello World"))
assertEq arg.lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(!"echo"), StrLit(Hello World)))"""
assertEq node.lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(!"echo"), StrLit(Hello World)))"""
assertEq nodeArray[0].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(!"echo"), StrLit(Hello World)))"""
assertEq nodeSeq[0].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(!"echo"), StrLit(Hello World)))"""
echo "OK"
static:
# the root node that is used to generate the Ast
var stmtList: NimNode
stmtList = newStmtList(nnkDiscardStmt.newTree(newEmptyNode()))
checkNode(stmtList, "direct construction")
macro foo(stmtList: untyped): untyped =
checkNode(stmtList, "untyped macro argument")
foo:
discard
static:
stmtList = quote do:
discard
checkNode(stmtList, "create with quote")
static:
echo "testing body from loop"
var loop = quote do:
for i in 0 ..< 10:
discard
let innerBody = loop[0][2]
innerBody.add newCall(ident"echo", newLit("Hello World"))
assertEq loop[0][2].lispRepr, innerBody.lispRepr
echo "OK"