I am trying to write a macro that expands into a call to another macro. Moreover, that other macro isn’t known statically—it’s determined at macro expansion time. I’m having difficulty constructing an AST with the macro name in a variable. Here’s what I’ve tried:
macro make_time_call(expr)
time_macro = Symbol("@time")
return Expr(:macrocall, [time_macro, LineNumberNode(1), 42])
end
@make_time_call 42
Gives me this error:
ERROR: LoadError: ArgumentError: "macrocall": too few arguments (expected 3)
Stacktrace:
[1] include(fname::String)
@ Base.MainInclude ./client.jl:478
[2] top-level scope
@ REPL[50]:1
in expression starting at /Users/ashton/…/tst.jl:6
Which seems really strange to me: no where am I calling a function called macrocall
—I’m just trying to create an AST node for a macro call. I’ve reproduced the three functions as best I can.
Then I tried using what looked like a solution here:
macro make_time_call(expr)
time_macro = Symbol("@time")
return esc(:(@time $expr)) # works
end
@make_time_call 42
and that works as expected—I get the (short!) runtime for evaluating 42
. But I need to be able to switch what macro is called; I can’t just have @time
sitting in there. So I tried this:
macro make_time_call(expr)
time_macro = Symbol("@time")
return esc(:($time_macro $expr))
end
@make_time_call 42
and I get this error:
ERROR: LoadError: UndefVarError: `$` not defined
Stacktrace:
[1] top-level scope
@ ~/…/tst.jl:6
[2] include(fname::String)
@ Base.MainInclude ./client.jl:478
[3] top-level scope
@ REPL[50]:1
in expression starting at /Users/ashton/…/tst.jl:6
Why does it think that $
is a variable that’s not defined?!
How can I call a macro given a symbol?