summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorandri lim <jangko128@gmail.com>2018-08-06 04:38:21 +0700
committerAndreas Rumpf <rumpf_a@web.de>2018-08-05 23:38:21 +0200
commit6e3d1dced55229309a85849a45c877a798080453 (patch)
treeddb900044aee6d790dad6543a90b2ced02f9674b
parent6fffadb7fdd60174891fba6de302bb748cd7ca60 (diff)
downloadNim-6e3d1dced55229309a85849a45c877a798080453.tar.gz
fixes #5617, 'copyLineInfo' addition (#8523)
-rw-r--r--changelog.md1
-rw-r--r--compiler/vm.nim27
-rw-r--r--compiler/vmdef.nim2
-rw-r--r--compiler/vmgen.nim16
-rw-r--r--lib/core/macros.nim3
-rw-r--r--tests/macros/tlineinfo.nim14
6 files changed, 40 insertions, 23 deletions
diff --git a/changelog.md b/changelog.md
index 045286ef9..4c19abfc0 100644
--- a/changelog.md
+++ b/changelog.md
@@ -91,6 +91,7 @@
 - ``parseOct`` and ``parseBin`` in parseutils now also support the ``maxLen`` argument similar to ``parseHexInt``
 - Added the proc ``flush`` for memory mapped files.
 - Added the ``MemMapFileStream``.
+- Added ``macros.copyLineInfo`` to copy lineInfo from other node
 
 ### Library changes
 
diff --git a/compiler/vm.nim b/compiler/vm.nim
index a6ec4788b..d4b041dea 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -1422,24 +1422,23 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       ensureKind(rkNode)
       if c.callsite != nil: regs[ra].node = c.callsite
       else: stackTrace(c, tos, pc, errFieldXNotFound & "callsite")
-    of opcNGetFile:
-      decodeB(rkNode)
-      let n = regs[rb].node
-      regs[ra].node = newStrNode(nkStrLit, toFullPath(c.config, n.info))
-      regs[ra].node.info = n.info
-      regs[ra].node.typ = n.typ
-    of opcNGetLine:
-      decodeB(rkNode)
+    of opcNGetLineInfo:
+      decodeBImm(rkNode)
       let n = regs[rb].node
-      regs[ra].node = newIntNode(nkIntLit, n.info.line.int)
+      case imm
+      of 0: # getFile
+        regs[ra].node = newStrNode(nkStrLit, toFullPath(c.config, n.info))
+      of 1: # getLine
+        regs[ra].node = newIntNode(nkIntLit, n.info.line.int)
+      of 2: # getColumn
+        regs[ra].node = newIntNode(nkIntLit, n.info.col)
+      else:
+        internalAssert c.config, false
       regs[ra].node.info = n.info
       regs[ra].node.typ = n.typ
-    of opcNGetColumn:
+    of opcNSetLineInfo:
       decodeB(rkNode)
-      let n = regs[rb].node
-      regs[ra].node = newIntNode(nkIntLit, n.info.col)
-      regs[ra].node.info = n.info
-      regs[ra].node.typ = n.typ
+      regs[ra].node.info = regs[rb].node.info
     of opcEqIdent:
       decodeBC(rkInt)
       # aliases for shorter and easier to understand code below
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index 866b79568..a4489513a 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -102,7 +102,7 @@ type
     opcNError,
     opcNWarning,
     opcNHint,
-    opcNGetLine, opcNGetColumn, opcNGetFile,
+    opcNGetLineInfo, opcNSetLineInfo,
     opcEqIdent,
     opcStrToIdent,
     opcGetImpl,
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 3b5ea4beb..965c75485 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -1181,14 +1181,14 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
   of mSameNodeType: genBinaryABC(c, n, dest, opcSameNodeType)
   of mNLineInfo:
     case n[0].sym.name.s
-    of "getFile":
-      genUnaryABC(c, n, dest, opcNGetFile)
-    of "getLine":
-      genUnaryABC(c, n, dest, opcNGetLine)
-    of "getColumn":
-      genUnaryABC(c, n, dest, opcNGetColumn)
-    else:
-      internalAssert c.config, false
+    of "getFile": genUnaryABI(c, n, dest, opcNGetLineInfo, 0)
+    of "getLine": genUnaryABI(c, n, dest, opcNGetLineInfo, 1)
+    of "getColumn": genUnaryABI(c, n, dest, opcNGetLineInfo, 2)
+    of "copyLineInfo":
+      internalAssert c.config, n.len == 3
+      unused(c, n, dest)
+      genBinaryStmt(c, n, opcNSetLineInfo)
+    else: internalAssert c.config, false
   of mNHint:
     unused(c, n, dest)
     genUnaryStmt(c, n, opcNHint)
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index d4e8ada0a..90fea440e 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -432,6 +432,9 @@ proc getLine(arg: NimNode): int {.magic: "NLineInfo", noSideEffect.}
 proc getColumn(arg: NimNode): int {.magic: "NLineInfo", noSideEffect.}
 proc getFile(arg: NimNode): string {.magic: "NLineInfo", noSideEffect.}
 
+proc copyLineInfo*(arg: NimNode, info: NimNode) {.magic: "NLineInfo", noSideEffect.}
+  ## copy lineinfo from info node
+
 proc lineInfoObj*(n: NimNode): LineInfo {.compileTime.} =
   ## returns ``LineInfo`` of ``n``, using absolute path for ``filename``
   result.filename = n.getFile
diff --git a/tests/macros/tlineinfo.nim b/tests/macros/tlineinfo.nim
new file mode 100644
index 000000000..2ab0e1ee8
--- /dev/null
+++ b/tests/macros/tlineinfo.nim
@@ -0,0 +1,14 @@
+# issue #5617, feature request
+# Ability to set a NimNode's lineinfo
+import macros
+
+type
+  Test = object
+
+macro mixer(n: typed): untyped =
+  let x = newIdentNode("echo")
+  x.copyLineInfo(n)
+  result = newLit(x.lineInfo == n.lineInfo)
+
+var z = mixer(Test)
+doAssert z