tim2CF

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

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. :slight_smile:

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. :slight_smile:

Where Next?

Popular in Questions Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
Lily
In templates/appointment/index.html.eex: <%= for appointment <- @appointments do %> <tr> <td><%= appoi...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New

We're in Beta

About us Mission Statement