summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-12-05 10:09:29 +0100
committerAraq <rumpf_a@web.de>2014-12-05 10:09:29 +0100
commit4b7de4dc5e628bf08ad6673652f1aa2df019525c (patch)
tree3e24d90c294a03f7e084e5e3e4c2eab12f58743a
parente27ab367318ceb01a023b367ac908c137e3223c7 (diff)
downloadNim-4b7de4dc5e628bf08ad6673652f1aa2df019525c.tar.gz
implemented 'experimental' switch
-rw-r--r--compiler/ast.nim1
-rw-r--r--compiler/commands.nim4
-rw-r--r--compiler/options.nim1
-rw-r--r--compiler/pragmas.nim8
-rw-r--r--compiler/sem.nim3
-rw-r--r--compiler/semdata.nim5
-rw-r--r--compiler/semexprs.nim2
-rw-r--r--compiler/wordrecg.nim5
-rw-r--r--doc/advopt.txt1
-rw-r--r--doc/manual/pragmas.txt18
-rw-r--r--doc/manual/stmts.txt3
-rw-r--r--web/news.txt5
12 files changed, 49 insertions, 7 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 1d2b63181..8ebe5afa6 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -294,6 +294,7 @@ const
                        # require RC ops
   sfCompileToCpp* = sfInfixCall       # compile the module as C++ code
   sfCompileToObjc* = sfNamedParamCall # compile the module as Objective-C code
+  sfExperimental* = sfOverriden       # module uses the .experimental switch
 
 const
   # getting ready for the future expr/stmt merge
diff --git a/compiler/commands.nim b/compiler/commands.nim
index f26d1d6c7..a5b0b40d7 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -226,6 +226,7 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
   of "tlsemulation": result = contains(gGlobalOptions, optTlsEmulation)
   of "implicitstatic": result = contains(gOptions, optImplicitStatic)
   of "patterns": result = contains(gOptions, optPatterns)
+  of "experimental": result = gExperimentalMode
   else: invalidCmdLineOption(passCmd1, switch, info)
   
 proc processPath(path: string, notRelativeToProj = false): string =
@@ -568,6 +569,9 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
     of "none": idents.firstCharIsCS = false
     else: localError(info, errGenerated,
       "'partial' or 'none' expected, but found " & arg)
+  of "experimental":
+    expectNoArg(switch, arg, pass, info)
+    gExperimentalMode = true
   else:
     if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
     else: invalidCmdLineOption(pass, switch, info)
diff --git a/compiler/options.nim b/compiler/options.nim
index 838f99f8e..415ac8430 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -115,6 +115,7 @@ var
                               # the tracked source X, saved by the CAAS client.
   gDirtyOriginalIdx* = 0'i32  # the original source file of the dirtified buffer.
   gNoNimblePath* = false
+  gExperimentalMode*: bool
 
 proc importantComments*(): bool {.inline.} = gCmd in {cmdDoc, cmdIdeTools}
 proc usesNativeGC*(): bool {.inline.} = gSelectedGC >= gcRefc
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index b548837fe..879950e79 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -45,7 +45,7 @@ const
     wBreakpoint, wWatchPoint, wPassl, wPassc, wDeadCodeElim, wDeprecated,
     wFloatchecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
     wLinearScanEnd, wPatterns, wEffects, wNoForward, wComputedGoto,
-    wInjectStmt, wDeprecated}
+    wInjectStmt, wDeprecated, wExperimental}
   lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, 
     wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader, 
     wDeprecated, wExtern, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame,
@@ -850,6 +850,12 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
             localError(it.info, errExprExpected)
           else: 
             it.sons[1] = c.semExpr(c, it.sons[1])
+        of wExperimental:
+          noVal(it)
+          if isTopLevel(c):
+            c.module.flags.incl sfExperimental
+          else:
+            localError(it.info, "'experimental' pragma only valid as toplevel statement") 
         else: invalidPragma(it)
       else: invalidPragma(it)
   else: processNote(c, it)
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 5b31129a5..5160af20a 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -133,9 +133,6 @@ proc commonType*(x, y: PType): PType =
         result = newType(k, r.owner)
         result.addSonSkipIntLit(r)
 
-proc isTopLevel(c: PContext): bool {.inline.} = 
-  result = c.currentScope.depthLevel <= 2
-
 proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym = 
   result = newSym(kind, considerQuotedIdent(n), getCurrOwner(), n.info)
 
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index 921e87d30..f876770c0 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -312,3 +312,8 @@ proc checkSonsLen*(n: PNode, length: int) =
 proc checkMinSonsLen*(n: PNode, length: int) = 
   if sonsLen(n) < length: illFormedAst(n)
 
