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

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