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:
parent
b85898cd41
commit
130f30ddb2
2 changed files with 75 additions and 0 deletions
|
|
@ -401,6 +401,11 @@ template handleJmpBack() {.dirty.} =
|
||||||
globalError(c.debug[pc], errTooManyIterations)
|
globalError(c.debug[pc], errTooManyIterations)
|
||||||
dec(c.loopIterations)
|
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 =
|
proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
var pc = start
|
var pc = start
|
||||||
var tos = tos
|
var tos = tos
|
||||||
|
|
@ -926,6 +931,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
macroCall.add(newSymNode(prc))
|
macroCall.add(newSymNode(prc))
|
||||||
for i in 1 .. rc-1: macroCall.add(regs[rb+i].regToNode)
|
for i in 1 .. rc-1: macroCall.add(regs[rb+i].regToNode)
|
||||||
let a = evalTemplate(macroCall, prc, genSymOwner)
|
let a = evalTemplate(macroCall, prc, genSymOwner)
|
||||||
|
a.recSetFlagIsRef
|
||||||
ensureKind(rkNode)
|
ensureKind(rkNode)
|
||||||
regs[ra].node = a
|
regs[ra].node = a
|
||||||
of opcTJmp:
|
of opcTJmp:
|
||||||
|
|
|
||||||
69
tests/vm/tnimnode.nim
Normal file
69
tests/vm/tnimnode.nim
Normal 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"
|
||||||
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue