Hi fellows
This is what happens
julia> Expr(:macrocall,Symbol("@m"),:(:x),:y)
:(@m y)
I was expecting
@m :x y)
Is this a bug?
Thanks
Hi fellows
This is what happens
julia> Expr(:macrocall,Symbol("@m"),:(:x),:y)
:(@m y)
I was expecting
@m :x y)
Is this a bug?
Thanks
dump
shows that macro calls are actually parsed with an extra first argument which holds the current line number:
julia> dump(:(@foo x))
Expr
head: Symbol macrocall
args: Array{Any}((3,))
1: Symbol @foo
2: LineNumberNode
line: Int64 1
file: Symbol REPL[1]
3: Symbol x
typ: Any
so it looks like your :x
is taking the place of that LineNumberNode. I’m not sure what the recommended practice is for constructing :macrocall
expressions manually, but it looks like you can provide that argument yourself:
julia> Expr(:macrocall, Symbol("@m"), LineNumberNode(0), :x, :y)
:(#= line 0 =# @m x y)
or let Julia do the parsing for you:
julia> :(@m $(:x) $(:y))
:(#= REPL[11]:1 =# @m x y)
You need to use Meta.quot
:
julia> :(@m $(Meta.quot(:x)) y)
:(@m :x y)
julia> Expr(:macrocall, Symbol("@m"), Meta.quot(:x), :y)
:(@m :x y)
See:
This is not the issue. (the first reply already answered it)
Ah, I see I was on 0.6.x, this breaking change is confusing because it is undocumented, just barely mentioned in NEWS, the only example is misleading, since it doesn’t need to be a LineNumberNode
and one con not dispatch a macro on that:
All macros receive an extra argument
__source__::LineNumberNode
which describes the parser location in the source file for the@
of the macro call. It can be accessed as a normal argument variable in the body of the macro. This is implemented by inserting an extra leading argument into theExpr(:macrocall, :@name, LineNumberNode(...), args...)
surface syntax. (#21746)
This well formed ekpression, looks nasty IMHO
julia> macro m(x, y) :($x, $y) end
@m (macro with 1 method)
julia> y = 5
5
julia> Expr(:macrocall, Symbol("@m"), rand(10), :(:x), :y)
:(@m :x y)
julia> eval(ans)
(:x, 5)
What I meant was that redits would still need to use quot
or wrap in :(...)
in order to return the desired output, also wouldn’t @__LINE__
be a better suggestion then (in this case it simply returns an int)?
We need to pass the line number node (or just anything) explicitly when constructing the expression manually yet it is inserted automatically when parsed? The metaprogramming API is getting real messy for my brain
julia> Expr(:macrocall, Symbol("@m"), @__LINE__, :(:x), :y)
:(@m :x y)
julia> dump(ans)
Expr
head: Symbol macrocall
args: Array{Any}((4,))
1: Symbol @m
2: Int64 1
3: QuoteNode
value: Symbol x
4: Symbol y
typ: Any