diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ast.nim | 3 | ||||
-rw-r--r-- | compiler/lexer.nim | 6 | ||||
-rw-r--r-- | compiler/parser.nim | 10 | ||||
-rw-r--r-- | compiler/semstmts.nim | 21 | ||||
-rw-r--r-- | compiler/wordrecg.nim | 4 |
5 files changed, 31 insertions, 13 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 62f2d105f..1d2b63181 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -160,6 +160,7 @@ type nkConstDef, # a const definition nkTypeDef, # a type definition nkYieldStmt, # the yield statement as a tree + nkDefer, # the 'defer' statement nkTryStmt, # a try statement nkFinally, # a finally section nkRaiseStmt, # a raise statement @@ -566,7 +567,7 @@ type mBool, mChar, mString, mCstring, mPointer, mEmptySet, mIntSetBaseType, mNil, mExpr, mStmt, mTypeDesc, mVoidType, mPNimrodNode, mShared, mGuarded, mLock, mSpawn, mDeepCopy, - mIsMainModule, mCompileDate, mCompileTime, mProcCall, + mIsMainModule, mCompileDate, mCompileTime, mProcCall, mCpuEndian, mHostOS, mHostCPU, mAppType, mNaN, mInf, mNegInf, mCompileOption, mCompileOptionArg, diff --git a/compiler/lexer.nim b/compiler/lexer.nim index dbeec8acf..fb74f27d6 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -35,7 +35,8 @@ type tkSymbol, # keywords: tkAddr, tkAnd, tkAs, tkAsm, tkAtomic, tkBind, tkBlock, tkBreak, tkCase, tkCast, - tkConst, tkContinue, tkConverter, tkDiscard, tkDistinct, tkDiv, tkDo, + tkConst, tkContinue, tkConverter, + tkDefer, tkDiscard, tkDistinct, tkDiv, tkDo, tkElif, tkElse, tkEnd, tkEnum, tkExcept, tkExport, tkFinally, tkFor, tkFrom, tkGeneric, tkIf, tkImport, tkIn, tkInclude, tkInterface, @@ -71,7 +72,8 @@ const "tkSymbol", "addr", "and", "as", "asm", "atomic", "bind", "block", "break", "case", "cast", - "const", "continue", "converter", "discard", "distinct", "div", "do", + "const", "continue", "converter", + "defer", "discard", "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export", "finally", "for", "from", "generic", "if", "import", "in", "include", "interface", "is", "isnot", "iterator", diff --git a/compiler/parser.nim b/compiler/parser.nim index e4de75a07..b5a9559d9 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -1423,9 +1423,10 @@ proc parseBlock(p: var TParser): PNode = colcom(p, result) addSon(result, parseStmt(p)) -proc parseStatic(p: var TParser): PNode = +proc parseStaticOrDefer(p: var TParser; k: TNodeKind): PNode = #| staticStmt = 'static' colcom stmt - result = newNodeP(nkStaticStmt, p) + #| deferStmt = 'defer' colcom stmt + result = newNodeP(k, p) getTokNoInd(p) colcom(p, result) addSon(result, parseStmt(p)) @@ -1863,7 +1864,7 @@ proc simpleStmt(p: var TParser): PNode = proc complexOrSimpleStmt(p: var TParser): PNode = #| complexOrSimpleStmt = (ifStmt | whenStmt | whileStmt #| | tryStmt | finallyStmt | exceptStmt | forStmt - #| | blockStmt | staticStmt | asmStmt + #| | blockStmt | staticStmt | deferStmt | asmStmt #| | 'proc' routine #| | 'method' routine #| | 'iterator' routine @@ -1884,7 +1885,8 @@ proc complexOrSimpleStmt(p: var TParser): PNode = of tkExcept: result = parseExceptBlock(p, nkExceptBranch) of tkFor: result = parseFor(p) of tkBlock: result = parseBlock(p) - of tkStatic: result = parseStatic(p) + of tkStatic: result = parseStaticOrDefer(p, nkStaticStmt) + of tkDefer: result = parseStaticOrDefer(p, nkDefer) of tkAsm: result = parseAsm(p) of tkProc: result = parseRoutine(p, nkProcDef) of tkMethod: result = parseRoutine(p, nkMethodDef) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index c6906d98e..933ac7daf 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1362,8 +1362,9 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = # nkNilLit, nkEmpty}: # dec last for i in countup(0, length - 1): - case n.sons[i].kind - of nkFinally, nkExceptBranch: + let k = n.sons[i].kind + case k + of nkFinally, nkExceptBranch, nkDefer: # stand-alone finally and except blocks are # transformed into regular try blocks: # @@ -1372,12 +1373,24 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = # ... | ... # | finally: # | fclose(f) + var deferPart: PNode + if k == nkDefer: + deferPart = newNodeI(nkFinally, n.sons[i].info) + deferPart.add n.sons[i].sons[0] + elif k == nkFinally: + message(n.info, warnDeprecated, + "use 'defer'; standalone 'finally'") + deferPart = n.sons[i] + else: + message(n.info, warnDeprecated, + "use an explicit 'try'; standalone 'except'") + deferPart = n.sons[i] 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]) + tryStmt.addSon(deferPart) n.sons[i] = semTry(c, tryStmt) n.sons.setLen(i+1) return @@ -1424,7 +1437,7 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = # a statement list (s; e) has the type 'e': if result.kind == nkStmtList and result.len > 0: var lastStmt = lastSon(result) - if lastStmt.kind != nkNilLit and not ImplicitlyDiscardable(lastStmt): + if lastStmt.kind != nkNilLit and not implicitlyDiscardable(lastStmt): result.typ = lastStmt.typ #localError(lastStmt.info, errGenerated, # "Last expression must be explicitly returned if it " & diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index 068f59c71..45206e7e7 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -24,7 +24,7 @@ type wAddr, wAnd, wAs, wAsm, wAtomic, wBind, wBlock, wBreak, wCase, wCast, wConst, - wContinue, wConverter, wDiscard, wDistinct, wDiv, wDo, + wContinue, wConverter, wDefer, wDiscard, wDistinct, wDiv, wDo, wElif, wElse, wEnd, wEnum, wExcept, wExport, wFinally, wFor, wFrom, wGeneric, wIf, wImport, wIn, wInclude, wInterface, wIs, wIsnot, wIterator, wLet, @@ -103,7 +103,7 @@ const "addr", "and", "as", "asm", "atomic", "bind", "block", "break", "case", "cast", "const", "continue", "converter", - "discard", "distinct", "div", "do", + "defer", "discard", "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export", "finally", "for", "from", "generic", "if", "import", "in", "include", "interface", "is", "isnot", "iterator", |