In one of my macros I would like to be able to retrieve a constant value (i.e. const, literal etc.) or routine (procedure, iterator) call from passed code. Minimal example:
const ProgramName = "MyProgram"
const Settings = (x: 5, y: 3, Q: 12.0)
myMacro:
name: ProgramName
range: 1..10
iter: Settings.items
Right now I only figured out how to get the range but that's just because I can handle it separately as they will be pretty common for my use case.
Added some type safety, used fieldPairs instead of items as an iterator:
import macros, tables, strutils
type
SettingsType = tuple[x: int, y: int, Q: float]
const ProgramName = "MyProgram"
const Settings = (x: 5, y: 3, Q: 12.0)
template doSomething(name: string, range: Slice[int], iter: (iterator(t: SettingsType): RootObj)): untyped =
echo name
for i in range:
echo i
for n, v in iter:
echo "$#: $#" % [n, $v]
macro myMacro(body: untyped): typed =
var props = initTable[string, NimNode]()
for def in body:
props[$def[0].ident] = def[1][0]
getAst doSomething(props["name"], props["range"], props["iter"])
myMacro:
name: ProgramName
range: 1..10
iter: Settings.fieldPairs
Edit: added actual use of range.OK, I hope this time I understand what you want :)
This must be imported in your code example and the macro line defining iter has to be commented out (supplying a closure iterator should also work):
import macros
# gets the name and bound symbol of a constant and does whatever is desired,
# even with constants of arbitrary type.
macro constCall*(name: string, value: typed): untyped =
result = newStmtList()
echo name, ": ", treeRepr(
if nnkSym == value.kind: value.symbol.getImpl
else: value
)
template constCallDef(name, value: untyped) =
constCall(name, value)
# converts constant entries into calls to constCall
macro myMacro*(body: untyped): untyped =
result = newStmtList()
for entry in body:
result.add getAst constCallDef($entry[0].ident, entry[1][0])
Alternatively, constCall could be overloaded procs, possibly similar to what you meant by "should utilize a separate generic proc".