implements 'defer'
This commit is contained in:
parent
85d83fd8cb
commit
e27ab36731
12 changed files with 45 additions and 20 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 " &
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
5
todo.txt
5
todo.txt
|
|
@ -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!
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
------------------
|
------------------
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue