cleanup, type fixes and new rebar

This commit is contained in:
Ulf Wiger 2011-04-18 15:16:54 +02:00
parent 3741317006
commit 60299e7410
15 changed files with 318 additions and 511 deletions

3
.gitignore vendored
View File

@ -1,3 +1,6 @@
examples/*.beam
examples/*.xf*
ebin
*~
*/*~
.eunit

View File

@ -32,51 +32,45 @@ The very simplest transform we can make is one that doesn't
change a thing. For convenience, we will at least print the forms.
This will enlighten us as to what the forms actually look like.
<pre>
-module(test_pt).
-export([parse_transform/2]).
parse_transform(Forms, _Options) ->
io:fwrite("Forms = ~p~n", [Forms]),
Forms.
io:fwrite("Forms = ~p~n", [Forms]),
Forms.
</pre>
Trying this with a very simple module:
<pre>
-module(ex1).
-export([add/2]).
add(X,Y) ->
X + Y.
X + Y.
</pre>
<pre>
1> c(ex1, [{parse_transform,test_pt}]).
Forms = [{attribute,1,file,{"./ex1.erl",1}},
{attribute,1,module,ex1},
{attribute,2,export,[{add,2}]},
{function,4,add,2,
[{clause,4,
[{var,4,'X'},{var,4,'Y'}],
[],
[{op,5,'+',{var,5,'X'},{var,5,'Y'}}]}]},
{eof,6}]
{attribute,1,module,ex1},
{attribute,2,export,[{add,2}]},
{function,4,add,2,
[{clause,4,
[{var,4,'X'},{var,4,'Y'}],
[],
[{op,5,'+',{var,5,'X'},{var,5,'Y'}}]}]},
{eof,6}]
{ok,ex1}
</pre>
<h2>`transform/4`</h2>
<h2><code>transform/4</code></h2>

View File

@ -5,6 +5,7 @@ Module ct_expand
<h1>Module ct_expand</h1>
* [Description](#description)
* [Data Types](#types)
* [Function Index](#index)
* [Function Details](#functions)
@ -38,6 +39,39 @@ For example, the line
would be expanded at compile-time to `[1,2,3,4,5]`.
<h2><a name="types">Data Types</a></h2>
<h3 class="typedecl"><a name="type-form">form()</a></h3>
<pre>form() = any()</pre>
<h3 class="typedecl"><a name="type-forms">forms()</a></h3>
<pre>forms() = [<a href="#type-form">form()</a>]</pre>
<h3 class="typedecl"><a name="type-options">options()</a></h3>
<pre>options() = [{atom(), any()}]</pre>
<h2><a name="index">Function Index</a></h2>
@ -45,23 +79,20 @@ would be expanded at compile-time to `[1,2,3,4,5]`.
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#parse_transform-2">parse_transform/2</a></td><td></td></tr></table>
<a name="functions"></a>
<h2>Function Details</h2>
<h2><a name="functions">Function Details</a></h2>
<a name="parse_transform-2"></a>
<h3>parse_transform/2</h3>
`parse_transform(Forms, Options) -> any()`
<pre>parse_transform(Forms::<a href="#type-forms">forms()</a>, Options::<a href="#type-options">options()</a>) -> <a href="#type-forms">forms()</a></pre>
<br></br>
_Generated by EDoc, Nov 11 2010, 22:26:54._

View File

@ -5,6 +5,7 @@ Module exprecs
<h1>Module exprecs</h1>
* [Description](#description)
* [Data Types](#types)
* [Function Index](#index)
* [Function Details](#functions)
@ -41,81 +42,112 @@ inserting a compiler attribute,
`export_records([RecName|...])` causes this transform
to lay out access functions for the exported records:
<pre>
-module(test_exprecs).
-module(test_exprecs).
-record(r, {a, b, c}).
-export_records([r]).
-record(r, {a, b, c}).
-export_records([r]).
-export(['#new-'/1, '#info-'/1, '#info-'/2, '#pos-'/2,
'#is_record-'/2, '#get-'/2, '#set-'/2, '#fromlist-'/2,
'#new-r'/0, '#new-r'/1, '#get-r'/2, '#set-r'/2,
'#pos-r'/1, '#fromlist-r'/2, '#info-r'/1]).
-export(['#new-'/1, '#info-'/1, '#info-'/2, '#pos-'/2,
'#is_record-'/2, '#get-'/2, '#set-'/2, '#fromlist-'/2,
'#new-r'/0, '#new-r'/1, '#get-r'/2, '#set-r'/2,
'#pos-r'/1, '#fromlist-r'/2, '#info-r'/1]).
'#new-'(r) -> '#new-r'().
'#new-'(r) -> '#new-r'().
'#info-'(RecName) -> '#info-'(RecName, fields).
'#info-'(RecName) -> '#info-'(RecName, fields).
'#info-'(r, Info) -> '#info-r'(Info).
'#info-'(r, Info) -> '#info-r'(Info).
'#pos-'(r, Attr) -> '#pos-r'(Attr).
'#pos-'(r, Attr) -> '#pos-r'(Attr).
'#is_record-'(r, Rec)
when tuple_size(Rec) == 3, element(1, Rec) == r ->
true;
'#is_record-'(_, _) -> false.
'#is_record-'(r, Rec)
when tuple_size(Rec) == 3, element(1, Rec) == r ->
true;
'#is_record-'(_, _) -> false.
'#get-'(Attrs, Rec) when is_record(Rec, r) ->
'#get-r'(Attrs, Rec).
'#get-'(Attrs, Rec) when is_record(Rec, r) ->
'#get-r'(Attrs, Rec).
'#set-'(Vals, Rec) when is_record(Rec, r) ->
'#set-r'(Vals, Rec).
'#set-'(Vals, Rec) when is_record(Rec, r) ->
'#set-r'(Vals, Rec).
'#fromlist-'(Vals, Rec) when is_record(Rec, r) ->
'#fromlist-r'(Vals, Rec).
'#fromlist-'(Vals, Rec) when is_record(Rec, r) ->
'#fromlist-r'(Vals, Rec).
'#new-r'() -> #r{}.
'#new-r'() -> #r{}.
'#new-r'(Vals) -> '#set-r'(Vals, #r{}).
'#new-r'(Vals) -> '#set-r'(Vals, #r{}).
'#get-r'(Attrs, R) when is_list(Attrs) ->
['#get-r'(A, R) || A <- Attrs];
'#get-r'(a, R) -> R#r.a;
'#get-r'(b, R) -> R#r.b;
'#get-r'(c, R) -> R#r.c;
'#get-r'(Attr, R) ->
erlang:error(bad_record_op, ['#get-r', Attr, R]).
'#get-r'(Attrs, R) when is_list(Attrs) ->
['#get-r'(A, R) || A <- Attrs];
'#get-r'(a, R) -> R#r.a;
'#get-r'(b, R) -> R#r.b;
'#get-r'(c, R) -> R#r.c;
'#get-r'(Attr, R) ->
erlang:error(bad_record_op, ['#get-r', Attr, R]).
'#set-r'(Vals, Rec) ->
F = fun ([], R, _F1) -> R;
([{a, V} | T], R, F1) -> F1(T, R#r{a = V}, F1);
([{b, V} | T], R, F1) -> F1(T, R#r{b = V}, F1);
([{c, V} | T], R, F1) -> F1(T, R#r{c = V}, F1);
(Vs, R, _) ->
erlang:error(bad_record_op, ['#set-r', Vs, R])
end,
F(Vals, Rec, F).
'#set-r'(Vals, Rec) ->
F = fun ([], R, _F1) -> R;
([{a, V} | T], R, F1) -> F1(T, R#r{a = V}, F1);
([{b, V} | T], R, F1) -> F1(T, R#r{b = V}, F1);
([{c, V} | T], R, F1) -> F1(T, R#r{c = V}, F1);
(Vs, R, _) ->
erlang:error(bad_record_op, ['#set-r', Vs, R])
end,
F(Vals, Rec, F).
'#fromlist-r'(Vals, Rec) ->
AttrNames = [{a, 2}, {b, 3}, {c, 4}],
F = fun ([], R, _F1) -> R;
([{H, Pos} | T], R, F1) ->
case lists:keyfind(H, 1, Vals) of
false -> F1(T, R, F1);
{_, Val} -> F1(T, setelement(Pos, R, Val), F1)
end
end,
F(AttrNames, Rec, F).
'#fromlist-r'(Vals, Rec) ->
AttrNames = [{a, 2}, {b, 3}, {c, 4}],
F = fun ([], R, _F1) -> R;
([{H, Pos} | T], R, F1) ->
case lists:keyfind(H, 1, Vals) of
false -> F1(T, R, F1);
{_, Val} -> F1(T, setelement(Pos, R, Val), F1)
end
end,
F(AttrNames, Rec, F).
'#pos-r'(a) -> 2;
'#pos-r'(b) -> 3;
'#pos-r'(c) -> 4;
'#pos-r'(_) -> 0.
'#pos-r'(a) -> 2;
'#pos-r'(b) -> 3;
'#pos-r'(c) -> 4;
'#pos-r'(_) -> 0.
'#info-r'(fields) -> record_info(fields, r);
'#info-r'(size) -> record_info(size, r).
</pre>
'#info-r'(fields) -> record_info(fields, r);
'#info-r'(size) -> record_info(size, r).
</pre>
<h2><a name="types">Data Types</a></h2>
<h3 class="typedecl"><a name="type-form">form()</a></h3>
<pre>form() = any()</pre>
<h3 class="typedecl"><a name="type-forms">forms()</a></h3>
<pre>forms() = [<a href="#type-form">form()</a>]</pre>
<h3 class="typedecl"><a name="type-options">options()</a></h3>
<pre>options() = [{atom(), any()}]</pre>
<h2><a name="index">Function Index</a></h2>
@ -125,23 +157,20 @@ F(AttrNames, Rec, F).
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#parse_transform-2">parse_transform/2</a></td><td></td></tr></table>
<a name="functions"></a>
<h2>Function Details</h2>
<h2><a name="functions">Function Details</a></h2>
<a name="parse_transform-2"></a>
<h3>parse_transform/2</h3>
`parse_transform(Forms, Options) -> any()`
<pre>parse_transform(Forms::<a href="#type-forms">forms()</a>, Options::<a href="#type-options">options()</a>) -> <a href="#type-forms">forms()</a></pre>
<br></br>
_Generated by EDoc, Nov 11 2010, 22:26:54._

View File

@ -5,6 +5,7 @@ Module parse_trans
<h1>Module parse_trans</h1>
* [Description](#description)
* [Data Types](#types)
* [Function Index](#index)
* [Function Details](#functions)
@ -24,6 +25,75 @@ __Authors:__ : Ulf Wiger ([`ulf.wiger@erlang-consulting.com`](mailto:ulf.wiger@e
...
<h2><a name="types">Data Types</a></h2>
<h3 class="typedecl"><a name="type-form">form()</a></h3>
<pre>form() = any()</pre>
<h3 class="typedecl"><a name="type-forms">forms()</a></h3>
<pre>forms() = [<a href="#type-form">form()</a>]</pre>
<h3 class="typedecl"><a name="type-insp_f">insp_f()</a></h3>
<pre>insp_f() = fun((<a href="#type-type">type()</a>, <a href="#type-form">form()</a>, #context{}, A) -> {boolean(), A})</pre>
<h3 class="typedecl"><a name="type-options">options()</a></h3>
<pre>options() = [{atom(), any()}]</pre>
<h3 class="typedecl"><a name="type-type">type()</a></h3>
<pre>type() = atom()</pre>
<h3 class="typedecl"><a name="type-xform_f_df">xform_f_df()</a></h3>
<pre>xform_f_df() = fun((<a href="#type-type">type()</a>, <a href="#type-form">form()</a>, #context{}, Acc) -> {<a href="#type-form">form()</a>, Acc} | {<a href="#type-forms">forms()</a>, <a href="#type-form">form()</a>, <a href="#type-forms">forms()</a>, Acc})</pre>
<h3 class="typedecl"><a name="type-xform_f_rec">xform_f_rec()</a></h3>
<pre>xform_f_rec() = fun((<a href="#type-type">type()</a>, <a href="#type-form">form()</a>, #context{}, Acc) -> {<a href="#type-form">form()</a>, boolean(), Acc} | {<a href="#type-forms">forms()</a>, <a href="#type-form">form()</a>, <a href="#type-forms">forms()</a>, boolean(), Acc})</pre>
<h2><a name="index">Function Index</a></h2>
@ -44,30 +114,26 @@ Erlang source code, storing it in the file Out.</td></tr><tr><td valign="top"><a
Makes one pass.</td></tr></table>
<a name="functions"></a>
<h2>Function Details</h2>
<h2><a name="functions">Function Details</a></h2>
<a name="context-2"></a>
<h3>context/2</h3>
<tt>context(X1::Attr, Context) -> any()</tt>* `Attr = module | function | arity | options`
<pre>context(X1::Attr, Context) -> any()</pre>
<ul class="definitions"><li><pre>Attr = module | function | arity | options</pre></li></ul>
Accessor function for the Context record.
<a name="depth_first-4"></a>
Accessor function for the Context record.<a name="depth_first-4"></a>
<h3>depth_first/4</h3>
@ -75,77 +141,75 @@ Accessor function for the Context record.
`depth_first(Fun, Acc, Forms, Options) -> any()`
<pre>depth_first(Fun::<a href="#type-xform_f_df">xform_f_df()</a>, Acc, Forms::<a href="#type-forms">forms()</a>, Options::<a href="#type-options">options()</a>) -> {<a href="#type-forms">forms()</a>, Acc} | {error, list()}</pre>
<br></br>
<a name="do_depth_first-4"></a>
<h3>do_depth_first/4</h3>
`do_depth_first(F, Acc, Forms, Context) -> any()`
<pre>do_depth_first(F::<a href="#type-xform_f_df">xform_f_df()</a>, Acc::term(), Forms::<a href="#type-forms">forms()</a>, Context::#context{}) -> {<a href="#type-forms">forms()</a>, term()}</pre>
<br></br>
<a name="do_insert_forms-4"></a>
<h3>do_insert_forms/4</h3>
`do_insert_forms(X1, Insert, Forms, Context) -> any()`
<pre>do_insert_forms(X1::above | below, Insert::<a href="#type-forms">forms()</a>, Forms::<a href="#type-forms">forms()</a>, Context::#context{}) -> <a href="#type-forms">forms()</a></pre>
<br></br>
<a name="do_inspect-4"></a>
<h3>do_inspect/4</h3>
`do_inspect(F, Acc, Forms, Context) -> any()`
<pre>do_inspect(F::<a href="#type-insp_f">insp_f()</a>, Acc::term(), Forms::<a href="#type-forms">forms()</a>, Context::#context{}) -> term()</pre>
<br></br>
<a name="do_transform-4"></a>
<h3>do_transform/4</h3>
`do_transform(F, Acc, Forms, Context) -> any()`
<pre>do_transform(F::<a href="#type-xform_f_rec">xform_f_rec()</a>, Acc::term(), Forms::<a href="#type-forms">forms()</a>, Context::#context{}) -> {<a href="#type-forms">forms()</a>, term()}</pre>
<br></br>
<a name="error-3"></a>
<h3>error/3</h3>
<tt>error(R::Reason, F::Form, I::Info) -> <a href="#type-throw">throw()</a></tt>* `Info = [{Key, Value}]`
<pre>error(R::Reason, F::Form, I::Info) -> <a href="#type-throw">throw()</a></pre>
<ul class="definitions"><li><pre>Info = [{Key, Value}]</pre></li></ul>
Used to report errors detected during the parse transform.
<a name="format_error-1"></a>
Used to report errors detected during the parse transform.<a name="format_error-1"></a>
<h3>format_error/1</h3>
@ -153,26 +217,26 @@ Used to report errors detected during the parse transform.
`format_error(X1) -> any()`
<pre>format_error(X1::{atom(), term()}) -> iolist()</pre>
<br></br>
<a name="function_exists-3"></a>
<h3>function_exists/3</h3>
<tt>function_exists(Fname::atom(), Arity::integer(), Forms) -> <a href="#type-boolean">boolean()</a></tt>
<pre>function_exists(Fname::atom(), Arity::integer(), Forms) -> boolean()</pre>
<br></br>
Checks whether the given function is defined in Forms.
<a name="get_attribute-2"></a>
Checks whether the given function is defined in Forms.<a name="get_attribute-2"></a>
<h3>get_attribute/2</h3>
@ -180,15 +244,13 @@ Checks whether the given function is defined in Forms.
<tt>get_attribute(A, Forms) -> any()</tt>* `A = atom()`
<pre>get_attribute(A, Forms) -> any()</pre>
<ul class="definitions"><li><pre>A = atom()</pre></li></ul>
Returns the value of the first occurence of attribute A.
<a name="get_file-1"></a>
Returns the value of the first occurence of attribute A.<a name="get_file-1"></a>
<h3>get_file/1</h3>
@ -196,14 +258,14 @@ Returns the value of the first occurence of attribute A.
<tt>get_file(Forms) -> string()</tt>
<pre>get_file(Forms) -> string()</pre>
<br></br>
Returns the name of the file being compiled.
<a name="get_module-1"></a>
Returns the name of the file being compiled.<a name="get_module-1"></a>
<h3>get_module/1</h3>
@ -211,14 +273,14 @@ Returns the name of the file being compiled.
<tt>get_module(Forms) -> atom()</tt>
<pre>get_module(Forms) -> atom()</pre>
<br></br>
Returns the name of the module being compiled.
<a name="get_orig_syntax_tree-1"></a>
Returns the name of the module being compiled.<a name="get_orig_syntax_tree-1"></a>
<h3>get_orig_syntax_tree/1</h3>
@ -226,7 +288,9 @@ Returns the name of the module being compiled.
<tt>get_orig_syntax_tree(File) -> Forms</tt>
<pre>get_orig_syntax_tree(File) -> Forms</pre>
<br></br>
@ -236,9 +300,7 @@ Returns the name of the module being compiled.
Fetches a Syntax Tree representing the code before pre-processing,
that is, including record and macro definitions. Note that macro
definitions must be syntactically complete forms (this function
uses epp_dodger).
<a name="get_pos-1"></a>
uses epp_dodger).<a name="get_pos-1"></a>
<h3>get_pos/1</h3>
@ -246,15 +308,15 @@ uses epp_dodger).
<tt>get_pos(I::list()) -> integer()</tt>
<pre>get_pos(I::list()) -> integer()</pre>
<br></br>
Tries to retrieve the line number from an erl_syntax form. Returns a
(very high) dummy number if not successful.
<a name="initial_context-2"></a>
(very high) dummy number if not successful.<a name="initial_context-2"></a>
<h3>initial_context/2</h3>
@ -262,7 +324,9 @@ Tries to retrieve the line number from an erl_syntax form. Returns a
<tt>initial_context(Forms, Options) -> #context{}</tt>
<pre>initial_context(Forms, Options) -> #context{}</pre>
<br></br>
@ -270,9 +334,7 @@ Tries to retrieve the line number from an erl_syntax form. Returns a
Initializes a context record. When traversing through the form
list, the context is updated to reflect the current function and
arity. Static elements in the context are the file name, the module
name and the options passed to the transform function.
<a name="inspect-4"></a>
name and the options passed to the transform function.<a name="inspect-4"></a>
<h3>inspect/4</h3>
@ -280,15 +342,13 @@ name and the options passed to the transform function.
<tt>inspect(F::Fun, Acc::Forms, Forms::Acc, Options) -> NewAcc</tt>* `Fun = function()`
<pre>inspect(F::Fun, Acc::Forms, Forms::Acc, Options) -> NewAcc</pre>
<ul class="definitions"><li><pre>Fun = function()</pre></li></ul>
Equvalent to do_inspect(Fun,Acc,Forms,initial_context(Forms,Options)).
<a name="optionally_pretty_print-3"></a>
Equvalent to do_inspect(Fun,Acc,Forms,initial_context(Forms,Options)).<a name="optionally_pretty_print-3"></a>
<h3>optionally_pretty_print/3</h3>
@ -296,27 +356,27 @@ Equvalent to do_inspect(Fun,Acc,Forms,initial_context(Forms,Options)).
`optionally_pretty_print(Result, Options, Context) -> any()`
<pre>optionally_pretty_print(Result::<a href="#type-forms">forms()</a>, Options::<a href="#type-options">options()</a>, Context::#context{}) -> ok</pre>
<br></br>
<a name="pp_beam-1"></a>
<h3>pp_beam/1</h3>
<tt>pp_beam(Beam::<a href="#type-filename">filename()</a>) -> string() | {error, Reason}</tt>
<pre>pp_beam(Beam::<a href="file.md#type-filename">file:filename()</a>) -> string() | {error, Reason}</pre>
<br></br>
Reads debug_info from the beam file Beam and returns a string containing
the pretty-printed corresponding erlang source code.
<a name="pp_beam-2"></a>
the pretty-printed corresponding erlang source code.<a name="pp_beam-2"></a>
<h3>pp_beam/2</h3>
@ -324,15 +384,15 @@ the pretty-printed corresponding erlang source code.
<tt>pp_beam(Beam::<a href="#type-filename">filename()</a>, Out::<a href="#type-filename">filename()</a>) -> ok | {error, Reason}</tt>
<pre>pp_beam(Beam::<a href="#type-filename">filename()</a>, Out::<a href="#type-filename">filename()</a>) -> ok | {error, Reason}</pre>
<br></br>
Reads debug_info from the beam file Beam and pretty-prints it as
Erlang source code, storing it in the file Out.
<a name="pp_src-2"></a>
Erlang source code, storing it in the file Out.<a name="pp_src-2"></a>
<h3>pp_src/2</h3>
@ -340,22 +400,24 @@ Erlang source code, storing it in the file Out.
<tt>pp_src(Res::Forms, Out::<a href="#type-filename">filename()</a>) -> ok</tt>
<pre>pp_src(Res::Forms, Out::<a href="#type-filename">filename()</a>) -> ok</pre>
<br></br>
Pretty-prints the erlang source code corresponding to Forms into Out
<a name="revert-1"></a>
<h3>revert/1</h3>
<tt>revert(Tree) -> Forms</tt>
<pre>revert(Tree) -> Forms</pre>
<br></br>
@ -364,9 +426,7 @@ Reverts back from Syntax Tools format to Erlang forms.
Note that the Erlang forms are a subset of the Syntax Tools
syntax tree, so this function is safe to call even on a list of
regular Erlang forms.
<a name="top-3"></a>
regular Erlang forms.<a name="top-3"></a>
<h3>top/3</h3>
@ -374,25 +434,22 @@ regular Erlang forms.
`top(F, Forms, Options) -> any()`
<pre>top(F::function(), Forms::<a href="#type-forms">forms()</a>, Options::list()) -> <a href="#type-forms">forms()</a> | {error, term()}</pre>
<br></br>
<a name="transform-4"></a>
<h3>transform/4</h3>
<tt>transform(Fun, Acc, Forms, Options) -> {TransformedForms, NewAcc}</tt>* `Fun = function()`
* `Options = [{Key, Value}]`
<pre>transform(Fun, Acc, Forms, Options) -> {TransformedForms, NewAcc}</pre>
<ul class="definitions"><li><pre>Fun = function()</pre></li><li><pre>Options = [{Key, Value}]</pre></li></ul>
Makes one pass
_Generated by EDoc, Nov 11 2010, 22:26:54._

View File

@ -34,22 +34,22 @@ and converts the corresponding erlang code to a data structure
representing the abstract form of that code.</td></tr></table>
<a name="functions"></a>
<h2>Function Details</h2>
<h2><a name="functions">Function Details</a></h2>
<a name="parse_transform-2"></a>
<h3>parse_transform/2</h3>
<tt>parse_transform(Forms, Options) -> NewForms</tt>
<pre>parse_transform(Forms, Options) -> NewForms</pre>
<br></br>
@ -137,21 +137,17 @@ bound at compile-time), using the construct `{'$var', V}`, where
`V` is a bound variable in the scope of the call to `gen_function/2`.
Example:
<pre>
gen(Name, X) ->
codegen:gen_function(Name, fun(L) -> lists:member({'$var',X}, L) end).
</pre>
gen(Name, X) ->
codegen:gen_function(Name, fun(L) -> lists:member({'$var',X}, L) end).
</pre>
After transformation, calling `gen(contains_17, 17)` will yield the
abstract form corresponding to:
<pre>
contains_17(L) ->
lists:member(17, L).
</pre>
contains_17(L) ->
lists:member(17, L).
</pre>
@ -166,20 +162,14 @@ It is possible to inject abstract forms, using the construct
the scope of the call to `gen_function/2`.
Example:
<pre>
gen(Name, F) ->
codegen:gen_function(Name, fun(X) -> X =:= {'$form',F} end).
</pre>
gen(Name, F) ->
codegen:gen_function(Name, fun(X) -> X =:= {'$form',F} end).
</pre>
After transformation, calling `gen(is_foo, {atom,0,foo})` will yield the
abstract form corresponding to:
<pre>
is_foo(X) ->
X =:= foo.
</pre>
_Generated by EDoc, Nov 11 2010, 22:26:54._
is_foo(X) ->
X =:= foo.
</pre>

View File

@ -27,11 +27,9 @@ The function `main/1` is called from escript, and can be used to
pretty-print debug info in a .beam file from a Linux shell.
Using e.g. the following bash alias:
<pre>
alias pp='escript $PARSE_TRANS_ROOT/ebin/parse_trans_pp.beam'
</pre>
alias pp='escript $PARSE_TRANS_ROOT/ebin/parse_trans_pp.beam'
</pre>
a file could be pretty-printed using the following command:
@ -49,42 +47,40 @@ Reads debug_info from the beam file Beam and pretty-prints it as
Erlang source code, storing it in the file Out.</td></tr><tr><td valign="top"><a href="#pp_src-2">pp_src/2</a></td><td>Pretty-prints the erlang source code corresponding to Forms into Out.</td></tr></table>
<a name="functions"></a>
<h2>Function Details</h2>
<h2><a name="functions">Function Details</a></h2>
<a name="main-1"></a>
<h3>main/1</h3>
`main(X1) -> any()`
<pre>main(X1::[string()]) -> any()</pre>
<br></br>
<a name="pp_beam-1"></a>
<h3>pp_beam/1</h3>
<tt>pp_beam(Beam::<a href="#type-filename">filename()</a>) -> string() | {error, Reason}</tt>
<pre>pp_beam(Beam::<a href="#type-filename">filename()</a>) -> string() | {error, Reason}</pre>
<br></br>
Reads debug_info from the beam file Beam and returns a string containing
the pretty-printed corresponding erlang source code.
<a name="pp_beam-2"></a>
the pretty-printed corresponding erlang source code.<a name="pp_beam-2"></a>
<h3>pp_beam/2</h3>
@ -92,15 +88,15 @@ the pretty-printed corresponding erlang source code.
<tt>pp_beam(Beam::<a href="#type-filename">filename()</a>, Out::<a href="#type-filename">filename()</a>) -> ok | {error, Reason}</tt>
<pre>pp_beam(Beam::<a href="#type-filename">filename()</a>, Out::<a href="#type-filename">filename()</a>) -> ok | {error, Reason}</pre>
<br></br>
Reads debug_info from the beam file Beam and pretty-prints it as
Erlang source code, storing it in the file Out.
<a name="pp_src-2"></a>
Erlang source code, storing it in the file Out.<a name="pp_src-2"></a>
<h3>pp_src/2</h3>
@ -108,11 +104,10 @@ Erlang source code, storing it in the file Out.
<tt>pp_src(Res::Forms, Out::<a href="#type-filename">filename()</a>) -> ok</tt>
<pre>pp_src(Res::Forms, Out::<a href="#type-filename">filename()</a>) -> ok</pre>
<br></br>
Pretty-prints the erlang source code corresponding to Forms into Out
_Generated by EDoc, Nov 11 2010, 22:26:54._

BIN
rebar vendored

Binary file not shown.

View File

@ -323,7 +323,7 @@ generate_accessors(L, Acc) ->
end, Acc#pass1.exports))] ++ version_accessors(L, Acc).
get_flds(Rname, #pass1{records = Rs}) ->
{value, {_, Flds}} = lists:keysearch(Rname, 1, Rs),
{_, Flds} = lists:keyfind(Rname, 1, Rs),
lists:map(
fun({record_field,_, {atom,_,N}}) -> N;
({record_field,_, {atom,_,N}, _}) -> N

View File

@ -60,7 +60,7 @@ main([F]) ->
%%
%% @doc Pretty-prints the erlang source code corresponding to Forms into Out
%%
-spec pp_src(parse_trans:forms(), filename:filename()) ->
-spec pp_src(parse_trans:forms(), file:filename()) ->
ok.
pp_src(Res, F) ->
Str = [io_lib:fwrite("~s~n",
@ -74,7 +74,7 @@ pp_src(Res, F) ->
%% Reads debug_info from the beam file Beam and returns a string containing
%% the pretty-printed corresponding erlang source code.
%% @end
-spec pp_beam(filename:filename()) -> ok | {error, any()}.
-spec pp_beam(file:filename()) -> ok | {error, any()}.
pp_beam(Beam) ->
case pp_beam_to_str(Beam) of
{ok, Str} ->
@ -90,7 +90,7 @@ pp_beam(Beam) ->
%% Erlang source code, storing it in the file Out.
%% @end
%%
-spec pp_beam(filename:filename(), filename:filename()) -> ok | {error,any()}.
-spec pp_beam(file:filename(), file:filename()) -> ok | {error,any()}.
pp_beam(F, Out) ->
case pp_beam_to_str(F) of
{ok, Str} ->

Binary file not shown.

View File

@ -1,37 +0,0 @@
%%% ----------------------------------------------------------------------------
%%% Copyright (c) 2009, Erlang Training and Consulting Ltd.
%%% All rights reserved.
%%%
%%% Redistribution and use in source and binary forms, with or without
%%% modification, are permitted provided that the following conditions are met:
%%% * Redistributions of source code must retain the above copyright
%%% notice, this list of conditions and the following disclaimer.
%%% * Redistributions in binary form must reproduce the above copyright
%%% notice, this list of conditions and the following disclaimer in the
%%% documentation and/or other materials provided with the distribution.
%%% * Neither the name of Erlang Training and Consulting Ltd. nor the
%%% names of its contributors may be used to endorse or promote products
%%% derived from this software without specific prior written permission.
%%%
%%% THIS SOFTWARE IS PROVIDED BY Erlang Training and Consulting Ltd. ''AS IS''
%%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
%%% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
%%% ARE DISCLAIMED. IN NO EVENT SHALL Erlang Training and Consulting Ltd. BE
%%% LIABLE SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
%%% BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
%%% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
%%% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
%%% ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
%%% ----------------------------------------------------------------------------
%%% @author Oscar Hellström <oscar@erlang-consulting.com>
-module(make_doc).
-export([edoc/0]).
edoc() ->
try
edoc:application(?THIS_APP, "./", [{doc, "doc/"}])
catch _:_ ->
halt(1)
end,
halt(0).

View File

@ -1,15 +0,0 @@
-module(make_plt).
-export([add/2]).
add(Apps, Plt) ->
Dirs = [filename:join(code:lib_dir(App), "ebin") || App <- Apps],
io:fwrite("generating custom plt file ~s~n", [Plt]),
dialyzer:run([{output_plt, Plt},
{analysis_type, plt_add},
{from, byte_code},
{erlang_mode, true},
{files_rec, Dirs}]),
io:fwrite("...done~n", []),
init:stop().

View File

@ -1,117 +0,0 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Copyright (c) 2009, Erlang Training and Consulting Ltd.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Erlang Training and Consulting Ltd. nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY Erlang Training and Consulting Ltd. ''AS IS''
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL Erlang Training and Consulting Ltd. BE
# LIABLE SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# ----------------------------------------------------------------------------
# Script for making a release of this app. Or any program in hg really. Check
# the Makefile target release for how to use it.
NAME=$1
VSN=$2
yesno() {
prompt=$1
while true; do
read -p "$1 [Y/n] " answer
case "x$answer" in
"x")
return 0
;;
"xY")
return 0
;;
"xy")
return 0
;;
"xN")
return 1
;;
"xn")
return 1
;;
*)
;;
esac
done
}
get_version() {
while true; do
read -p "What is the version of the release? [$VSN] " release_vsn
if [ "$release_vsn" = "" ]; then
release_vsn=$VSN
fi
if $(echo "$TAGS" | grep -q "^$release_vsn\$"); then
if yesno "A tag exists for version $release_vsn, is this correct?"; then
break
fi
else
if yesno "A tag doesn't exist for version $release_vsn, should one be created?"; then
hg tag $release_vsn
fi
break
fi
done
echo $release_vsn
}
if ! hg identify 1>/dev/null 2>&1; then
echo "No hg repository here..."
exit 1
fi
if ! [ "$(hg identify | awk '{print $2};')" = "tip" ]; then
if ! yesno "Repository is not at tip, do you want to continue?"; then
exit 1
fi
fi
if ! yesno "Did the compilation run without warnings?"; then
"Try again..."
exit 1
fi
if ! yesno "Is the changelog up to date?"; then
"Try again..."
exit 1
fi
if ! yesno "Did dialyzer run without warnings?"; then
"Try again..."
exit 1
fi
TAGS=$(hg tags | awk '{print $1 };' | grep -v "^tip$")
LATEST_TAG=$(echo "$TAGS" | head -n 1)
RELEASE_VSN=$(get_version)
echo "Creating a release for $NAME-$RELEASE_VSN now."
archive="./$NAME-$RELEASE_VSN.tar.gz"
if [ -e $archive ]; then
echo "$archive exists, giving up."
exit 1
fi
hg archive -t tgz -X ".hg*" $archive

View File

@ -1,123 +0,0 @@
%%% ----------------------------------------------------------------------------
%%% Copyright (c) 2009, Erlang Training and Consulting Ltd.
%%% All rights reserved.
%%%
%%% Redistribution and use in source and binary forms, with or without
%%% modification, are permitted provided that the following conditions are met:
%%% * Redistributions of source code must retain the above copyright
%%% notice, this list of conditions and the following disclaimer.
%%% * Redistributions in binary form must reproduce the above copyright
%%% notice, this list of conditions and the following disclaimer in the
%%% documentation and/or other materials provided with the distribution.
%%% * Neither the name of Erlang Training and Consulting Ltd. nor the
%%% names of its contributors may be used to endorse or promote products
%%% derived from this software without specific prior written permission.
%%%
%%% THIS SOFTWARE IS PROVIDED BY Erlang Training and Consulting Ltd. ''AS IS''
%%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
%%% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
%%% ARE DISCLAIMED. IN NO EVENT SHALL Erlang Training and Consulting Ltd. BE
%%% LIABLE SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
%%% BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
%%% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
%%% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
%%% ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
%%% ----------------------------------------------------------------------------
%%% @author Oscar Hellström <oscar@erlang-consulting.com>
-module(run_test).
-export([run/0]).
-include_lib("eunit/include/eunit.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
-define(TEST_LOG, "test/error_logger.log").
-define(SASL_LOG, "test/sasl.log").
-define(FILE_NAME(MODULE),
"cover_report/" ++ atom_to_list(MODULE) ++ ".html").
run() ->
Modules = get_modules(),
ok = cover_compile(Modules),
start_logging(),
Result = eunit:test(?MODULE, [verbose]),
filelib:ensure_dir("cover_report/index.html"),
html_report(Modules),
write_report(Modules),
stop_logging(),
io:format("Cover report in cover_report/index.html~n"),
io:format("Test logs in ~s and ~s~n", [?TEST_LOG, ?SASL_LOG]),
if
Result =:= ok -> halt(0);
Result =/= ok -> halt(1)
end.
start_logging() ->
application:load(sasl),
application:set_env(sasl, sasl_error_logger, {file, ?SASL_LOG}),
file:delete(?TEST_LOG),
file:delete(?SASL_LOG),
error_logger:tty(false),
error_logger:logfile({open, ?TEST_LOG}),
application:start(sasl).
stop_logging() ->
error_logger:logfile(close),
application:stop(sasl).
html_report([Module | Modules]) ->
cover:analyse_to_file(Module, ?FILE_NAME(Module), [html]),
html_report(Modules);
html_report([]) ->
ok.
write_report(Modules) ->
{TotalPercentage, ModulesPersentage} = percentage(Modules, 0, 0, []),
file:write_file("cover_report/index.html",
[
"<html>\n<head><title>Cover report index</title></head>\n"
"<body>\n"
"<h1>Cover report for ", atom_to_list(?THIS_APP), "</h1>"
"Total coverage: ", integer_to_list(TotalPercentage), "%"
"<h2>Cover for individual modules</h2>\n"
"<ul>\n\t",
lists:foldl(fun({Module, Percentage}, Acc) ->
Name = atom_to_list(Module),
[
"<li>"
"<a href=\"", Name ++ ".html" "\">",
Name,
"</a> ", integer_to_list(Percentage), "%"
"</li>\n\t" |
Acc
]
end, [], ModulesPersentage),
"</ul></body></html>"
]).
percentage([Module | Modules], TotCovered, TotLines, Percentages) ->
{ok, Analasys} = cover:analyse(Module, coverage, line),
{Covered, Lines} = lists:foldl(fun({_, {C, _}}, {Covered, Lines}) ->
{C + Covered, Lines + 1}
end, {0, 0}, Analasys),
Percent = (Covered * 100) div Lines,
NewPercentages = [{Module, Percent} | Percentages],
percentage(Modules, Covered + TotCovered, Lines + TotLines, NewPercentages);
percentage([], Covered, Lines, Percentages) ->
{(Covered * 100) div Lines, Percentages}.
get_modules() ->
application:load(?THIS_APP),
{ok, Modules} = application:get_key(?THIS_APP, modules),
Modules.
cover_compile([Module | Modules]) ->
{ok, Module} = cover:compile_beam(Module),
cover_compile(Modules);
cover_compile([]) ->
ok.
%%% Eunit functions
application_test_() ->
{application, ?THIS_APP}.