I am trying to make a macro which takes an untyped block but can be still overloaded by any other routine with the same name (mainly to avoid name conflicts). In the other words: I'm looking for something which means "bind symbol in calling scope" (NOT in the macro's scope, which is the default). Does anyone know a way to do it?
Example:
foreach i in 1 .. 10: # calling `macro foreach(head, body: untyped): untyped`
...
var seq = @[1, 2, 3, 4, 5]
s.foreach(echo) # calling `proc foreach[T](arr: openArray[T], fun: proc (x: T) {..})`
Of course I wouldn't like the macro to have to know about every possible overloader and try as it would be pretty much pointless.
I'm not sure whether it actually is possible without dirty hacks like dynamically creating a new macro in the call scope or something, but hope it is. :)
You can overload macros by node kind:
macro foreach(e: untyped{nkInfix}, body: untyped{nkStmtList}): untyped =
discard
Surprisingly, it reports illformed AST when I try this.
Overloading by node kind seems a nice option but doesn't really solve my problem. :( Just like in the example, I only want X in Y form for the first argument to match.
My guess is that you need mixin to have the symbol lookup happen later, but I'm not familiar with that part of the language.
mixin is mentioned here https://nim-lang.org/docs/manual.html#generics-symbol-lookup-in-generics but there isn't a lot of documentation.