slepher / astranaut

traverse erlang ast and elixir macro in erlang.
MIT License
15 stars 0 forks source link

unique var name generate in quote support. #4

Closed slepher closed 4 years ago

slepher commented 5 years ago
-use_macro({macro/0, [unique_var]}).
macro() ->
  quote(
    fun(A) ->
      B = A + 1
      B  = A + 3
      {C, +B} = {A  + 5, A +3}
      {B, C}
   end). 

hello(A) ->
  B = A + 5,
  macro().
=>
hello(A) ->
  B = A + 5,
  fun(A_1@Q_1) ->
      B_1@Q_1 = A_1@Q_1 + 1
      B_2@Q_1 = A_1@Q_1 + 3
      {C_1@Q_1, B_2@Q_1} = {A_1@Q_1  + 5, A_1@Q_1 + 3}
      {B_2@Q_1, C_1@Q_1}
   end.

+before Var is pin operator. just behaviours like pattern matching and pin operator in elixir https://elixir-lang.org/getting-started/pattern-matching.html

slepher commented 5 years ago

how exlir impl

defmodule TestElixirMacro do
  defmacro test_0(do: e) do
    quote do
      a = 0
      b = 3
      b = 5
      c = b + 3
      unquote(e)
      unquote(e)
      c
    end
  end
end

defmodule TestElixir do
  require TestElixirMacro

  def hello do
    b = 1
    TestElixirMacro.test_0 do
      b = b + 10
    end
    TestElixirMacro.test_0 do
      b = b + 10
    end
    b
  end
end
:beam_lib.chunks(:code.which(Elixir.TestElixir), [:abstract_code])
       {:function, 4, :hello, 0,
        [
          {:clause, 4, [], [],
           [
             {:match, 5, {:var, 5, :_b@1}, {:integer, 0, 1}},
             {:match, 6, {:var, 6, :__@1}, {:integer, 0, 0}},
             {:match, 6, {:var, 6, :__@2}, {:integer, 0, 3}},
             {:match, 6, {:var, 6, :__@3}, {:integer, 0, 5}},
             {:match, 6, {:var, 6, :__@4},
              {:op, 6, :+, {:var, 6, :__@3}, {:integer, 0, 3}}},
             {:match, 7, {:var, 7, :_b@2},
              {:op, 7, :+, {:var, 7, :_b@1}, {:integer, 0, 10}}},
             {:match, 7, {:var, 7, :_b@3},
              {:op, 7, :+, {:var, 7, :_b@2}, {:integer, 0, 10}}},
             {:var, 6, :__@4},
             {:match, 9, {:var, 9, :__@5}, {:integer, 0, 0}},
             {:match, 9, {:var, 9, :__@6}, {:integer, 0, 3}},
             {:match, 9, {:var, 9, :__@7}, {:integer, 0, 5}},
             {:match, 9, {:var, 9, :__@8},
              {:op, 9, :+, {:var, 9, :__@7}, {:integer, 0, 3}}},
             {:match, 10, {:var, 10, :_b@4},
              {:op, 10, :+, {:var, 10, :_b@3}, {:integer, 0, 10}}},
             {:match, 10, {:var, 10, :_b@5},
              {:op, 10, :+, {:var, 10, :_b@4}, {:integer, 0, 10}}},
             {:var, 9, :__@8},
             {:var, 12, :_b@5}
           ]}
        ]}
     ]}
slepher commented 4 years ago

macro.ex explain move to https://github.com/slepher/astranaut/issues/7#issuecomment-532026726

slepher commented 4 years ago

support elixir style var in macro is useless. change it to global declaration.

-unique_var(true).
slepher commented 4 years ago

done.