Created
July 13, 2016 02:11
-
-
Save lalbuquerque/921cb6d7726e1a8fd40a5e21a738bb25 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@doc """ | |
Breaks a pipeline expression into a list. | |
The AST for a pipeline (a sequence of applications of `|>`) is similar to the | |
AST of a sequence of binary operators or function applications: the top-level | |
expression is the right-most `:|>` (which is the last one to be executed), and | |
its left-hand and right-hand sides are its arguments: | |
quote do: 100 |> div(5) |> div(2) | |
#=> {:|>, _, [arg1, arg2]} | |
In the example above, the `|>` pipe is the right-most pipe; `arg1` is the AST | |
for `100 |> div(5)`, and `arg2` is the AST for `div(2)`. | |
It's often useful to have the AST for such a pipeline as a list of function | |
applications. This function does exactly that: | |
Macro.unpipe(quote do: 100 |> div(5) |> div(2)) | |
#=> [{100, 0}, {{:div, [], [5]}, 0}, {{:div, [], [2]}, 0}] | |
We get a list that follows the pipeline directly: first the `100`, then the | |
`div(5)` (more precisely, its AST), then `div(2)`. The `0` as the second | |
element of the tuples is the position of the previous element in the pipeline | |
inside the current function application: `{{:div, [], [5]}, 0}` means that the | |
previous element (`100`) will be inserted as the 0th (first) argument to the | |
`div/2` function, so that the AST for that function will become `{:div, [], | |
[100, 5]}` (`div(100, 5)`). | |
""" | |
@spec unpipe(Macro.t) :: [Macro.t] | |
def unpipe(expr) do | |
:lists.reverse(unpipe(expr, [])) | |
end | |
defp unpipe({:|>, _, [left, right]}, acc) do | |
unpipe(right, unpipe(left, acc)) | |
end | |
defp unpipe(other, acc) do | |
[{other, 0} | acc] | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment