如何实现宏以使用一些常见参数和一些不同参数重复应用模板
How to implement a macro to apply a template repeatedly with some common and some varying arguments
用例如下:我有一个配置对象和一个主对象。主对象包含配置类型的字段。 Config 对象有很多字段,我想让它们从主对象访问,就好像它们是主对象的字段一样。
这是一个玩具示例,显示了预期 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
用例如下:我有一个配置对象和一个主对象。主对象包含配置类型的字段。 Config 对象有很多字段,我想让它们从主对象访问,就好像它们是主对象的字段一样。
这是一个玩具示例,显示了预期 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