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
parent 1a407402a4
commit cfff27529e
6 changed files with 90 additions and 3 deletions

View File

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

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)
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 & ')')

View File

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

View File

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

View File

@@ -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('/'))