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>
This commit is contained in:
Andreas Rumpf 2021-03-29 16:23:19 +02:00 • committed by GitHub
commit cfff27529e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 90 additions and 3 deletions

View file

@ -221,6 +221,7 @@ type
nkBreakState, # special break statement for easier code generation nkBreakState, # special break statement for easier code generation
nkFuncDef, # a func nkFuncDef, # a func
nkTupleConstr # a tuple constructor nkTupleConstr # a tuple constructor
nkError # erroneous AST node
nkModuleRef # for .rod file support: A (moduleId, itemId) pair nkModuleRef # for .rod file support: A (moduleId, itemId) pair
nkReplayAction # for .rod file support: A replay action nkReplayAction # for .rod file support: A replay action
nkNilRodNode # for .rod file support: a 'nil' PNode nkNilRodNode # for .rod file support: a 'nil' PNode

View file

@ -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]

View file

@ -1645,6 +1645,10 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
gsons(g, n, c, 0) gsons(g, n, c, 0)
of nkTypeClassTy: of nkTypeClassTy:
gTypeClassTy(g, n) gTypeClassTy(g, n)
of nkError:
putWithSpace(g, tkSymbol, "error")
#gcomma(g, n, c)
gsub(g, n[0], c)
else: else:
#nkNone, nkExplicitTypeListCall: #nkNone, nkExplicitTypeListCall:
internalError(g.config, n.info, "rnimsyn.gsub(" & $n.kind & ')') internalError(g.config, n.info, "rnimsyn.gsub(" & $n.kind & ')')

View file

@ -10,7 +10,7 @@
import import
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees, intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
wordrecg, strutils, options, guards, lineinfos, semfold, semdata, wordrecg, strutils, options, guards, lineinfos, semfold, semdata,
modulegraphs, varpartitions, typeallowed, nilcheck modulegraphs, varpartitions, typeallowed, nilcheck, errorhandling
when defined(useDfa): when defined(useDfa):
import dfa import dfa
@ -1136,6 +1136,8 @@ proc track(tracked: PEffects, n: PNode) =
dec tracked.leftPartOfAsgn dec tracked.leftPartOfAsgn
for i in 1 ..< n.len: track(tracked, n[i]) for i in 1 ..< n.len: track(tracked, n[i])
inc tracked.leftPartOfAsgn inc tracked.leftPartOfAsgn
of nkError:
localError(tracked.config, n.info, errorToString(tracked.config, n))
else: else:
for i in 0..<n.safeLen: track(tracked, n[i]) for i in 0..<n.safeLen: track(tracked, n[i])

View file

@ -85,7 +85,8 @@ type
nnkState, nnkState,
nnkBreakState, nnkBreakState,
nnkFuncDef, nnkFuncDef,
nnkTupleConstr nnkTupleConstr,
nnkError, ## erroneous AST node
NimNodeKinds* = set[NimNodeKind] NimNodeKinds* = set[NimNodeKind]
NimTypeKind* = enum # some types are no longer used, see ast.nim NimTypeKind* = enum # some types are no longer used, see ast.nim

View file

@ -13,7 +13,7 @@ proc parseURL(url: string): TURL =
var pattern: string = r"([a-zA-Z]+://)?(\w+?\.)?(\w+)(\.\w+)(:[0-9]+)?(/.+)?" var pattern: string = r"([a-zA-Z]+://)?(\w+?\.)?(\w+)(\.\w+)(:[0-9]+)?(/.+)?"
var m: array[0..6, string] #Array with the matches var m: array[0..6, string] #Array with the matches
newSeq(m, 7) #ERROR 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], result = (protocol: m[1], subdomain: m[2], domain: m[3] & m[4],
port: m[5], path: m[6].split('/')) port: m[5], path: m[6].split('/'))