OMG I think I got it now.

The problem is that `register` is called with a symbol that is not guaranteed 
to be resolved, and in case of `foo(string)` ends up as `nnkClosedSymChoice`. 
Thats why overloaded `foo` example doesn't work.

I have tweaked `register` to take a call instead of symbol to guarantee that 
the symbol is fully resolved, and suddenly it worked, even the generic example. 
Here's the working version:
    
    
    import macros, tables, hashes
    
    proc hash(n: NimNode): Hash =
      hash($n)
    
    var r {.compiletime.}: Table[NimNode, NimNode]
    
    macro register(k, v: typed): untyped =
      r[k[0]] = v
    
    macro inst(c: typed): untyped =
      result = newCall(r[c[0]])
    
    proc foo(a: int) =
      proc bar() =
        echo "foo int"
      register(foo(5), bar)
    
    proc foo(a: string) =
      proc bar() =
        echo "foo string"
      register(foo("hi"), bar)
    
    proc genericfoo[T](a: T) =
      proc bar() =
        when T is int:
          echo "generic foo int"
        else:
          echo "generic foo not int"
      
      register(genericfoo(a), bar)
    
    foo(5)
    inst foo(5)
    foo("i")
    inst foo("i")
    
    genericfoo(5)
    inst genericfoo(5)
    genericfoo("i")
    inst genericfoo("i")
    
    
    Run

Now it all kinda makes sense :)

Reply via email to