mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-04 10:54:42 +00:00
fixes #1742
This commit is contained in:
@@ -798,7 +798,9 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
||||
startBlock(p)
|
||||
var finallyBlock = t.lastSon
|
||||
if finallyBlock.kind == nkFinally:
|
||||
expr(p, finallyBlock.sons[0], d)
|
||||
#expr(p, finallyBlock.sons[0], d)
|
||||
genStmts(p, finallyBlock.sons[0])
|
||||
|
||||
line(p, cpsStmts, ~"throw;$n")
|
||||
endBlock(p)
|
||||
|
||||
@@ -807,7 +809,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
||||
|
||||
discard pop(p.nestedTryStmts)
|
||||
if (i < length) and (t.sons[i].kind == nkFinally):
|
||||
exprBlock(p, t.sons[i].sons[0], d)
|
||||
genSimpleBlock(p, t.sons[i].sons[0])
|
||||
|
||||
proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
||||
# code to generate:
|
||||
@@ -899,7 +901,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
||||
endBlock(p) # end of else block
|
||||
if i < length and t.sons[i].kind == nkFinally:
|
||||
p.finallySafePoints.add(safePoint)
|
||||
exprBlock(p, t.sons[i].sons[0], d)
|
||||
genSimpleBlock(p, t.sons[i].sons[0])
|
||||
discard pop(p.finallySafePoints)
|
||||
linefmt(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", safePoint)
|
||||
|
||||
|
||||
@@ -601,15 +601,13 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||
if p.target == targetJS:
|
||||
app(p.body, "} finally {" & tnl & "excHandler = excHandler.prev;" & tnl)
|
||||
if i < length and n.sons[i].kind == nkFinally:
|
||||
gen(p, n.sons[i].sons[0], a)
|
||||
moveInto(p, a, r)
|
||||
genStmt(p, n.sons[i].sons[0])
|
||||
if p.target == targetJS:
|
||||
app(p.body, "}" & tnl)
|
||||
if p.target == targetLua:
|
||||
# we need to repeat the finally block for Lua ...
|
||||
if i < length and n.sons[i].kind == nkFinally:
|
||||
gen(p, n.sons[i].sons[0], a)
|
||||
moveInto(p, a, r)
|
||||
genStmt(p, n.sons[i].sons[0])
|
||||
|
||||
proc genRaiseStmt(p: PProc, n: PNode) =
|
||||
genLineDir(p, n)
|
||||
|
||||
@@ -505,7 +505,7 @@ proc parsePar(p: var TParser): PNode =
|
||||
getTok(p)
|
||||
optInd(p, result)
|
||||
if p.tok.tokType in {tkDiscard, tkInclude, tkIf, tkWhile, tkCase,
|
||||
tkTry, tkFinally, tkExcept, tkFor, tkBlock,
|
||||
tkTry, tkDefer, tkFinally, tkExcept, tkFor, tkBlock,
|
||||
tkConst, tkLet, tkWhen, tkVar,
|
||||
tkMixin}:
|
||||
# XXX 'bind' used to be an expression, so we exclude it here;
|
||||
|
||||
@@ -263,7 +263,8 @@ proc semTry(c: PContext, n: PNode): PNode =
|
||||
n.sons[0] = semExprBranchScope(c, n.sons[0])
|
||||
typ = commonType(typ, n.sons[0].typ)
|
||||
var check = initIntSet()
|
||||
for i in countup(1, sonsLen(n) - 1):
|
||||
var last = sonsLen(n) - 1
|
||||
for i in countup(1, last):
|
||||
var a = n.sons[i]
|
||||
checkMinSonsLen(a, 1)
|
||||
var length = sonsLen(a)
|
||||
@@ -282,11 +283,12 @@ proc semTry(c: PContext, n: PNode): PNode =
|
||||
a.sons[j].typ = typ
|
||||
if containsOrIncl(check, typ.id):
|
||||
localError(a.sons[j].info, errExceptionAlreadyHandled)
|
||||
elif a.kind != nkFinally:
|
||||
elif a.kind != nkFinally:
|
||||
illFormedAst(n)
|
||||
# last child of an nkExcept/nkFinally branch is a statement:
|
||||
a.sons[length-1] = semExprBranchScope(c, a.sons[length-1])
|
||||
typ = commonType(typ, a.sons[length-1].typ)
|
||||
if a.kind != nkFinally: typ = commonType(typ, a.sons[length-1].typ)
|
||||
else: dec last
|
||||
dec c.p.inTryStmt
|
||||
if isEmptyType(typ) or typ.kind == tyNil:
|
||||
discardCheck(c, n.sons[0])
|
||||
@@ -294,13 +296,14 @@ proc semTry(c: PContext, n: PNode): PNode =
|
||||
if typ == enforceVoidContext:
|
||||
result.typ = enforceVoidContext
|
||||
else:
|
||||
if n.lastSon.kind == nkFinally: discardCheck(c, n.lastSon.lastSon)
|
||||
n.sons[0] = fitNode(c, typ, n.sons[0])
|
||||
for i in 1..n.len-1:
|
||||
for i in 1..last:
|
||||
var it = n.sons[i]
|
||||
let j = it.len-1
|
||||
it.sons[j] = fitNode(c, typ, it.sons[j])
|
||||
result.typ = typ
|
||||
|
||||
|
||||
proc fitRemoveHiddenConv(c: PContext, typ: PType, n: PNode): PNode =
|
||||
result = fitNode(c, typ, n)
|
||||
if result.kind in {nkHiddenStdConv, nkHiddenSubConv}:
|
||||
@@ -1251,6 +1254,7 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
tryStmt.addSon(deferPart)
|
||||
n.sons[i] = semTry(c, tryStmt)
|
||||
n.sons.setLen(i+1)
|
||||
n.typ = n.sons[i].typ
|
||||
return
|
||||
else:
|
||||
n.sons[i] = semExpr(c, n.sons[i])
|
||||
|
||||
@@ -463,7 +463,7 @@ proc genTry(c: PCtx; n: PNode; dest: var TDest) =
|
||||
# from the stack
|
||||
c.gABx(fin, opcFinally, 0, 0)
|
||||
if fin.kind == nkFinally:
|
||||
c.gen(fin.sons[0], dest)
|
||||
c.gen(fin.sons[0])
|
||||
c.clearDest(n, dest)
|
||||
c.gABx(fin, opcFinallyEnd, 0, 0)
|
||||
|
||||
|
||||
@@ -47,6 +47,27 @@ the rest of the procedure - that is not within a ``finally`` clause -
|
||||
is not executed (if an exception occurs).
|
||||
|
||||
|
||||
Try expression
|
||||
--------------
|
||||
|
||||
Try can also be used as an expression; the type of the ``try`` branch then
|
||||
needs to fit the types of ``except`` branches, but the type of the ``finally``
|
||||
branch always has to be ``void``:
|
||||
|
||||
.. code-block:: nim
|
||||
let x = try: parseInt("133a")
|
||||
except: -1
|
||||
finally: echo "hi"
|
||||
|
||||
|
||||
To prevent confusing code there is a parsing limitation; if the ``try``
|
||||
follows a ``(`` it has to be written as a one liner:
|
||||
|
||||
.. code-block:: nim
|
||||
let x = (try: parseInt("133a") except: -1)
|
||||
|
||||
|
||||
|
||||
Defer statement
|
||||
---------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user