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?