Reputation: 3381
Suppose I have a type defined as follows:
type TMyStruct = object
foo: int32
bar: int16
My goal is to construct a macro (or otherwise) which, given a "simple" object type like the one above, is able to compute the sum of the sizes of each field in the type, based on sizeof
. In this case int32
has size 4 and int16
has size 2 so the idea is that
myMacro(TMyStruct) # or, in the worst case, myMacro(x) where x is a TMyStruct
should evaluate to 6 as a constant expression. I want to extend it to nested objects later on but that should be easy via recursion once the basic version is working.
I have tried many things and failed horribly; the farthest I managed to get was to retrieve the field names "foo" and "bar" in the AST as nnkSymNodes, but I was unable to retrieve any information about their types. Meaningful documentation (at my level of Nim expertise) is sparse to non-existent.
Is what I am asking possible, and what Nim functionality do I need to use to achieve it?
Thanks
Upvotes: 2
Views: 909
Reputation: 39768
import macros
type TMyStruct = object
foo: int32
bar: int16
macro sumSizes(t: typedesc): expr =
result = nil
let tDesc = getType(getType(t)[1])
for field in tDesc[2].children:
let sizeOfThis = newCall("sizeof", field)
if isNil(result):
result = sizeOfThis
else:
result = infix(result, "+", sizeOfThis)
echo sumSizes(TMyStruct)
It is a bit strange that you have to chain the getType
calls in the beginning. This is because getType(t)
returns the following:
BracketExpr
Sym "typeDesc"
Sym "TMyStruct"
If you want to do this with instances of a type, just change these lines:
macro sumSizes(e: typed): expr =
result = nil
let tDesc = getType(e)
Note that typed
is important here to have a typed symbol inside the macro.
Upvotes: 2