Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
camshaft committed Apr 25, 2015
0 parents commit bb590b6
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/_build
/deps
erl_crash.dump
*.ez
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
rebind
======

rebind parse transform for erlang

Usage
-----

```erlang
-module(test).
-compile({parse_transform, rebind}).

-export([sum/0]).

sum() ->
State = 1,
rebind(State) = State + 1,
rebind(State) = State + 1,
rebind(State) = State + 1,
rebind(State) = State + 1,
State.
```
18 changes: 18 additions & 0 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
defmodule Rebind.Mixfile do
use Mix.Project

def project do
[app: :rebind,
version: "0.1.0",
elixir: "~> 1.0",
deps: deps]
end

def application do
[applications: [:logger]]
end

defp deps do
[{:parse_trans, github: "uwiger/parse_trans"}]
end
end
35 changes: 35 additions & 0 deletions src/rebind.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
-module(rebind).

-export([parse_transform/2]).

parse_transform(Forms, Options) ->
{Forms2, _} = parse_trans:transform(fun do_transform/4, #{}, Forms, Options),
parse_trans:revert(Forms2).

do_transform(application,{call,_,{atom,_,rebind},[{var,Line,Name}]}, _Context, Acc) ->
Count = maps:get(Name, Acc, 0) + 1,
{rebind(Name, Line, Count), false, maps:put(Name, Count, Acc)};
do_transform(variable,{var,Line,Name}, _Context, Acc) ->
{rebind(Name, Line, Acc), false, Acc};
do_transform(match_expr, {match,Line,LH,RH}, Context, Acc) ->
%% reverse the recurse order
{RH2, Acc2} = traverse_match(RH,Acc,Context),
{LH2, Acc3} = traverse_match(LH,Acc2,Context),
{{match,Line,LH2,RH2}, false, Acc3};
do_transform(_Type, Form, _Context, Acc) ->
{Form, true, Acc}.

rebind(Name, Line, Acc) when is_map(Acc) ->
case maps:find(Name, Acc) of
error ->
{var, Line, Name};
{ok, Count} ->
rebind(Name, Line, Count)
end;
rebind(Name, Line, Count) when is_integer(Count) ->
{var, Line, list_to_atom("_" ++ atom_to_list(Name) ++ "__REBIND__" ++ integer_to_list(Count))}.

traverse_match(Side, Acc, Context) ->
{[Side2], Acc2} = parse_trans:do_transform(fun do_transform/4, Acc, [Side], Context),
[Out] = parse_trans:revert([Side2]),
{Out, Acc2}.

0 comments on commit bb590b6

Please sign in to comment.