1import ast
2
3template elementType*(T: typedesc): typedesc =
4  typeof(block:
5    var a: T
6    for ai in a: ai)
7
8proc fromLit*(a: PNode, T: typedesc): auto =
9  ## generic PNode => type
10  ## see also reverse operation `toLit`
11  when T is set:
12    result = default(T)
13    type Ti = elementType(T)
14    for ai in a:
15      result.incl Ti(ai.intVal)
16  else:
17    static: doAssert false, "not yet supported: " & $T # add as needed
18
19proc toLit*[T](a: T): PNode =
20  ## generic type => PNode
21  ## see also reverse operation `fromLit`
22  when T is string: newStrNode(nkStrLit, a)
23  elif T is Ordinal: newIntNode(nkIntLit, a.ord)
24  elif T is (proc): newNode(nkNilLit)
25  elif T is ref:
26    if a == nil: newNode(nkNilLit)
27    else: toLit(a[])
28  elif T is tuple:
29    result = newTree(nkTupleConstr)
30    for ai in fields(a): result.add toLit(ai)
31  elif T is seq:
32    result = newNode(nkBracket)
33    for ai in a:
34      result.add toLit(ai)
35  elif T is object:
36    result = newTree(nkObjConstr)
37    result.add(newNode(nkEmpty))
38    for k, ai in fieldPairs(a):
39      let reti = newNode(nkExprColonExpr)
40      reti.add k.toLit
41      reti.add ai.toLit
42      result.add reti
43  else:
44    static: doAssert false, "not yet supported: " & $T # add as needed
45
46