diff options
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/parser.nim | 11 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 34 |
2 files changed, 37 insertions, 8 deletions
diff --git a/compiler/parser.nim b/compiler/parser.nim index 78e39bcd2..13aaec41b 100755 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -998,7 +998,14 @@ proc parseTry(p: var TParser): PNode = addSon(result, b) if b.kind == nkFinally: break if b == nil: parMessage(p, errTokenExpected, "except") - + +proc parseExceptBlock(p: var TParser, kind: TNodeKind): PNode = + result = newNodeP(kind, p) + getTok(p) + eat(p, tkColon) + skipComment(p, result) + addSon(result, parseStmt(p)) + proc parseFor(p: var TParser): PNode = result = newNodeP(nkForStmt, p) getTok(p) @@ -1393,6 +1400,8 @@ proc complexOrSimpleStmt(p: var TParser): PNode = of tkWhile: result = parseWhile(p) of tkCase: result = parseCase(p) of tkTry: result = parseTry(p) + of tkFinally: result = parseExceptBlock(p, nkFinally) + of tkExcept: result = parseExceptBlock(p, nkExceptBranch) of tkFor: result = parseFor(p) of tkBlock: result = parseBlock(p) of tkStatic: result = parseStatic(p) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 6b79326fe..9c5efaf2d 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -871,13 +871,33 @@ proc SemStmt(c: PContext, n: PNode): PNode = of nkBlockStmt: result = semBlock(c, n) of nkStmtList: var length = sonsLen(n) - for i in countup(0, length - 1): - n.sons[i] = semStmt(c, n.sons[i]) - if n.sons[i].kind in LastBlockStmts: - for j in countup(i + 1, length - 1): - case n.sons[j].kind - of nkPragma, nkCommentStmt, nkNilLit, nkEmpty: nil - else: localError(n.sons[j].info, errStmtInvalidAfterReturn) + for i in countup(0, length - 1): + case n.sons[i].kind + of nkFinally, nkExceptBranch: + # stand-alone finally and except blocks are + # transformed into regular try blocks: + # + # var f = fopen("somefile") | var f = fopen("somefile") + # finally: fcsole(f) | try: + # ... | ... + # | finally: + # | fclose(f) + var tryStmt = newNodeI(nkTryStmt, n.sons[i].info) + var body = newNodeI(nkStmtList, n.sons[i].info) + if i < n.sonsLen - 1: + body.sons = n.sons[(i+1)..(-1)] + tryStmt.addSon(body) + tryStmt.addSon(n.sons[i]) + n.sons[i] = semTry(c, tryStmt) + n.sons.setLen(i+1) + return + else: + n.sons[i] = semStmt(c, n.sons[i]) + if n.sons[i].kind in LastBlockStmts: + for j in countup(i + 1, length - 1): + case n.sons[j].kind + of nkPragma, nkCommentStmt, nkNilLit, nkEmpty: nil + else: localError(n.sons[j].info, errStmtInvalidAfterReturn) of nkRaiseStmt: result = semRaise(c, n) of nkVarSection: result = semVarOrLet(c, n, skVar) of nkLetSection: result = semVarOrLet(c, n, skLet) |