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
|
||||
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",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue