try this:
import macros
proc replaceSymAndIdent(a : NimNode, b : NimNode, c : NimNode, isLit :
static[bool] = true) =
for i in 0..len(a)-1:
if a[i].kind == nnkSym:
if ident(strVal(a[i])) == b:
a[i] = c
elif a[i].kind == nnkClosedSymChoice or a[i].kind == nnkOpenSymChoice:
if ident(strVal(a[i][^1])) == b:
a[i] = c
elif a[i].kind == nnkIdent:
if a[i] == b:
a[i] = c
elif a[i].len != 0:
if a[i].kind == nnkDotExpr:
when not isLit:
if a[i][0].kind == nnkSym:
if ident(strVal(a[i][0])) == b:
a[i][0] = c
elif a[i][0].kind == nnkClosedSymChoice or a[i][0].kind ==
nnkOpenSymChoice:
if ident(strVal(a[i][0][^1])) == b:
a[i][0] = c
elif a[i][0].kind == nnkIdent:
if a[i][0] == b:
a[i][0] = c
else:
replaceSymAndIdent(a[i], b, c, isLit)
macro iterateSeq(a : untyped, b : static[seq[string]], code : untyped) :
untyped =
let a =
if a.kind == nnkSym:
ident($a)
elif a.kind == nnkClosedSymChoice or a.kind == nnkOpenSymChoice:
ident($a[^1])
else:
a
#echo type(a)
result = newStmtList()
for item in b:
var newCode = code.copy()
replaceSymAndIdent(newCode, a, newLit(item), isLit = true)
result.add(newCode)
#echo treeRepr result
#echo repr result
#echo ""
#result = newStmtList()
macro assignField*(obj, fieldName, value: typed) : untyped =
let fieldSym = newIdentNode($`fieldName`)
result = quote do:
`obj`.`fieldSym`=`value`
type
SomeObj* = object
a* : int
b* : int
c* : int
var
foo = SomeObj()
iterateSeq(field, @["a", "c"]):
assignField(foo, field, 50)
echo foo
assignField(foo, "a", 100)
assignField(foo, "c", 200)
block:
assignField(foo, "b", 300)
echo foo
Run
Also, I noticed you were missing a return type on your macro so I don't know
how your code compiled at all.