summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorhlaaftana <10591326+hlaaftana@users.noreply.github.com>2021-11-24 14:22:40 +0300
committerGitHub <noreply@github.com>2021-11-24 12:22:40 +0100
commitc7c6b13a325958c6b55cbec2eb812eb06074101b (patch)
treee90d098448eb1614e1e5d20c3ea32111d83c52b4
parentff39f6e26062651a56d6ac4c24fe5a799c177c50 (diff)
downloadNim-c7c6b13a325958c6b55cbec2eb812eb06074101b.tar.gz
parseExpr/parseStmt accept filename, fixes #13540 (#19182)
-rw-r--r--changelog.md3
-rw-r--r--compiler/vm.nim9
-rw-r--r--compiler/vmgen.nim4
-rw-r--r--lib/core/macros.nim14
-rw-r--r--tests/macros/mparsefile.nim4
-rw-r--r--tests/macros/tparsefile.nim11
6 files changed, 32 insertions, 13 deletions
diff --git a/changelog.md b/changelog.md
index f7f92ad3c..63c3eff40 100644
--- a/changelog.md
+++ b/changelog.md
@@ -13,6 +13,9 @@
 
 ## Standard library additions and changes
 
+- `macros.parseExpr` and `macros.parseStmt` now accept an optional
+  filename argument for more informative errors.
+
 ## `std/smtp`
 
 - Sends `ehlo` first. If the mail server does not understand, it sends `helo` as a fallback.
diff --git a/compiler/vm.nim b/compiler/vm.nim
index b64545081..d58a49f9e 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -1748,11 +1748,10 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       elif instr.opcode == opcNHint:
         message(c.config, info, hintUser, a.strVal)
     of opcParseExprToAst:
-      decodeB(rkNode)
-      # c.debug[pc].line.int - countLines(regs[rb].strVal) ?
+      decodeBC(rkNode)
       var error: string
       let ast = parseString(regs[rb].node.strVal, c.cache, c.config,
-                            toFullPath(c.config, c.debug[pc]), c.debug[pc].line.int,
+                            regs[rc].node.strVal, 0,
                             proc (conf: ConfigRef; info: TLineInfo; msg: TMsgKind; arg: string) {.nosinks.} =
                               if error.len == 0 and msg <= errMax:
                                 error = formatMsg(conf, info, msg, arg))
@@ -1764,10 +1763,10 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       else:
         regs[ra].node = ast[0]
     of opcParseStmtToAst:
-      decodeB(rkNode)
+      decodeBC(rkNode)
       var error: string
       let ast = parseString(regs[rb].node.strVal, c.cache, c.config,
-                            toFullPath(c.config, c.debug[pc]), c.debug[pc].line.int,
+                            regs[rc].node.strVal, 0,
                             proc (conf: ConfigRef; info: TLineInfo; msg: TMsgKind; arg: string) {.nosinks.} =
                               if error.len == 0 and msg <= errMax:
                                 error = formatMsg(conf, info, msg, arg))
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index bb095d3ee..9a823dff4 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -1225,9 +1225,9 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
     unused(c, n, dest)
     genBinaryStmtVar(c, n, opcAddSeqElem)
   of mParseExprToAst:
-    genUnaryABC(c, n, dest, opcParseExprToAst)
+    genBinaryABC(c, n, dest, opcParseExprToAst)
   of mParseStmtToAst:
-    genUnaryABC(c, n, dest, opcParseStmtToAst)
+    genBinaryABC(c, n, dest, opcParseStmtToAst)
   of mTypeTrait:
     let tmp = c.genx(n[1])
     if dest < 0: dest = c.getTemp(n.typ)
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index c7d56c0ed..444783b5a 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -511,27 +511,29 @@ proc lineInfo*(arg: NimNode): string =
   ## Return line info in the form `filepath(line, column)`.
   $arg.lineInfoObj
 
-proc internalParseExpr(s: string): NimNode {.
+proc internalParseExpr(s, filename: string): NimNode {.
   magic: "ParseExprToAst", noSideEffect.}
 
-proc internalParseStmt(s: string): NimNode {.
+proc internalParseStmt(s, filename: string): NimNode {.
   magic: "ParseStmtToAst", noSideEffect.}
 
 proc internalErrorFlag*(): string {.magic: "NError", noSideEffect.}
   ## Some builtins set an error flag. This is then turned into a proper
   ## exception. **Note**: Ordinary application code should not call this.
 
-proc parseExpr*(s: string): NimNode {.noSideEffect.} =
+proc parseExpr*(s: string; filename: string = ""): NimNode {.noSideEffect.} =
   ## Compiles the passed string to its AST representation.
   ## Expects a single expression. Raises `ValueError` for parsing errors.
-  result = internalParseExpr(s)
+  ## A filename can be given for more informative errors.
+  result = internalParseExpr(s, filename)
   let x = internalErrorFlag()
   if x.len > 0: raise newException(ValueError, x)
 
-proc parseStmt*(s: string): NimNode {.noSideEffect.} =
+proc parseStmt*(s: string; filename: string = ""): NimNode {.noSideEffect.} =
   ## Compiles the passed string to its AST representation.
   ## Expects one or more statements. Raises `ValueError` for parsing errors.
-  result = internalParseStmt(s)
+  ## A filename can be given for more informative errors.
+  result = internalParseStmt(s, filename)
   let x = internalErrorFlag()
   if x.len > 0: raise newException(ValueError, x)
 
diff --git a/tests/macros/mparsefile.nim b/tests/macros/mparsefile.nim
new file mode 100644
index 000000000..8ac99d568
--- /dev/null
+++ b/tests/macros/mparsefile.nim
@@ -0,0 +1,4 @@
+let a = 1
+let b = 2
+let c =
+let d = 4
diff --git a/tests/macros/tparsefile.nim b/tests/macros/tparsefile.nim
new file mode 100644
index 000000000..a41223f80
--- /dev/null
+++ b/tests/macros/tparsefile.nim
@@ -0,0 +1,11 @@
+import macros
+
+static:
+  let fn = "mparsefile.nim"
+  var raised = false
+  try:
+    discard parseStmt(staticRead(fn), filename = fn)
+  except ValueError as e:
+    raised = true
+    doAssert e.msg == "mparsefile.nim(4, 1) Error: invalid indentation"
+  doAssert raised