First of all, avoid using const sequences, use arrays if possible. Also, _stmt_ 
is depreciated, use _untyped_ instead.

You don't really need to store fields' names anywhere, actually. Nim's macros 
do code transformations at the compile time, when fields' names are known. Try 
it with: 
    
    
    echo treeRepr(x.getType)
    

where x is any variable you put into the macro. It will show you how the AST 
tree for the type.

How to utilize this information? As you run the above command on your type, 
you'll see it (and any object type, actually), has three children:

  * pragmas associated with the type (none here)
  * parent information (none here)
  * field information



Which means the information you need can be access through _obj.getType[2]_. 
Also, it means the macro can generate code for any object type, not just 
mtcars. 
    
    
    import strutils
    macro dif(obj: typed): untyped =
      result = newStmtList()
      for col in obj.getType[2]:
        result.add parseStmt("result.$1 = x.$1 - y.$1" % [$col])
    

You can also pass a typedesc instead, then using _typeName.getType_ will 
convert typedesc into a NimNode (BracketExpr, to be specific). It has two 
elements, the second of which is a Sym corresponding to the type. So you need 
_typeName.getType[1].getType[2]_.

Macros can be also used to actually create the needed procedure so you don't 
have to write "proc - (x, y: A): B = dif(x)". You can do it either by using 
parseExpr/quote or by-hand, using newProc.

Of course I advice you to write a more universal macro so that it can generate 
any given code for all the given type's fields. Remember that the code is 
actually duplicated, not generalized.

Reply via email to