Skip to content

Commit

Permalink
parseExpr/parseStmt accept filename, fixes nim-lang#13540 (nim-lang#1…
Browse files Browse the repository at this point in the history
  • Loading branch information
metagn authored and dsrw committed Jan 31, 2022
1 parent 71da996 commit a797a04
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 13 deletions.
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
filename argument for more informative errors.
- Module `colors` expanded with missing colors from the CSS color standard.
- Fixed `lists.SinglyLinkedList` being broken after removing the last node ([#19353](https://github.com/nim-lang/Nim/pull/19353)).
- `macros.parseExpr` and `macros.parseStmt` now accept an optional
filename argument for more informative errors.

## `std/smtp`


## Language changes
Expand Down
9 changes: 4 additions & 5 deletions compiler/vm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1760,11 +1760,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 @@ -1776,10 +1775,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 @@ -1229,9 +1229,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 @@ -516,27 +516,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 a797a04

Please sign in to comment.