make genericParams support static[T] generic params (#13433)

* make genericParams support static[T] generic params

* WrapStatic => StaticParam
This commit is contained in:
Timothee Cour 2020-03-02 09:05:14 -08:00 • committed by GitHub
commit 451b724c40
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 72 additions and 7 deletions

View file

@ -86,13 +86,13 @@ since (1, 1):
# Note: `[]` currently gives: `Error: no generic parameters allowed for ...`
type(default(T)[i])
type StaticParam*[value] = object
## used to wrap a static value in `genericParams`
import std/macros
macro genericParams*(T: typedesc): untyped {.since: (1, 1).} =
## return tuple of generic params for generic `T`
runnableExamples:
type Foo[T1, T2]=object
doAssert genericParams(Foo[float, string]) is (float, string)
macro genericParamsImpl(T: typedesc): untyped =
# auxiliary macro needed, can't do it directly in `genericParams`
result = newNimNode(nnkTupleConstr)
var impl = getTypeImpl(T)
expectKind(impl, nnkBracketExpr)
@ -107,11 +107,33 @@ macro genericParams*(T: typedesc): untyped {.since: (1, 1).} =
continue
of nnkBracketExpr:
for i in 1..<impl.len:
result.add impl[i]
let ai = impl[i]
var ret: NimNode
case ai.typeKind
of ntyStatic:
ret = newTree(nnkBracketExpr, @[bindSym"StaticParam", ai])
of ntyTypeDesc:
ret = ai
else:
assert false, $(ai.typeKind, ai.kind)
result.add ret
break
else:
error "wrong kind: " & $impl.kind
since (1, 1):
template genericParams*(T: typedesc): untyped =
## return tuple of generic params for generic `T`
runnableExamples:
type Foo[T1, T2]=object
doAssert genericParams(Foo[float, string]) is (float, string)
type Bar[N: static float, T] = object
doAssert genericParams(Bar[1.0, string]) is (StaticParam[1.0], string)
doAssert genericParams(Bar[1.0, string]).get(0).value == 1.0
type T2 = T
genericParamsImpl(T2)
when isMainModule:
static:
doAssert $type(42) == "int"