diff options
author | Zahary Karadjov <zahary@gmail.com> | 2013-12-25 00:01:12 +0200 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2013-12-25 00:32:53 +0200 |
commit | 952dbc4b8fd41bdf0f6b587147f62d8d15a95751 (patch) | |
tree | c61dd86b2d1719c2d869dce4508fb7990abd125c | |
parent | 027f30610e44633b661befcca1b5dd39e9eaa283 (diff) | |
download | Nim-952dbc4b8fd41bdf0f6b587147f62d8d15a95751.tar.gz |
documented static params
-rw-r--r-- | compiler/semtypes.nim | 2 | ||||
-rw-r--r-- | doc/manual.txt | 54 | ||||
-rw-r--r-- | lib/system.nim | 10 |
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 + |