summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ast.nim3
-rw-r--r--compiler/lexer.nim6
-rw-r--r--compiler/parser.nim10
-rw-r--r--compiler/semstmts.nim21
-rw-r--r--compiler/wordrecg.nim4
-rw-r--r--doc/gc.txt3
-rw-r--r--doc/grammar.txt3
-rw-r--r--doc/keywords.txt2
-rw-r--r--lib/core/macros.nim2
-rw-r--r--lib/packages/docutils/highlite.nim5
-rw-r--r--todo.txt5
-rw-r--r--web/news.txt1
12 files changed, 45 insertions, 20 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",
diff --git a/doc/gc.txt b/doc/gc.txt
index fdb1d1b6c..9398262d9 100644
--- a/doc/gc.txt
+++ b/doc/gc.txt
@@ -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)
diff --git a/doc/grammar.txt b/doc/grammar.txt
index a54428678..bce3769d0 100644
--- a/doc/grammar.txt
+++ b/doc/grammar.txt
@@ -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
diff --git a/doc/keywords.txt b/doc/keywords.txt
index a43b35475..67ff0ab7f 100644
--- a/doc/keywords.txt
+++ b/doc/keywords.txt
@@ -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
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index b61fe1d17..ed5d3c50c 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -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,
diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim
index d4bd94e5e..9c482575a 100644
--- a/lib/packages/docutils/highlite.nim
+++ b/lib/packages/docutils/highlite.nim
@@ -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",
diff --git a/todo.txt b/todo.txt
index 077f5c9cb..6068c049b 100644
--- a/todo.txt
+++ b/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!
diff --git a/web/news.txt b/web/news.txt
index fd9ac77c2..65f245ae6 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -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
   ------------------