如何实现一个宏,用一些常见和不同的参数重复应用模板



用例如下:我有一个配置对象和一个主对象。主对象包含配置类型的字段。配置对象有很多字段,我想让它们从主对象访问,就像它们是主对象的字段一样。

下面是一个玩具示例,展示了预期的api:

type
MyCfg = object
text: string
number: int
MyObj = object
myCfg: MyCfg
otherField: bool
template expose(ObjType, cfg, field, FieldType: untyped) =
template `field`(o: ObjType): FieldType =
o.`cfg`.`field`
expose MyObj, myCfg, text, string
var obj = MyObj()
obj.myCfg.text = "hi"
echo obj.text
macro expose(ObjType, myCfg, body: untyped) =
discard

expose(ObjType, myCfg):
(text, string) # even better if I can avoid parenthesis
(number, int)

如上所示,我知道如何创建一个公开字段的template,知道如何将其封装在一个简化语法的模板中,我还没有学会如何使用宏来重复应用第一个参数始终相同的模板,我在下面几行中给出了不同的参数。

edit:此提交可能会使我的意图更加明确:https://github.com/pietroppeter/nimibook/pull/50/commits/9edf5e351713db61cabb6d4aa0c740f31ba537c4

以下作品

import std/[genasts, macros]
type
MyCfg = object
text: string
number: int
MyObj = object
myCfg: MyCfg
otherField: bool
macro expose(t: typed, childObject: untyped) =
for field in t.getimpl[2][2]:
if field[0] == childObject:
result = newStmtList()
for subfield in field[1].getimpl[2][2]:
result.add:
genast(subfieldName = subfield[0], ParentObject = t, SubfieldType = subfield[1], childObject = childObject):
proc subfieldName(o: ParentObject): SubfieldType =
o.childObject.subfieldName
MyObj.expose(myCfg)
var myObj = MyObj()
myObj.myCfg.text = "text"
myObj.myCfg.number = 1234567890
echo myObj.text
echo myObj.number

最新更新