假设我的类型定义如下:
type TMyStruct = object
foo: int32
bar: int16
我的目标是构建一个宏(或其他),给出一个简单的"像上面那样的对象类型,能够根据sizeof
计算类型中每个字段的大小总和。在这种情况下,int32
的大小为4,int16
的大小为2,因此想法是
myMacro(TMyStruct) # or, in the worst case, myMacro(x) where x is a TMyStruct
应评估为6作为常量表达式。我想稍后将它扩展到嵌套对象,但是一旦基本版本正常工作,这应该很容易通过递归。
我尝试了许多事情并且失败了;我设法得到的最远的是检索字段名称" foo"和" bar"在AST中作为nnkSymNodes,但我无法检索有关其类型的任何信息。有意义的文档(在我的Nim专业水平上)很少到根本不存在。
我问的是可能的,我需要用什么Nim功能才能实现它?
由于
答案 0 :(得分:1)
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)
您必须在开始时链接getType
来电,这有点奇怪。这是因为getType(t)
返回以下内容:
BracketExpr
Sym "typeDesc"
Sym "TMyStruct"
如果您想对类型的实例执行此操作,只需更改以下行:
macro sumSizes(e: typed): expr =
result = nil
let tDesc = getType(e)
请注意,此处typed
在宏中包含一个类型符号非常重要。