summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2013-12-25 00:01:12 +0200
committerZahary Karadjov <zahary@gmail.com>2013-12-25 00:32:53 +0200
commit952dbc4b8fd41bdf0f6b587147f62d8d15a95751 (patch)
treec61dd86b2d1719c2d869dce4508fb7990abd125c
parent027f30610e44633b661befcca1b5dd39e9eaa283 (diff)
downloadNim-952dbc4b8fd41bdf0f6b587147f62d8d15a95751.tar.gz
documented static params
-rw-r--r--compiler/semtypes.nim2
-rw-r--r--doc/manual.txt54
-rw-r--r--lib/system.nim10
3 files changed, 66 insertions, 0 deletions
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index d4d953757..85928ee75 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -684,6 +684,8 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
       result.sons.setLen(result.sons.len - 1)
   of tyTypeClass:
     result = addImplicitGeneric(copyType(paramType, getCurrOwner(), false))
+  of tyExpr:
+    result = addImplicitGeneric(newTypeS(tyGenericParam, c))
   else: nil
 
   # result = liftingWalk(paramType)
diff --git a/doc/manual.txt b/doc/manual.txt
index dabff3d69..dca43ecbb 100644
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -3827,6 +3827,60 @@ This is a simple syntactic transformation into:
 Special Types
 =============
 
+static[T]
+---------
+
+As their name suggests, static params must be known at compile-time:
+
+.. code-block:: nimrod
+
+  proc precompiledRegex(pattern: static[string]): TRegEx =
+    var res {.global.} = re(pattern)
+    return res
+
+  precompiledRegex("/d+") # Replaces the call with a precompiled
+                          # regex, stored in a global variable
+
+  precompiledRegex(paramStr(1)) # Error, command-line options
+                                # are not known at compile-time
+
+
+For the purposes of code generation, all static params are treated as
+generic params - the proc will be compiled separately for each unique
+supplied value (or combination of values). 
+
+Furthermore, the system module defines a `semistatic[T]` type than can be
+used to declare procs accepting both static and run-time values, which can
+optimize their body according to the supplied param using the `isStatic(p)`
+predicate:
+
+.. code-block:: nimrod
+
+  # The following proc will be compiled once for each unique static
+  # value and also once for the case handling all run-time values:
+
+  proc re(pattern: semistatic[string]): TRegEx =
+    when isStatic(pattern):
+      return precompiledRegex(pattern)
+    else:
+      return compile(pattern)
+
+Static params can also appear in the signatures of generic types:
+
+.. code-block:: nimrod
+
+  type
+    Matrix[M,N: static[int]; T: Number] = array[0..(M*N - 1), T]
+      # Please, note how `Number` is just a type constraint here, while
+      # `static[int]` requires us to supply a compile-time int value
+
+    AffineTransform2D[T] = Matrix[3, 3, T]
+    AffineTransform3D[T] = Matrix[4, 4, T]
+
+  AffineTransform3D[float] # OK
+  AffineTransform2D[string] # Error, `string` is not a `Number`
+
+
 typedesc
 --------
 
diff --git a/lib/system.nim b/lib/system.nim
index e58378c05..d45137b9e 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -2675,3 +2675,13 @@ proc locals*(): TObject {.magic: "Locals", noSideEffect.} =
   ## the official signature says, the return type is not ``TObject`` but a
   ## tuple of a structure that depends on the current scope.
   nil
+
+when not defined(booting):
+  type
+    semistatic*[T] = static[T] | T
+    # indicates a param of proc specialized for each static value,
+    # but also accepting run-time values
+
+  template isStatic*(x): expr = compiles(static(x))
+    # checks whether `x` is a value known at compile-time
+