+proc isTopLevel*(c: PContext): bool {.inline.} = 
+  result = c.currentScope.depthLevel <= 2
+
+proc experimentalMode*(c: PContext): bool {.inline.} =
+  result = gExperimentalMode or sfExperimental in c.module.flags
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 108e21369..ac82e9fed 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1433,6 +1433,8 @@ proc newAnonSym(kind: TSymKind, info: TLineInfo,
 
 proc semUsing(c: PContext, n: PNode): PNode =
   result = newNodeI(nkEmpty, n.info)
+  if not experimentalMode(c):
+    localError(n.info, "use the {.experimental.} pragma to enable 'using'")
   for e in n.sons:
     let usedSym = semExpr(c, e)
     if usedSym.kind == nkSym:
diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim
index 45206e7e7..f08ab0ad9 100644
--- a/compiler/wordrecg.nim
+++ b/compiler/wordrecg.nim
@@ -61,7 +61,8 @@ type
     wPassc, wPassl, wBorrow, wDiscardable,
     wFieldChecks, 
     wWatchPoint, wSubsChar, 
-    wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto, wInjectStmt,
+    wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto, 
+    wInjectStmt, wExperimental,
     wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit, 
     wAsmNoStackFrame,
     wImplicitStatic, wGlobal, wCodegenDecl, wUnchecked, wGuard, wLocks,
@@ -144,7 +145,7 @@ const
     "passc", "passl", "borrow", "discardable", "fieldchecks",
     "watchpoint",
     "subschar", "acyclic", "shallow", "unroll", "linearscanend",
-    "computedgoto", "injectstmt",
+    "computedgoto", "injectstmt", "experimental",
     "write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
     "asmnostackframe", "implicitstatic", "global", "codegendecl", "unchecked",
     "guard", "locks",
diff --git a/doc/advopt.txt b/doc/advopt.txt
index 2ddba12e8..78c3d571a 100644
--- a/doc/advopt.txt
+++ b/doc/advopt.txt
@@ -91,4 +91,5 @@ Advanced options:
   --verbosity:0|1|2|3       set Nim's verbosity level (1 is default)
   --cs:none|partial         set case sensitivity level (default: none);
                             do not use! this setting affects the whole language
+  --experimental            enable experimental language features
   -v, --version             show detailed version information
diff --git a/doc/manual/pragmas.txt b/doc/manual/pragmas.txt
index 6181b3e1b..6bb1314cd 100644
--- a/doc/manual/pragmas.txt
+++ b/doc/manual/pragmas.txt
@@ -495,3 +495,21 @@ identifier that can be used to enable or disable it:
 This is often better than disabling all warnings at once.
 
 
+experimental pragma
+-------------------
+
+The ``experimental`` pragma enables experimental language features. Depending
+on the concrete feature this means that the feature is either considered
+too unstable for an otherwise stable release or that the future of the feature
+is uncertain (it may be removed any time).
+
+Example:
+
+.. code-block:: nim
+  {.experimental.}
+
+  proc useUsing(dest: var string) =
+    using dest
+    add "foo"
+    add "bar"
+
diff --git a/doc/manual/stmts.txt b/doc/manual/stmts.txt
index 8d958733d..e31be7121 100644
--- a/doc/manual/stmts.txt
+++ b/doc/manual/stmts.txt
@@ -488,7 +488,8 @@ Instead of:
 Using statement
 ---------------
 
-**Warning**: The ``using`` statement is highly experimental!
+**Warning**: The ``using`` statement is highly experimental and has to be
+explicitly enabled with the `experimental`:idx: pragma or command line option!
 
 The using statement provides syntactic convenience for procs that
 heavily use a single contextual parameter. When applied to a variable or a
diff --git a/web/news.txt b/web/news.txt
index 65f245ae6..76541560c 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -29,6 +29,8 @@ News
   - The "symmetric set difference" operator (``-+-``) never worked and has been
     removed.
   - ``defer`` is a keyword now.
+  - The ``using`` language feature now needs to be activated via the new
+    ``{.experimental.}`` pragma that enables experimental language features.
 
   Language Additions
   ------------------
@@ -39,6 +41,9 @@ News
   - ``deepCopy`` has been added to the language.
   - The builtin ``procCall`` can be used to get ``super``-like functionality
     for multi methods.
+  - There is a new pragma ``{.experimental.}`` that enables experimental
+    language features per module, or you can enable this features on a global
+    level with the ``--experimental`` command line option.
 
 
   Compiler Additions