I want to construct an expression inside a macro, given a particular input parameter.
The behavior should be like that:
julia> @macroexpand @mymacro mysym[15]
:([[:mysym], 15])
So I tried to write something like that:
macro mymacro(ex)
return :([[ :$(ex.args[1]) ], $(ex.args[2]) ])
end
# but this gave me:
julia> @macroexpand @mymacro mysym[15]
:([[(:$)((Main.ex).args[1])], 15])
I am really having trouble to understand this output.
ex.args[2] evaluated perfectly as intended to 15.
But ex.args[1] is searching to be evaluated in the Main module. I don’t want that. I just want ex to be evaluated locally inside the macro.
I reached close when I escaped ex.args[1], although I didn’t quite understood why, since I was thinking of the esc() as the way to access user namespace:
macro mymacro(ex)
return :([[ $(esc(ex.args[1])) ], $(ex.args[2]) ])
end
# so now only the `:` is missing
julia> @macroexpand @mymacro mysym[15]
:([[mysym], 15])
But adding the : really destroys everything:
macro mymacro(ex)
return :([[ :($(esc(ex.args[1]))) ], $(ex.args[2]) ])
end
julia> @macroexpand @mymacro mysym[15]
:([[Main.esc((Main.ex).args[1])], 15])
I finally got it working with
macro mymacro2(ex)
return Expr(:vect, Expr(:vect, QuoteNode(ex.args[1])), ex.args[2])
end
But that was quite hard and unintuitive to construct.
Can there be a simpler solution using :(....) like in my first attempts?