implements 'defer'

This commit is contained in:
Araq 2014-12-04 10:12:32 +01:00
commit e27ab36731
12 changed files with 45 additions and 20 deletions

View file

@ -160,6 +160,7 @@ type
nkConstDef, # a const definition nkConstDef, # a const definition
nkTypeDef, # a type definition nkTypeDef, # a type definition
nkYieldStmt, # the yield statement as a tree nkYieldStmt, # the yield statement as a tree
nkDefer, # the 'defer' statement
nkTryStmt, # a try statement nkTryStmt, # a try statement
nkFinally, # a finally section nkFinally, # a finally section
nkRaiseStmt, # a raise statement nkRaiseStmt, # a raise statement

View file

@ -35,7 +35,8 @@ type
tkSymbol, # keywords: tkSymbol, # keywords:
tkAddr, tkAnd, tkAs, tkAsm, tkAtomic, tkAddr, tkAnd, tkAs, tkAsm, tkAtomic,
tkBind, tkBlock, tkBreak, tkCase, tkCast, 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, tkElif, tkElse, tkEnd, tkEnum, tkExcept, tkExport,
tkFinally, tkFor, tkFrom, tkFinally, tkFor, tkFrom,
tkGeneric, tkIf, tkImport, tkIn, tkInclude, tkInterface, tkGeneric, tkIf, tkImport, tkIn, tkInclude, tkInterface,
@ -71,7 +72,8 @@ const
"tkSymbol", "tkSymbol",
"addr", "and", "as", "asm", "atomic", "addr", "and", "as", "asm", "atomic",
"bind", "block", "break", "case", "cast", "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", "elif", "else", "end", "enum", "except", "export",
"finally", "for", "from", "generic", "if", "finally", "for", "from", "generic", "if",
"import", "in", "include", "interface", "is", "isnot", "iterator", "import", "in", "include", "interface", "is", "isnot", "iterator",

View file

