This commit is contained in:
Dominik Picheta
2017-02-01 21:11:40 +01:00
parent e8c46d29cd
commit 3cbfd56e1d
4 changed files with 41 additions and 19 deletions

View File

@@ -1585,12 +1585,21 @@ proc skipStmtList*(n: PNode): PNode =
result = n
proc toRef*(typ: PType): PType =
## If ``typ`` is a tyObject then it is converted into a `ref <typ>` and
## returned. Otherwise ``typ`` is simply returned as-is.
result = typ
if typ.kind == tyObject:
# Convert to a `ref T`.
result = newType(tyRef, typ.owner)
rawAddSon(result, typ)
proc toObject*(typ: PType): PType =
## If ``typ`` is a tyRef then its immediate son is returned (which in many
## cases should be a ``tyObject``).
## Otherwise ``typ`` is simply returned as-is.
result = typ
if result.kind == tyRef:
result = result.sons[0]
when false:
proc containsNil*(n: PNode): bool =
# only for debugging

View File

@@ -291,8 +291,16 @@ proc semTry(c: PContext, n: PNode): PNode =
symbolNode = a.sons[j].sons[2]
# Resolve the type ident into a PType.
var typ = semTypeNode(c, typeNode, nil)
if not symbolNode.isNil:
var typ = semTypeNode(c, typeNode, nil).toObject()
if typ.kind != tyObject:
localError(a.sons[j].info, errExprCannotBeRaised)
let newTypeNode = newNodeI(nkType, typeNode.info)
newTypeNode.typ = typ
if symbolNode.isNil:
a.sons[j] = newTypeNode
else:
a.sons[j].sons[1] = newTypeNode
# Add the exception ident to the symbol table.
let symbol = newSymG(skLet, symbolNode, c)
symbol.typ = typ.toRef()
@@ -302,18 +310,6 @@ proc semTry(c: PContext, n: PNode): PNode =
symNode.sym = symbol
a.sons[j].sons[2] = symNode
if typ.kind == tyRef: typ = typ.sons[0]
if typ.kind != tyObject:
localError(a.sons[j].info, errExprCannotBeRaised)
let newTypeNode = newNodeI(nkType, typeNode.info)
if symbolNode.isNil:
a.sons[j] = newTypeNode
a.sons[j].typ = typ
else:
a.sons[j].sons[1] = newTypeNode
a.sons[j].sons[1].typ = typ
if containsOrIncl(check, typ.id):
localError(a.sons[j].info, errExceptionAlreadyHandled)
elif a.kind != nkFinally:

View File

@@ -707,12 +707,14 @@ proc transformExceptBranch(c: PTransf, n: PNode): PTransNode =
let excTypeNode = n[0][1]
let actions = newTransNode(nkStmtList, n[1].info, 2)
# Generating `let exc = (excType)(getCurrentException())`
# -> getCurrentException()
let excCall = PTransNode(callCodegenProc("getCurrentException", ast.emptyNode))
# -> (excType)
let convNode = newTransNode(nkHiddenSubConv, n[1].info, 2)
convNode[0] = PTransNode(ast.emptyNode)
convNode[1] = excCall
PNode(convNode).typ = excTypeNode.typ.toRef()
# -> let exc = ...
let identDefs = newTransNode(nkIdentDefs, n[1].info, 3)
identDefs[0] = PTransNode(n[0][2])
identDefs[1] = PTransNode(ast.emptyNode)
@@ -720,15 +722,14 @@ proc transformExceptBranch(c: PTransf, n: PNode): PTransNode =
let letSection = newTransNode(nkLetSection, n[1].info, 1)
letSection[0] = identDefs
# Place the let statement and body of the 'except' branch into new stmtList.
actions[0] = letSection
actions[1] = transformSons(c, n[1])
# Overwrite 'except' branch body with our stmtList.
result[1] = actions
# Replace the `Exception as foobar` with just `Exception`.
result[0] = result[0][1]
#debug(PNode(result))
#echo(PNode(result))
proc dontInlineConstant(orig, cnst: PNode): bool {.inline.} =
# symbols that expand to a complex constant (array, etc.) should not be