diff options
-rw-r--r-- | compiler/vm.nim | 2 | ||||
-rw-r--r-- | compiler/vmgen.nim | 35 | ||||
-rw-r--r-- | tests/macros/tvarnimnode.nim | 19 | ||||
-rw-r--r-- | tests/manyloc/argument_parser/argument_parser.nim | 4 | ||||
-rw-r--r-- | todo.txt | 4 |
5 files changed, 51 insertions, 13 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim index 81e712047..0929e072b 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1025,7 +1025,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode = regs[ra].sons[0].flags.incl nfIsRef of opcNCopyNimNode: decodeB(nkMetaNode) - setMeta(regs[ra], copyNode(regs[rb])) + setMeta(regs[ra], copyNode(regs[rb].skipMeta)) of opcNCopyNimTree: decodeB(nkMetaNode) setMeta(regs[ra], copyTree(regs[rb])) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index a6d044e24..206cca0d7 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -321,9 +321,18 @@ proc genAndOr(c: PCtx; n: PNode; opc: TOpcode; dest: var TDest) = c.gen(n.sons[2], dest) c.patch(L1) +proc nilLiteral(n: PNode): PNode = + if n.kind == nkNilLit and n.typ.sym != nil and + n.typ.sym.magic == mPNimrodNode: + let nilo = newNodeIT(nkNilLit, n.info, n.typ) + result = newNodeIT(nkMetaNode, n.info, n.typ) + result.add nilo + else: + result = n + proc rawGenLiteral(c: PCtx; n: PNode): int = result = c.constants.len - c.constants.add n + c.constants.add n.nilLiteral internalAssert result < 0x7fff proc sameConstant*(a, b: PNode): bool = @@ -907,17 +916,20 @@ proc requiresCopy(n: PNode): bool = proc unneededIndirection(n: PNode): bool = n.typ.skipTypes(abstractInst-{tyTypeDesc}).kind == tyRef -proc skipDeref(n: PNode): PNode = - if n.kind in {nkDerefExpr, nkHiddenDeref} and unneededIndirection(n.sons[0]): - result = n.sons[0] - else: - result = n - proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode; flags: TGenFlags) = # a nop for certain types let flags = if opc == opcAddr: flags+{gfAddrOf} else: flags - if unneededIndirection(n.sons[0]): + # consider: + # proc foo(f: var ref int) = + # f = new(int) + # proc blah() = + # var x: ref int + # foo x + # + # The type of 'f' is 'var ref int' and of 'x' is 'ref int'. Hence for + # nkAddr we must not use 'unneededIndirection', but for deref we use it. + if opc != opcAddr and unneededIndirection(n.sons[0]): gen(c, n.sons[0], dest, flags) else: let tmp = c.genx(n.sons[0], flags) @@ -1109,7 +1121,12 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode = result = newNodeIT(nkFloatLit, info, t) of tyVar, tyPointer, tyPtr, tyCString, tySequence, tyString, tyExpr, tyStmt, tyTypeDesc, tyStatic, tyRef: - result = newNodeIT(nkNilLit, info, t) + if t.sym != nil and t.sym.magic == mPNimrodNode: + let nilo = newNodeIT(nkNilLit, info, t) + result = newNodeIT(nkMetaNode, info, t) + result.add nilo + else: + result = newNodeIT(nkNilLit, info, t) of tyProc: if t.callConv != ccClosure: result = newNodeIT(nkNilLit, info, t) diff --git a/tests/macros/tvarnimnode.nim b/tests/macros/tvarnimnode.nim new file mode 100644 index 000000000..73fcc16ea --- /dev/null +++ b/tests/macros/tvarnimnode.nim @@ -0,0 +1,19 @@ +discard """ + output: 10 +""" + +#bug #926 + +import macros + +proc test(f: var PNimrodNode) {.compileTime.} = + f = newNimNode(nnkStmtList) + f.add newCall(newIdentNode("echo"), newLit(10)) + +macro blah(prc: stmt): stmt = + result = prc + + test(result) + +proc test() {.blah.} = + echo 5 diff --git a/tests/manyloc/argument_parser/argument_parser.nim b/tests/manyloc/argument_parser/argument_parser.nim index 95c71c08c..1edda4aa0 100644 --- a/tests/manyloc/argument_parser/argument_parser.nim +++ b/tests/manyloc/argument_parser/argument_parser.nim @@ -178,14 +178,14 @@ template new_parsed_parameter*(tkind: Tparam_kind, expr): Tparsed_parameter = ## #parsed_param3 = new_parsed_parameter(PK_INT, "231") var result {.gensym.}: Tparsed_parameter result.kind = tkind - when tkind == PK_EMPTY: nil + when tkind == PK_EMPTY: discard elif tkind == PK_INT: result.int_val = expr elif tkind == PK_BIGGEST_INT: result.big_int_val = expr elif tkind == PK_FLOAT: result.float_val = expr elif tkind == PK_BIGGEST_FLOAT: result.big_float_val = expr elif tkind == PK_STRING: result.str_val = expr elif tkind == PK_BOOL: result.bool_val = expr - elif tkind == PK_HELP: nil + elif tkind == PK_HELP: discard else: {.error: "unknown kind".} result diff --git a/todo.txt b/todo.txt index 2e6eb708b..656bd06fc 100644 --- a/todo.txt +++ b/todo.txt @@ -1,8 +1,10 @@ version 0.9.4 ============= +- fix macros\tstringinterp.nim: + - problem: needs another level of indirection for 'seq' + - problem: deref is not correct - fix GC issues -- fix macros\tstringinterp.nim - test and fix showoff |