@treeform you could also do something like this:
import macros
import strformat
type
Stuff = object
x: int
y: int
proc foobar(x: string): string =
discard
proc foobar(x: int): int =
discard
proc foobar(x: Stuff, y: string): int =
discard
proc findChild(root: NimNode, target: NimNodeKind): NimNode =
var stack = newSeqOfCap[NimNode](root.len)
# Do a iterative recursive loop using a stack
stack.add(root)
while stack.len > 0:
let elem = stack.pop()
if elem.kind == target:
return elem
else:
for child in elem:
stack.add(child)
raise newException(Exception, &"Nimnode of kind {target} not found!")
macro choose(f: typed, ty: varargs[typed]) =
for choice in f:
let impl = choice.getImpl
# Get the nested child that contains the parameters
let tree = findChild(impl, nnkFormalParams)
# FormalParams
# Sym "int"
# IdentDefs (-> arg)
# Sym "x"
# Sym "Stuff" (-> arg[1], which is the type)
# Empty
var i = 1 # skip the return type
# This loop will match the param types in order, from left to right
# and you don't have to specify them all
while i < tree.len:
let arg = tree[i]
let argTy = arg[1]
if (i-1) < ty.len and argTy == ty[i-1]:
echo impl.treeRepr
i += 1
choose(foobar, Stuff)
# This works too!
choose(foobar, Stuff, int)
choose(foobar, int)
Run