summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/vm.nim6
-rw-r--r--tests/vm/tnimnode.nim69
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"
+  
+