If I write a macro as such:
macro `@@@`(x: typed): FancyType =
# stuff goes here
var a = @@@{"fromStruct": "blah", "sub": {"joe": 10}}
All is good.
Or if I do:
macro `@@@`(x: Blork): FancyType =
# stuff goes here
let xyz = Blork()
var a = @@@xyz
All is still good.
But if I do both, then one macro overwrites the other.
Okay, no problem. I'll make the first one have a specific type for that curly-bracket-thing to separate it from the other. I can't see to find the name for it though. Reverse engineering implies the type is determined on a case-by-case basis during compile-time. Makes sense. Looking at json example of %*. Yep, uses NimNode generically. Drat.
But, I'll ask anyway: is there a way to "declare" that one version of the macro is expecting the curly-bracket-thing.
Also..is there an official name for the...curly-bracket-looks-like-json-but-isn't-thing? Giving me a name will help with further communication. :)
As much as I wanted that to work, it doesn't. Once I place type like that in the macro parameter, the compiler re-encodes the Table Constructor as an array (nnkTableConstructor disappears from the NimNode). And then it stops supporting mixed structures like:
{"a": "blah", "b": 4}
Not a big deal. I'll just use different macro names.
What Nim calls the Table Constructor as dom96 has correctly pointed out, the lisp world has long called "association lists", often abbreviated "alist".
Since it is a macro you are writing, you could check that the kind of the NimNode is nnkTableConstr and if not emit a useful compile-time message for client code, as in something approximately like:
import macros
macro `@@@`(x: untyped): untyped =
if x.kind != nnkTableConstr:
error "triple-@ expects a {(,),(,)..} table constructor"
var a = @@@{"fromStruct": "blah", "sub": {"joe": 10}}
#var b = @@@[1,2,3] #Errors out with above message.
You can also use AST based overloading https://nim-lang.org/docs/manual_experimental.html#ast-based-overloading (which isn't actually experimental even though it appears there). In this case all the overloads will need to be untyped to avoid typechecking invalid AST.
import macros
macro `@@@`(x: untyped{nkTableConstr}): untyped =
echo x.treerepr
result = newNimNode(nnkTableConstr).add(x[0])
macro `@@@`(x: untyped{nkBracket}): untyped =
echo x.treerepr
result = x
macro `@@@`(x: untyped{nkStrLit}): untyped =
echo x.treerepr
result = x
var a = @@@{"fromStruct": "blah", "sub": {"joe": 10}}
var b = @@@[1,2,3]
var c = @@@"test"