diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2021-03-29 16:23:19 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-29 16:23:19 +0200 |
commit | cfff27529e4ec129daad602d945a2b222145e922 (patch) | |
tree | bfbdcd036d07c282865531e1ede7864263e9ba12 | |
parent | 1a407402a4614fc9100617f71c2d3c9b8a8367a5 (diff) | |
download | Nim-cfff27529e4ec129daad602d945a2b222145e922.tar.gz |
added nkError to the AST (#17567)
* added nkError to the AST * Update lib/core/macros.nim Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com> * Update compiler/ast.nim Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com> Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com>
-rw-r--r-- | compiler/ast.nim | 1 | ||||
-rw-r--r-- | compiler/errorhandling.nim | 79 | ||||
-rw-r--r-- | compiler/renderer.nim | 4 | ||||
-rw-r--r-- | compiler/sempass2.nim | 4 | ||||
-rw-r--r-- | lib/core/macros.nim | 3 | ||||
-rw-r--r-- | tests/misc/tinvalidnewseq.nim | 2 |
6 files changed, 90 insertions, 3 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 1f3d5f129..7d13956e9 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -221,6 +221,7 @@ type nkBreakState, # special break statement for easier code generation nkFuncDef, # a func nkTupleConstr # a tuple constructor + nkError # erroneous AST node nkModuleRef # for .rod file support: A (moduleId, itemId) pair nkReplayAction # for .rod file support: A replay action nkNilRodNode # for .rod file support: a 'nil' PNode diff --git a/compiler/errorhandling.nim b/compiler/errorhandling.nim new file mode 100644 index 000000000..d7092d477 --- /dev/null +++ b/compiler/errorhandling.nim @@ -0,0 +1,79 @@ +# +# +# The Nim Compiler +# (c) Copyright 2021 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module contains support code for new-styled error +## handling via an `nkError` node kind. + +import ast, renderer, options, lineinfos, strutils, types + +type + ErrorKind* = enum ## expand as you need. + RawTypeMismatchError + ExpressionCannotBeCalled + CustomError + WrongNumberOfArguments + AmbiguousCall + +proc errorSubNode*(n: PNode): PNode = + case n.kind + of nkEmpty..nkNilLit: + result = nil + of nkError: + result = n + else: + result = nil + for i in 0..<n.len: + result = errorSubNode(n[i]) + if result != nil: break + +proc newError*(wrongNode: PNode; k: ErrorKind; args: varargs[PNode]): PNode = + assert wrongNode.kind != nkError + let innerError = errorSubNode(wrongNode) + if innerError != nil: + return innerError + result = newNodeIT(nkError, wrongNode.info, newType(tyError, ItemId(module: -1, item: -1), nil)) + result.add wrongNode + result.add newIntNode(nkIntLit, ord(k)) + for a in args: result.add a + +proc newError*(wrongNode: PNode; msg: string): PNode = + assert wrongNode.kind != nkError + let innerError = errorSubNode(wrongNode) + if innerError != nil: + return innerError + result = newNodeIT(nkError, wrongNode.info, newType(tyError, ItemId(module: -1, item: -1), nil)) + result.add wrongNode + result.add newIntNode(nkIntLit, ord(CustomError)) + result.add newStrNode(msg, wrongNode.info) + +proc errorToString*(config: ConfigRef; n: PNode): string = + assert n.kind == nkError + assert n.len > 1 + let wrongNode = n[0] + case ErrorKind(n[1].intVal) + of RawTypeMismatchError: + result = "type mismatch" + of ExpressionCannotBeCalled: + result = "expression '$1' cannot be called" % wrongNode[0].renderTree + of CustomError: + result = n[2].strVal + of WrongNumberOfArguments: + result = "wrong number of arguments" + of AmbiguousCall: + let a = n[2].sym + let b = n[3].sym + var args = "(" + for i in 1..<wrongNode.len: + if i > 1: args.add(", ") + args.add(typeToString(wrongNode[i].typ)) + args.add(")") + result = "ambiguous call; both $1 and $2 match for: $3" % [ + getProcHeader(config, a), + getProcHeader(config, b), + args] diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 9ca485f6e..9a599f6fc 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -1645,6 +1645,10 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = gsons(g, n, c, 0) of nkTypeClassTy: gTypeClassTy(g, n) + of nkError: + putWithSpace(g, tkSymbol, "error") + #gcomma(g, n, c) + gsub(g, n[0], c) else: #nkNone, nkExplicitTypeListCall: internalError(g.config, n.info, "rnimsyn.gsub(" & $n.kind & ')') diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index f269afe4c..a1572c85e 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -10,7 +10,7 @@ import intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees, wordrecg, strutils, options, guards, lineinfos, semfold, semdata, - modulegraphs, varpartitions, typeallowed, nilcheck + modulegraphs, varpartitions, typeallowed, nilcheck, errorhandling when defined(useDfa): import dfa @@ -1136,6 +1136,8 @@ proc track(tracked: PEffects, n: PNode) = dec tracked.leftPartOfAsgn for i in 1 ..< n.len: track(tracked, n[i]) inc tracked.leftPartOfAsgn + of nkError: + localError(tracked.config, n.info, errorToString(tracked.config, n)) else: for i in 0..<n.safeLen: track(tracked, n[i]) diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 8d6258e80..795909c6b 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -85,7 +85,8 @@ type nnkState, nnkBreakState, nnkFuncDef, - nnkTupleConstr + nnkTupleConstr, + nnkError, ## erroneous AST node NimNodeKinds* = set[NimNodeKind] NimTypeKind* = enum # some types are no longer used, see ast.nim diff --git a/tests/misc/tinvalidnewseq.nim b/tests/misc/tinvalidnewseq.nim index dec00fd4a..7a95db020 100644 --- a/tests/misc/tinvalidnewseq.nim +++ b/tests/misc/tinvalidnewseq.nim @@ -13,7 +13,7 @@ proc parseURL(url: string): TURL = var pattern: string = r"([a-zA-Z]+://)?(\w+?\.)?(\w+)(\.\w+)(:[0-9]+)?(/.+)?" var m: array[0..6, string] #Array with the matches newSeq(m, 7) #ERROR - discard regexprs.match(url, re(pattern), m) + discard re.match(url, re(pattern), m) result = (protocol: m[1], subdomain: m[2], domain: m[3] & m[4], port: m[5], path: m[6].split('/')) |