mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-06 20:04:18 +00:00
implements 'defer'
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 " &
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -47,7 +47,8 @@ Realtime support
|
||||
================
|
||||
|
||||
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
|
||||
proc GC_setMaxPause*(MaxPauseInUs: int)
|
||||
|
||||
@@ -142,6 +142,7 @@ exceptBlock = 'except' colcom stmt
|
||||
forStmt = 'for' (identWithPragma ^+ comma) 'in' expr colcom stmt
|
||||
blockStmt = 'block' symbol? colcom stmt
|
||||
staticStmt = 'static' colcom stmt
|
||||
deferStmt = 'defer' colcom stmt
|
||||
asmStmt = 'asm' pragma? (STR_LIT | RSTR_LIT | TRIPLE_STR_LIT)
|
||||
genericParam = symbol (comma symbol)* (colon expr)? ('=' optInd expr)?
|
||||
genericParamList = '[' optInd
|
||||
@@ -182,7 +183,7 @@ simpleStmt = ((returnStmt | raiseStmt | yieldStmt | discardStmt | breakStmt
|
||||
| includeStmt | commentStmt) / exprStmt) COMMENT?
|
||||
complexOrSimpleStmt = (ifStmt | whenStmt | whileStmt
|
||||
| tryStmt | finallyStmt | exceptStmt | forStmt
|
||||
| blockStmt | staticStmt | asmStmt
|
||||
| blockStmt | staticStmt | deferStmt | asmStmt
|
||||
| 'proc' routine
|
||||
| 'method' routine
|
||||
| 'iterator' routine
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
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
|
||||
|
||||
@@ -46,7 +46,7 @@ type
|
||||
nnkForStmt, nnkParForStmt, nnkWhileStmt, nnkCaseStmt,
|
||||
nnkTypeSection, nnkVarSection, nnkLetSection, nnkConstSection,
|
||||
nnkConstDef, nnkTypeDef,
|
||||
nnkYieldStmt, nnkTryStmt, nnkFinally, nnkRaiseStmt,
|
||||
nnkYieldStmt, nnkDefer, nnkTryStmt, nnkFinally, nnkRaiseStmt,
|
||||
nnkReturnStmt, nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, nnkStaticStmt,
|
||||
nnkDiscardStmt, nnkStmtList,
|
||||
nnkImportStmt,
|
||||
|
||||
@@ -47,8 +47,9 @@ const
|
||||
# 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.
|
||||
nimKeywords = ["addr", "and", "as", "asm", "atomic", "bind", "block",
|
||||
"break", "case", "cast", "const", "continue", "converter", "discard",
|
||||
"distinct", "div", "do", "elif", "else", "end", "enum", "except", "export",
|
||||
"break", "case", "cast", "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", "let", "macro", "method",
|
||||
"mixin", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc",
|
||||
|
||||
5
todo.txt
5
todo.txt
@@ -1,12 +1,16 @@
|
||||
version 0.10
|
||||
============
|
||||
|
||||
Repetition renders the ridiculous reasonable.
|
||||
|
||||
- introduce ``--experimental`` switch
|
||||
- c2nim depends on the compiler
|
||||
- make nimble part of the distribution
|
||||
- split idetools into separate tool
|
||||
- split docgen into separate tool
|
||||
|
||||
|
||||
|
||||
Concurrency
|
||||
-----------
|
||||
|
||||
@@ -33,7 +37,6 @@ Misc
|
||||
Bugs
|
||||
====
|
||||
|
||||
- fix the bug that keeps 'defer' template from working
|
||||
- VM: Pegs do not work at compile-time
|
||||
- VM: ptr/ref T cannot work in general
|
||||
- scopes are still broken for generic instantiation!
|
||||
|
||||
@@ -28,6 +28,7 @@ News
|
||||
fails to match.
|
||||
- The "symmetric set difference" operator (``-+-``) never worked and has been
|
||||
removed.
|
||||
- ``defer`` is a keyword now.
|
||||
|
||||
Language Additions
|
||||
------------------
|
||||
|
||||
Reference in New Issue
Block a user