import macros, strutils
type TypeA = distinct int
type TypeB = distinct int
macro printType(e:expr[typed]) : stmt =
echo e.getType.treeRepr
discard
let a = 0.TypeA
let b = 0.TypeB
printType(a) # distinct[int]
printType(b) # distinct[int]
I need this, because I would like to branch in my macro, depending on the type that I pass to the macro
macro magicmacro(e:expr[typed]) : stmt =
case e.getType.name # proc name doesn't exist, but that's what I would need.
of "TypeA":
# do some A related stuff
of "TypeB":
# do some B related stuff
import macros
type TypeA = distinct int
type TypeB = distinct int
let a = 0.TypeA
let b = 1.TypeB
macro magicmacro(e:TypeA): stmt =
quote do:
echo "type A ", `e`.int
macro magicmacro(e:TypeB): stmt =
quote do:
echo "type B ", `e`.int
magicmacro(a)
magicmacro(b)
# prints:
# type A 0
# type B 1
I haven't found a way to get the expr's type at compile type in the way you want it. At runtime, you can use a.type.name (from the typetraits module) by the way.
You can use n.kind (proc kind) to obtain the NimNodeKind of a Nim node n, n.symbol (proc symbol) to obtain the NimSym of a Nim node that represents a symbol, and sym.getImpl (proc getImpl) to get the definition of a symbol.
For example, I've extended your code to use these procs:
import macros, strutils
type TypeA = distinct int
type TypeB = distinct int
proc printSymbolDef(sym: NimSym) {.compileTime.} =
echo "\n=> printSymbolDef(sym: $#)" % $sym
let impl = sym.getImpl
echo "sym.impl == " & $impl.treeRepr
echo "\nimpl.kind == " & $impl.kind
if impl.kind == nnkConv:
echo impl[0].treeRepr
echo "=====> " & $impl[0].symbol
elif impl.kind == nnkSym:
# Recursion!
printSymbolDef(impl.symbol)
macro printType(e: typed): stmt =
echo e.getType.treeRepr
echo "----"
echo "e.kind == " & $e.kind
if e.kind == nnkSym:
printSymbolDef(e.symbol)
echo "\n********\n"
discard
let a = 0.TypeA
var b: TypeB = 0.TypeB
var c: TypeB = b
printType(a)
printType(b)
printType(c)
When I compile this code, I get the following output:
BracketExpr
Sym "distinct"
Sym "int"
----
e.kind == nnkSym
=> printSymbolDef(sym: a)
sym.impl == Conv
Sym "TypeA"
IntLit 0
impl.kind == nnkConv
Sym "TypeA"
=====> TypeA
********
BracketExpr
Sym "distinct"
Sym "int"
----
e.kind == nnkSym
=> printSymbolDef(sym: b)
sym.impl == Conv
Sym "TypeB"
IntLit 0
impl.kind == nnkConv
Sym "TypeB"
=====> TypeB
********
BracketExpr
Sym "distinct"
Sym "int"
----
e.kind == nnkSym
=> printSymbolDef(sym: c)
sym.impl == Sym "b"
impl.kind == nnkSym
=> printSymbolDef(sym: b)
sym.impl == Conv
Sym "TypeB"
IntLit 0
impl.kind == nnkConv
Sym "TypeB"
=====> TypeB
********