@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

Reply via email to