diff options
-rw-r--r-- | compiler/vm.nim | 6 | ||||
-rw-r--r-- | tests/vm/tnimnode.nim | 69 |
2 files changed, 75 insertions, 0 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim index 91fe3d209..344ad6610 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -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: diff --git a/tests/vm/tnimnode.nim b/tests/vm/tnimnode.nim new file mode 100644 index 000000000..1508419c4 --- /dev/null +++ b/tests/vm/tnimnode.nim @@ -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" + + |