I am trying to correctly handle visibility modifiers in my patty macros for pattern matching. I am getting an error I don't understand.
For context, the variant macro expands a declaration like
variant Shape:
Circle(r: float)
Rectangle(w: float, h: float)
UnitCircle
to something like
type
ShapeKind {.pure.} = enum
Circle, Rectangle, UnitCircle
Shape = object
case kind: ShapeKind
of ShapeKind.Circle:
r: float
of ShapeKind.Rectangle:
w: float
h: float
of ShapeKind.UnitCircle:
nil
plus some definitions for equality and constructors (see here for more information).
I would like to be able to decide whether the defined types are public or private. The problem is, if I try to change this line to
let enumType =
if pub: newEnum(postfix(enumName, "*"), enumsIn(body))
else: newEnum(enumName, enumsIn(body))
that is, by adding a * if some flag is set, I get an error test.nim(77, 14) Error: invalid visibility: '*' in the calling code.
What is the right way to set visibility inside a macro?
Thats how i do it:
if export_proc:
ctor[0] = new_nim_node(nnkPostfix).add(
new_ident_node("*"),
ctor[0]
)
Rule of thumb - manually write code that macro should generate and dump its ast. Then make a macro to construct identical AST. Pretty sure you will find inconsistencies between AST of manually written code and AST generated by your macro.
The postfix function in the macros package is just a shortcut for that, see here
It seems to me that the two trees are identical - in fact that is how I found out how to set the visibility. Still, I get the above error.
EDIT: I checked by calling echo treeRepr(result) in my macro vs calling dumpTree on the desired output written by hand. I ran a diff and it turns out the two trees are identical
I will restructure my tests to avoid the issue
Or maybe we should allow * but ignore in a local scope for convenience.