In nim I have a macro that takes in a proc definition and generates a proc based on that and some statements. The syntax looks like this:
type A = object
name: string
type B = object
name: string
id: int
macro generateMapper(body: untyped): untyped =
let procDefNode: NimNode = body[0]
... macro code ...
generateMapper():
proc myMapProc(source: A, target: B): string =
target.name = source.name
I can fetch the proc definition out of the body into procDefNode
as shown. The procDefNode.treeRepr
is:
ProcDef
Ident "myMapProc"
Empty
Empty
FormalParams
Ident "string"
IdentDefs
Ident "source"
Ident "A"
Empty
IdentDefs
Ident "target"
Ident "B"
Empty
Empty
Empty
StmtList
... some body statements that don't matter right now...
This shows that I can access the nodes of my parameter types, which are A
and B
.
What I want now is to generate a list from the node for B
of all the fields that type has. In this example that would be @["name", "id"]
.
But how do I do that?
I've skimmed through std/macros and getImpl
seems like the thing I want, but I can't figure out how to make it work.
This:
macro generateMapper(body: untyped): untyped =
let procDefNode: NimNode = body[0]
let typeNode = procDefNode[3][2][1] # 3 is the node for FormalParams, 2 is the Node of the second parameter and 1 there is the type-Node of the second parameter
echo getImpl(typeNode)
Just errors out with Error: node is not a symbol
.
So how do I get from the node ident "B"
aka typeNode
to all of its fields in the shape of @["name", "id"]
?