documented static params
This commit is contained in:
parent
027f30610e
commit
952dbc4b8f
3 changed files with 66 additions and 0 deletions
|
|
@ -684,6 +684,8 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
result.sons.setLen(result.sons.len - 1)
|
result.sons.setLen(result.sons.len - 1)
|
||||||
of tyTypeClass:
|
of tyTypeClass:
|
||||||
result = addImplicitGeneric(copyType(paramType, getCurrOwner(), false))
|
result = addImplicitGeneric(copyType(paramType, getCurrOwner(), false))
|
||||||
|
of tyExpr:
|
||||||
|
result = addImplicitGeneric(newTypeS(tyGenericParam, c))
|
||||||
else: nil
|
else: nil
|
||||||
|
|
||||||
# result = liftingWalk(paramType)
|
# result = liftingWalk(paramType)
|
||||||
|
|
|
||||||
|
|
@ -3827,6 +3827,60 @@ This is a simple syntactic transformation into:
|
||||||
Special Types
|
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
|
typedesc
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2675,3 +2675,13 @@ proc locals*(): TObject {.magic: "Locals", noSideEffect.} =
|
||||||
## the official signature says, the return type is not ``TObject`` but a
|
## the official signature says, the return type is not ``TObject`` but a
|
||||||
## tuple of a structure that depends on the current scope.
|
## tuple of a structure that depends on the current scope.
|
||||||
nil
|
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
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue