1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
%% Copyright (c) 2013, Loïc Hoguin <[email protected]>
%%
%% Permission to use, copy, modify, and/or distribute this software for any
%% purpose with or without fee is hereby granted, provided that the above
%% copyright notice and this permission notice appear in all copies.
%%
%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-module(horse_autoexport).
-export([parse_transform/2]).
parse_transform([File, Module|Forms], _) ->
Exports = [F || {attribute, _, export, [{F, 0}]} <- Forms],
AutoExports = [{attribute, 0, export, [{F, 0}]}
|| {function, _, F, 0, _} <- Forms,
"horse_" =:= string:substr(atom_to_list(F), 1, 6),
false =:= lists:member(F, Exports)],
replace_calls([File, Module|AutoExports ++ Forms]).
replace_calls(Forms) ->
lists:flatten([replace_call(Form) || Form <- Forms]).
replace_call(
{function, Fu, Name, 0, [
{clause, Cl, [], [], [
{call, Ca, {remote, _, {atom, _, horse}, {atom, _, repeat}}, [
Repeat,
Expr
]}
]}
]}
) when Repeat > 0 ->
GenName = list_to_atom("generated_" ++ atom_to_list(Name)),
[
{function, Fu, Name, 0, [
{clause, Cl, [], [], [
{call, Ca, {atom, Ca, GenName}, [Repeat]}
]}
]},
{function, Ca, GenName, 1, [
{clause, Ca, [{integer, Ca, 0}], [], [
{atom, Ca, ok}
]},
{clause, Ca, [{var, Ca, 'N'}], [], [
Expr,
{call, Ca, {atom, Ca, GenName}, [
{op, Ca, '-', {var, Ca, 'N'}, {integer, Ca, 1}}
]}
]}
]}
];
replace_call(Form) ->
Form.
|