@ -1423,9 +1423,10 @@ proc parseBlock(p: var TParser): PNode =
colcom(p, result) colcom(p, result)
addSon(result, parseStmt(p)) addSon(result, parseStmt(p))
proc parseStatic(p: var TParser): PNode = proc parseStaticOrDefer(p: var TParser; k: TNodeKind): PNode =
#| staticStmt = 'static' colcom stmt #| staticStmt = 'static' colcom stmt
result = newNodeP(nkStaticStmt, p) #| deferStmt = 'defer' colcom stmt
result = newNodeP(k, p)
getTokNoInd(p) getTokNoInd(p)
colcom(p, result) colcom(p, result)
addSon(result, parseStmt(p)) addSon(result, parseStmt(p))
@ -1863,7 +1864,7 @@ proc simpleStmt(p: var TParser): PNode =
proc complexOrSimpleStmt(p: var TParser): PNode = proc complexOrSimpleStmt(p: var TParser): PNode =
#| complexOrSimpleStmt = (ifStmt | whenStmt | whileStmt #| complexOrSimpleStmt = (ifStmt | whenStmt | whileStmt
#| | tryStmt | finallyStmt | exceptStmt | forStmt #| | tryStmt | finallyStmt | exceptStmt | forStmt
#| | blockStmt | staticStmt | asmStmt #| | blockStmt | staticStmt | deferStmt | asmStmt
#| | 'proc' routine #| | 'proc' routine
#| | 'method' routine #| | 'method' routine
#| | 'iterator' routine #| | 'iterator' routine
@ -1884,7 +1885,8 @@ proc complexOrSimpleStmt(p: var TParser): PNode =
of tkExcept: result = parseExceptBlock(p, nkExceptBranch) of tkExcept: result = parseExceptBlock(p, nkExceptBranch)
of tkFor: result = parseFor(p) of tkFor: result = parseFor(p)
of tkBlock: result = parseBlock(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 tkAsm: result = parseAsm(p)
of tkProc: result = parseRoutine(p, nkProcDef) of tkProc: result = parseRoutine(p, nkProcDef)
of tkMethod: result = parseRoutine(p, nkMethodDef) of tkMethod: result = parseRoutine(p, nkMethodDef)

View file

@ -1362,8 +1362,9 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
# nkNilLit, nkEmpty}: # nkNilLit, nkEmpty}:
# dec last # dec last
for i in countup(0, length - 1): for i in countup(0, length - 1):
case n.sons[i].kind let k = n.sons[i].kind
of nkFinally, nkExceptBranch: case k
of nkFinally, nkExceptBranch, nkDefer:
# stand-alone finally and except blocks are # stand-alone finally and except blocks are
# transformed into regular try blocks: # transformed into regular try blocks:
# #
@ -1372,12 +1373,24 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
# ... | ... # ... | ...
# | finally: # | finally:
# | fclose(f) # | 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 tryStmt = newNodeI(nkTryStmt, n.sons[i].info)
var body = newNodeI(nkStmtList, n.sons[i].info) var body = newNodeI(nkStmtList, n.sons[i].info)
if i < n.sonsLen - 1: if i < n.sonsLen - 1:
body.sons = n.sons[(i+1)..(-1)] body.sons = n.sons[(i+1)..(-1)]
tryStmt.addSon(body) tryStmt.addSon(body)
tryStmt.addSon(n.sons[i]) tryStmt.addSon(deferPart)
n.sons[i] = semTry(c, tryStmt) n.sons[i] = semTry(c, tryStmt)
n.sons.setLen(i+1) n.sons.setLen(i+1)
return return
@ -1424,7 +1437,7 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
# a statement list (s; e) has the type 'e': # a statement list (s; e) has the type 'e':
if result.kind == nkStmtList and result.len > 0: if result.kind == nkStmtList and result.len > 0:
var lastStmt = lastSon(result) var lastStmt = lastSon(result)
if lastStmt.kind != nkNilLit and not ImplicitlyDiscardable(lastStmt): if lastStmt.kind != nkNilLit and not implicitlyDiscardable(lastStmt):
result.typ = lastStmt.typ result.typ = lastStmt.typ
#localError(lastStmt.info, errGenerated, #localError(lastStmt.info, errGenerated,
# "Last expression must be explicitly returned if it " & # "Last expression must be explicitly returned if it " &

View file

@ -24,7 +24,7 @@ type
wAddr, wAnd, wAs, wAsm, wAtomic, wAddr, wAnd, wAs, wAsm, wAtomic,
wBind, wBlock, wBreak, wCase, wCast, wConst, 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, wElif, wElse, wEnd, wEnum, wExcept, wExport,
wFinally, wFor, wFrom, wGeneric, wIf, wImport, wIn, wFinally, wFor, wFrom, wGeneric, wIf, wImport, wIn,
wInclude, wInterface, wIs, wIsnot, wIterator, wLet, wInclude, wInterface, wIs, wIsnot, wIterator, wLet,
@ -103,7 +103,7 @@ const
"addr", "and", "as", "asm", "atomic", "addr", "and", "as", "asm", "atomic",
"bind", "block", "break", "case", "cast", "bind", "block", "break", "case", "cast",
"const", "continue", "converter", "const", "continue", "converter",
"discard", "distinct", "div", "do", "defer", "discard", "distinct", "div", "do",
"elif", "else", "end", "enum", "except", "export", "elif", "else", "end", "enum", "except", "export",
"finally", "for", "from", "generic", "if", "finally", "for", "from", "generic", "if",
"import", "in", "include", "interface", "is", "isnot", "iterator", "import", "in", "include", "interface", "is", "isnot", "iterator",

View file

@ -47,7 +47,8 @@ Realtime support
================ ================
To enable realtime support, the symbol `useRealtimeGC`:idx: needs to be To enable realtime support, the symbol `useRealtimeGC`:idx: needs to be
defined. With this switch the GC supports the following operations: defined via ``--define:useRealtimeGC`` (you can put this into your config
file as well). With this switch the GC supports the following operations:
.. code-block:: nim .. code-block:: nim
proc GC_setMaxPause*(MaxPauseInUs: int) proc GC_setMaxPause*(MaxPauseInUs: int)

View file

@ -142,6 +142,7 @@ exceptBlock = 'except' colcom stmt
forStmt = 'for' (identWithPragma ^+ comma) 'in' expr colcom stmt forStmt = 'for' (identWithPragma ^+ comma) 'in' expr colcom stmt
blockStmt = 'block' symbol? colcom stmt blockStmt = 'block' symbol? colcom stmt
staticStmt = 'static' colcom stmt staticStmt = 'static' colcom stmt
deferStmt = 'defer' colcom stmt
asmStmt = 'asm' pragma? (STR_LIT | RSTR_LIT | TRIPLE_STR_LIT) asmStmt = 'asm' pragma? (STR_LIT | RSTR_LIT | TRIPLE_STR_LIT)
genericParam = symbol (comma symbol)* (colon expr)? ('=' optInd expr)? genericParam = symbol (comma symbol)* (colon expr)? ('=' optInd expr)?
genericParamList = '[' optInd genericParamList = '[' optInd
@ -182,7 +183,7 @@ simpleStmt = ((returnStmt | raiseStmt | yieldStmt | discardStmt | breakStmt
| includeStmt | commentStmt) / exprStmt) COMMENT? | includeStmt | commentStmt) / exprStmt) COMMENT?
complexOrSimpleStmt = (ifStmt | whenStmt | whileStmt complexOrSimpleStmt = (ifStmt | whenStmt | whileStmt
| tryStmt | finallyStmt | exceptStmt | forStmt | tryStmt | finallyStmt | exceptStmt | forStmt
| blockStmt | staticStmt | asmStmt | blockStmt | staticStmt | deferStmt | asmStmt
| 'proc' routine | 'proc' routine
| 'method' routine | 'method' routine
| 'iterator' routine | 'iterator' routine

View file

@ -1,7 +1,7 @@
addr and as asm atomic addr and as asm atomic
bind block break bind block break
case cast const continue converter case cast const continue converter
discard distinct div do defer discard distinct div do
elif else end enum except export elif else end enum except export
finally for from finally for from
generic generic

View file

@ -46,7 +46,7 @@ type
nnkForStmt, nnkParForStmt, nnkWhileStmt, nnkCaseStmt, nnkForStmt, nnkParForStmt, nnkWhileStmt, nnkCaseStmt,
nnkTypeSection, nnkVarSection, nnkLetSection, nnkConstSection, nnkTypeSection, nnkVarSection, nnkLetSection, nnkConstSection,
nnkConstDef, nnkTypeDef, nnkConstDef, nnkTypeDef,
nnkYieldStmt, nnkTryStmt, nnkFinally, nnkRaiseStmt, nnkYieldStmt, nnkDefer, nnkTryStmt, nnkFinally, nnkRaiseStmt,
nnkReturnStmt, nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, nnkStaticStmt, nnkReturnStmt, nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, nnkStaticStmt,
nnkDiscardStmt, nnkStmtList, nnkDiscardStmt, nnkStmtList,
nnkImportStmt, nnkImportStmt,

View file

@ -47,8 +47,9 @@ const
# The following list comes from doc/keywords.txt, make sure it is # The following list comes from doc/keywords.txt, make sure it is
# synchronized with this array by running the module itself as a test case. # synchronized with this array by running the module itself as a test case.
nimKeywords = ["addr", "and", "as", "asm", "atomic", "bind", "block", nimKeywords = ["addr", "and", "as", "asm", "atomic", "bind", "block",
"break", "case", "cast", "const", "continue", "converter", "discard", "break", "case", "cast", "const", "continue", "converter",
"distinct", "div", "do", "elif", "else", "end", "enum", "except", "export", "defer", "discard", "distinct", "div", "do",
"elif", "else", "end", "enum", "except", "export",
"finally", "for", "from", "generic", "if", "import", "in", "include", "finally", "for", "from", "generic", "if", "import", "in", "include",
"interface", "is", "isnot", "iterator", "let", "macro", "method", "interface", "is", "isnot", "iterator", "let", "macro", "method",
"mixin", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc", "mixin", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc",

View file

@ -1,12 +1,16 @@
version 0.10 version 0.10
============ ============
Repetition renders the ridiculous reasonable.
- introduce ``--experimental`` switch - introduce ``--experimental`` switch
- c2nim depends on the compiler
- make nimble part of the distribution - make nimble part of the distribution
- split idetools into separate tool - split idetools into separate tool
- split docgen into separate tool - split docgen into separate tool
Concurrency Concurrency
----------- -----------
@ -33,7 +37,6 @@ Misc
Bugs Bugs
==== ====
- fix the bug that keeps 'defer' template from working
- VM: Pegs do not work at compile-time - VM: Pegs do not work at compile-time
- VM: ptr/ref T cannot work in general - VM: ptr/ref T cannot work in general
- scopes are still broken for generic instantiation! - scopes are still broken for generic instantiation!

View file

@ -28,6 +28,7 @@ News
fails to match. fails to match.
- The "symmetric set difference" operator (``-+-``) never worked and has been - The "symmetric set difference" operator (``-+-``) never worked and has been
removed. removed.
- ``defer`` is a keyword now.
Language Additions Language Additions
------------------ ------------------