tim2CF
How to expand AST fully?
Hey!
I’m playing around with macro and I’m thinking - is it possible to completely expand quoted expression (including all private and public macro)?
Simplest example which I actually can’t fully expand:
defmodule Hello do
defmacrop foo, do: {:y, [], nil}
def bar(x, foo()), do: x + y
end
for example let’s try to use Macro.expand/2
quote do
defmodule Hello do
defmacrop foo, do: {:y, [], nil}
def bar(x, foo()), do: x + y
end
end
|> Macro.expand(__ENV__)
|> Macro.to_string
|> Code.format_string!
|> IO.puts
result is
:elixir_module.compile(
Hello,
{:__block__, [],
[
{:=, [],
[
{:result, [], Kernel},
{:__block__, [],
[
{:defmacrop, [context: Elixir, import: Kernel],
[{:foo, [context: Elixir], Elixir}, [do: {:{}, [], [:y, [], nil]}]]},
{:def, [context: Elixir, import: Kernel],
[
{:bar, [context: Elixir], [{:x, [], Elixir}, {:foo, [], []}]},
[do: {:+, [context: Elixir, import: Kernel], [{:x, [], Elixir}, {:y, [], Elixir}]}]
]}
]}
]},
{{:., [], [:elixir_utils, :noop]}, [], []},
{:result, [], Kernel}
]},
[{:q, nil, :_@0, q}],
__ENV__
)
interesting line is
{:bar, [context: Elixir], [{:x, [], Elixir}, {:foo, [], []}]},
where foo is AST of macro call, but not result of this call (should be {:y, [], Elixir})
Is there any way to expand it and get resulting quoted expression somehow?
Most Liked
OvermindDL1
That’s because it is not a macro, :foo at that point is a function invocation of something called foo that is not in scope at that point. A macro cannot be expanded unless it is in scope. ![]()
Nah, expanding is fine, you just have to make sure it is all in scope first, and def blah... inside the ast itself does not bring anything into scope at that time as it needs to be in scope ‘prior’ to the expand call. ![]()








