diff --git a/changelog.md b/changelog.md index fbda7058288b..3f75fb17f968 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,16 @@ ## Standard library additions and changes +## Standard library additions and changes + +- `macros.parseExpr` and `macros.parseStmt` now accept an optional + 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 diff --git a/compiler/vm.nim b/compiler/vm.nim index 5e105e1ce91d..ecdb7f49c9a2 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1758,11 +1758,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)) @@ -1774,10 +1773,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 bb095d3eedef..9a823dff4374 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 806ea7e31348..8b4ea22c54e4 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -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) diff --git a/tests/macros/mparsefile.nim b/tests/macros/mparsefile.nim new file mode 100644 index 000000000000..8ac99d5685ee --- /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 000000000000..a41223f803c9 --- /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