diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2016-10-27 15:37:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-10-27 15:37:34 +0200 |
commit | cacbf8b32c7b910eeb6b8b5d37adf2a7dd2f343c (patch) | |
tree | faddd5fb0ea8009db010f75c8bdff642ab5e4c2e | |
parent | 38ad7400fa4ecc475b587456770e4d981dc9d037 (diff) | |
parent | 74c6500a30b99fde9af5d17a87723dcf18309964 (diff) | |
download | Nim-cacbf8b32c7b910eeb6b8b5d37adf2a7dd2f343c.tar.gz |
Merge pull request #4963 from jangko/macro_error_improvement
Macro.error improvement fixes #4915
-rw-r--r-- | compiler/vm.nim | 12 | ||||
-rw-r--r-- | compiler/vmgen.nim | 2 | ||||
-rw-r--r-- | lib/core/macros.nim | 8 | ||||
-rw-r--r-- | tests/clearmsg/tmacroerrorproc.nim | 13 | ||||
-rw-r--r-- | web/news/e029_version_0_16_0.rst | 2 |
5 files changed, 28 insertions, 9 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim index be522ced0..c4e8df90e 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -76,12 +76,13 @@ proc stackTraceAux(c: PCtx; x: PStackFrame; pc: int; recursionLimit=100) = msgWriteln(s) proc stackTrace(c: PCtx, tos: PStackFrame, pc: int, - msg: TMsgKind, arg = "") = + msg: TMsgKind, arg = "", n: PNode = nil) = msgWriteln("stack trace: (most recent call last)") stackTraceAux(c, tos, pc) # XXX test if we want 'globalError' for every mode - if c.mode == emRepl: globalError(c.debug[pc], msg, arg) - else: localError(c.debug[pc], msg, arg) + let lineInfo = if n == nil: c.debug[pc] else: n.info + if c.mode == emRepl: globalError(lineInfo, msg, arg) + else: localError(lineInfo, msg, arg) proc bailOut(c: PCtx; tos: PStackFrame) = stackTrace(c, tos, c.exceptionInstr, errUnhandledExceptionX, @@ -1245,7 +1246,10 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = regs[rc].node.strVal, regs[rd].node.strVal, c.debug[pc]) of opcNError: - stackTrace(c, tos, pc, errUser, regs[ra].node.strVal) + decodeB(rkNode) + let a = regs[ra].node + let b = regs[rb].node + stackTrace(c, tos, pc, errUser, a.strVal, if b.kind == nkNilLit: nil else: b) of opcNWarning: message(c.debug[pc], warnUser, regs[ra].node.strVal) of opcNHint: diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 6bfc33f00..ed8f3f338 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1068,7 +1068,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = else: # setter unused(n, dest) - genUnaryStmt(c, n, opcNError) + genBinaryStmt(c, n, opcNError) of mNCallSite: if dest < 0: dest = c.getTemp(n.typ) c.gABC(n, opcCallSite, dest) diff --git a/lib/core/macros.nim b/lib/core/macros.nim index d584b1ac5..b0ef54397 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -235,7 +235,7 @@ proc getImpl*(s: NimSym): NimNode {.magic: "GetImpl", noSideEffect.} = ## const. discard -proc error*(msg: string) {.magic: "NError", benign.} +proc error*(msg: string, n: NimNode = nil) {.magic: "NError", benign.} ## writes an error message at compile time proc warning*(msg: string) {.magic: "NWarning", benign.} @@ -377,19 +377,19 @@ proc expectKind*(n: NimNode, k: NimNodeKind) {.compileTime.} = ## checks that `n` is of kind `k`. If this is not the case, ## compilation aborts with an error message. This is useful for writing ## macros that check the AST that is passed to them. - if n.kind != k: error("Expected a node of kind " & $k & ", got " & $n.kind) + if n.kind != k: error("Expected a node of kind " & $k & ", got " & $n.kind, n) proc expectMinLen*(n: NimNode, min: int) {.compileTime.} = ## checks that `n` has at least `min` children. If this is not the case, ## compilation aborts with an error message. This is useful for writing ## macros that check its number of arguments. - if n.len < min: error("macro expects a node with " & $min & " children") + if n.len < min: error("macro expects a node with " & $min & " children", n) proc expectLen*(n: NimNode, len: int) {.compileTime.} = ## checks that `n` has exactly `len` children. If this is not the case, ## compilation aborts with an error message. This is useful for writing ## macros that check its number of arguments. - if n.len != len: error("macro expects a node with " & $len & " children") + if n.len != len: error("macro expects a node with " & $len & " children", n) proc newTree*(kind: NimNodeKind, children: varargs[NimNode]): NimNode {.compileTime.} = diff --git a/tests/clearmsg/tmacroerrorproc.nim b/tests/clearmsg/tmacroerrorproc.nim new file mode 100644 index 000000000..9a6ff6a06 --- /dev/null +++ b/tests/clearmsg/tmacroerrorproc.nim @@ -0,0 +1,13 @@ +discard """ + file: "tmacroerrorproc.nim" + line: 13 + errormsg: "Expected a node of kind nnkCharLit, got nnkCommand" +""" +# issue #4915 +import macros + +macro mixer(n: typed): untyped = + expectKind(n, nnkCharLit) + +mixer: + echo "owh" \ No newline at end of file diff --git a/web/news/e029_version_0_16_0.rst b/web/news/e029_version_0_16_0.rst index 1d3f3b3df..2f6c72c82 100644 --- a/web/news/e029_version_0_16_0.rst +++ b/web/news/e029_version_0_16_0.rst @@ -31,6 +31,8 @@ Changes affecting backwards compatibility Library Additions ----------------- +- Added new parameter to ``error`` proc of ``macro`` module to provide better + error message Tool Additions -------------- |