Skip to content

Commit

Permalink
parseExpr/parseStmt accept filename, fixes #13540 (#19182)
Browse files Browse the repository at this point in the history
  • Loading branch information
metagn authored Nov 24, 2021
1 parent ff39f6e commit c7c6b13
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 13 deletions.
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
9 changes: 4 additions & 5 deletions compiler/vm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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))
Expand Down
4 changes: 2 additions & 2 deletions compiler/vmgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
14 changes: 8 additions & 6 deletions lib/core/macros.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
4 changes: 4 additions & 0 deletions tests/macros/mparsefile.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
let a = 1
let b = 2
let c =
let d = 4
11 changes: 11 additions & 0 deletions tests/macros/tparsefile.nim
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit c7c6b13

Please sign in to comment.