mirror of
https://github.com/valitydev/parse_trans.git
synced 2024-11-06 08:35:17 +00:00
re-generated docs
This commit is contained in:
parent
0a67c98cd1
commit
68a87e656c
13
README.md
13
README.md
@ -1,16 +1,3 @@
|
||||
|
||||
|
||||
# The parse_trans application #
|
||||
|
||||
|
||||
## Modules ##
|
||||
|
||||
|
||||
<table width="100%" border="0" summary="list of modules">
|
||||
<tr><td><a href="http://github.com/uwiger/parse_trans/blob/master/doc/ct_expand.md" class="module">ct_expand</a></td></tr>
|
||||
<tr><td><a href="http://github.com/uwiger/parse_trans/blob/master/doc/exprecs.md" class="module">exprecs</a></td></tr>
|
||||
<tr><td><a href="http://github.com/uwiger/parse_trans/blob/master/doc/parse_trans.md" class="module">parse_trans</a></td></tr>
|
||||
<tr><td><a href="http://github.com/uwiger/parse_trans/blob/master/doc/parse_trans_codegen.md" class="module">parse_trans_codegen</a></td></tr>
|
||||
<tr><td><a href="http://github.com/uwiger/parse_trans/blob/master/doc/parse_trans_mod.md" class="module">parse_trans_mod</a></td></tr>
|
||||
<tr><td><a href="http://github.com/uwiger/parse_trans/blob/master/doc/parse_trans_pp.md" class="module">parse_trans_pp</a></td></tr></table>
|
||||
|
||||
|
@ -1,16 +1,3 @@
|
||||
|
||||
|
||||
# The parse_trans application #
|
||||
|
||||
|
||||
## Modules ##
|
||||
|
||||
|
||||
<table width="100%" border="0" summary="list of modules">
|
||||
<tr><td><a href="ct_expand.md" class="module">ct_expand</a></td></tr>
|
||||
<tr><td><a href="exprecs.md" class="module">exprecs</a></td></tr>
|
||||
<tr><td><a href="parse_trans.md" class="module">parse_trans</a></td></tr>
|
||||
<tr><td><a href="parse_trans_codegen.md" class="module">parse_trans_codegen</a></td></tr>
|
||||
<tr><td><a href="parse_trans_mod.md" class="module">parse_trans_mod</a></td></tr>
|
||||
<tr><td><a href="parse_trans_pp.md" class="module">parse_trans_pp</a></td></tr></table>
|
||||
|
||||
|
@ -6,44 +6,32 @@
|
||||
* [Function Index](#index)
|
||||
* [Function Details](#functions)
|
||||
|
||||
|
||||
Compile-time expansion utility.
|
||||
|
||||
__Authors:__ : Ulf Wiger ([`ulf@feuerlabs.com`](mailto:ulf@feuerlabs.com)).
|
||||
|
||||
<a name="description"></a>
|
||||
|
||||
## Description ##
|
||||
|
||||
|
||||
|
||||
This module serves as an example of parse_trans-based transforms,
|
||||
but might also be a useful utility in its own right.
|
||||
The transform searches for calls to the pseudo-function
|
||||
`ct_expand:term(Expr)`, and then replaces the call site with the
|
||||
result of evaluating `Expr` at compile-time.
|
||||
|
||||
|
||||
|
||||
For example, the line
|
||||
|
||||
|
||||
|
||||
`ct_expand:term(lists:sort([3,5,2,1,4]))`
|
||||
|
||||
|
||||
|
||||
would be expanded at compile-time to `[1,2,3,4,5]`.
|
||||
|
||||
|
||||
|
||||
ct_expand has now been extended to also evaluate calls to local functions.
|
||||
See examples/ct_expand_test.erl for some examples.
|
||||
|
||||
|
||||
|
||||
A debugging facility exists: passing the option {ct_expand_trace, Flags} as an option,
|
||||
or adding a compiler attribute -ct_expand_trace(Flags) will enable a form of call trace.
|
||||
|
||||
|
||||
`Flags` can be `[]` (no trace) or `[F]`, where `F` is `c` (call trace),
|
||||
`r` (return trace), or `x` (exception trace)'.
|
||||
|
||||
@ -57,7 +45,6 @@ or adding a compiler attribute -ct_expand_trace(Flags) will enable a form of cal
|
||||
### <a name="type-form">form()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre><code>
|
||||
form() = any()
|
||||
</code></pre>
|
||||
@ -65,11 +52,9 @@ form() = any()
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="type-forms">forms()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre><code>
|
||||
forms() = [<a href="#type-form">form()</a>]
|
||||
</code></pre>
|
||||
@ -77,16 +62,13 @@ forms() = [<a href="#type-form">form()</a>]
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="type-options">options()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre><code>
|
||||
options() = [{atom(), any()}]
|
||||
</code></pre>
|
||||
|
||||
|
||||
<a name="index"></a>
|
||||
|
||||
## Function Index ##
|
||||
@ -105,22 +87,18 @@ options() = [{atom(), any()}]
|
||||
|
||||
`extract_fun(Name, Arity, Forms) -> any()`
|
||||
|
||||
|
||||
<a name="lfun_rewrite-2"></a>
|
||||
|
||||
### lfun_rewrite/2 ###
|
||||
|
||||
`lfun_rewrite(Exprs, Forms) -> any()`
|
||||
|
||||
|
||||
<a name="parse_transform-2"></a>
|
||||
|
||||
### parse_transform/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
parse_transform(Forms::<a href="#type-forms">forms()</a>, Options::<a href="#type-options">options()</a>) -> <a href="#type-forms">forms()</a>
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
%% encoding: UTF-8
|
||||
{application,parse_trans}.
|
||||
{packages,[]}.
|
||||
{modules,[ct_expand,exprecs,parse_trans,parse_trans_codegen,parse_trans_mod,
|
||||
parse_trans_pp]}.
|
||||
|
@ -6,9 +6,10 @@
|
||||
* [Function Index](#index)
|
||||
* [Function Details](#functions)
|
||||
|
||||
|
||||
Parse transform for generating record access functions.
|
||||
|
||||
__Authors:__ : Ulf Wiger ([`ulf@wiger.net`](mailto:ulf@wiger.net)).
|
||||
|
||||
<a name="description"></a>
|
||||
|
||||
## Description ##
|
||||
@ -16,54 +17,28 @@ __Authors:__ : Ulf Wiger ([`ulf@wiger.net`](mailto:ulf@wiger.net)).
|
||||
This parse transform can be used to reduce compile-time
|
||||
dependencies in large systems.
|
||||
|
||||
|
||||
In the old days, before records, Erlang programmers often wrote
|
||||
access functions for tuple data. This was tedious and error-prone.
|
||||
The record syntax made this easier, but since records were implemented
|
||||
fully in the pre-processor, a nasty compile-time dependency was
|
||||
introduced.
|
||||
|
||||
|
||||
This module automates the generation of access functions for
|
||||
records. While this method cannot fully replace the utility of
|
||||
pattern matching, it does allow a fair bit of functionality on
|
||||
records without the need for compile-time dependencies.
|
||||
|
||||
|
||||
Whenever record definitions need to be exported from a module,
|
||||
inserting a compiler attribute,
|
||||
`export_records([RecName|...])` causes this transform
|
||||
to lay out access functions for the exported records:
|
||||
|
||||
|
||||
As an example, consider the following module:
|
||||
|
||||
```
|
||||
```erlang
|
||||
|
||||
-module(test_exprecs).
|
||||
-export([f/0]).
|
||||
-compile({parse_transform, exprecs}).
|
||||
-record(r, {a = 0 :: integer(),
|
||||
b = 0 :: integer(),
|
||||
c = 0 :: integer()}).
|
||||
-record(s,{a}).
|
||||
-export_records([r,s]).
|
||||
f() ->
|
||||
{new,'#new-r'([])}.
|
||||
```
|
||||
|
||||
|
||||
|
||||
Compiling this (assuming exprecs is in the path) will produce the
|
||||
following code.
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
-module(test_exprecs).
|
||||
-compile({pt_pp_src,true}).
|
||||
-export([f/0]).
|
||||
-record(r,{a = 0 :: integer(),b = 0 :: integer(),c = 0 :: integer()}).
|
||||
-record(s,{a}).
|
||||
-export_records([r,s]).
|
||||
@ -96,6 +71,7 @@ following code.
|
||||
'#fromlist-s'/2,
|
||||
'#info-s'/1,
|
||||
'#lens-s'/1]).
|
||||
-export_type(['#prop-r'/0,'#attr-r'/0,'#prop-s'/0,'#attr-s'/0]).
|
||||
-type '#prop-r'() :: {a, integer()} | {b, integer()} | {c, integer()}.
|
||||
-type '#attr-r'() :: a | b | c.
|
||||
-type '#prop-s'() :: {a, any()}.
|
||||
@ -109,14 +85,14 @@ following code.
|
||||
'#new-r'();
|
||||
'#new-'(s) ->
|
||||
'#new-s'().
|
||||
-spec '#info-'(r) -> [a | b | c];
|
||||
(s) -> [a].
|
||||
-spec '#info-'(r) -> ['#attr-r'()];
|
||||
(s) -> ['#attr-s'()].
|
||||
'#info-'(RecName) ->
|
||||
'#info-'(RecName, fields).
|
||||
-spec '#info-'(r, size) -> 4;
|
||||
(r, fields) -> [a | b | c];
|
||||
(r, fields) -> ['#attr-r'()];
|
||||
(s, size) -> 2;
|
||||
(s, fields) -> [a].
|
||||
(s, fields) -> ['#attr-s'()].
|
||||
'#info-'(r, Info) ->
|
||||
'#info-r'(Info);
|
||||
'#info-'(s, Info) ->
|
||||
@ -150,7 +126,8 @@ following code.
|
||||
(b, #r{}) -> integer();
|
||||
(c, #r{}) -> integer();
|
||||
(a, #s{}) -> any();
|
||||
(['#attr-r'()], #r{}) -> [integer()];
|
||||
(['#attr-r'()], #r{}) ->
|
||||
[integer() | integer() | integer()];
|
||||
(['#attr-s'()], #s{}) -> [any()].
|
||||
'#get-'(Attrs, Rec) when is_record(Rec, r) ->
|
||||
'#get-r'(Attrs, Rec);
|
||||
@ -168,9 +145,9 @@ following code.
|
||||
'#fromlist-r'(Vals, Rec);
|
||||
'#fromlist-'(Vals, Rec) when is_record(Rec, s) ->
|
||||
'#fromlist-s'(Vals, Rec).
|
||||
-spec '#lens-'('#prop-r'(), r) ->
|
||||
-spec '#lens-'('#attr-r'(), r) ->
|
||||
{fun((#r{}) -> any()), fun((any(), #r{}) -> #r{})};
|
||||
('#prop-s'(), s) ->
|
||||
('#attr-s'(), s) ->
|
||||
{fun((#s{}) -> any()), fun((any(), #s{}) -> #s{})}.
|
||||
'#lens-'(Attr, r) ->
|
||||
'#lens-r'(Attr);
|
||||
@ -185,7 +162,7 @@ following code.
|
||||
-spec '#get-r'(a, #r{}) -> integer();
|
||||
(b, #r{}) -> integer();
|
||||
(c, #r{}) -> integer();
|
||||
(['#attr-r'()], #r{}) -> [integer()].
|
||||
(['#attr-r'()], #r{}) -> [any()].
|
||||
'#get-r'(Attrs, R) when is_list(Attrs) ->
|
||||
[
|
||||
'#get-r'(A, R) ||
|
||||
@ -240,12 +217,12 @@ following code.
|
||||
'#pos-r'(A) when is_atom(A) ->
|
||||
0.
|
||||
-spec '#info-r'(fields) -> [a | b | c];
|
||||
(size) -> 3.
|
||||
(size) -> 4.
|
||||
'#info-r'(fields) ->
|
||||
record_info(fields, r);
|
||||
'#info-r'(size) ->
|
||||
record_info(size, r).
|
||||
-spec '#lens-r'('#prop-r'()) ->
|
||||
-spec '#lens-r'('#attr-r'()) ->
|
||||
{fun((#r{}) -> any()), fun((any(), #r{}) -> #r{})}.
|
||||
'#lens-r'(a) ->
|
||||
{fun(R) ->
|
||||
@ -320,12 +297,12 @@ following code.
|
||||
'#pos-s'(A) when is_atom(A) ->
|
||||
0.
|
||||
-spec '#info-s'(fields) -> [a];
|
||||
(size) -> 1.
|
||||
(size) -> 2.
|
||||
'#info-s'(fields) ->
|
||||
record_info(fields, s);
|
||||
'#info-s'(size) ->
|
||||
record_info(size, s).
|
||||
-spec '#lens-s'('#prop-s'()) ->
|
||||
-spec '#lens-s'('#attr-s'()) ->
|
||||
{fun((#s{}) -> any()), fun((any(), #s{}) -> #s{})}.
|
||||
'#lens-s'(a) ->
|
||||
{fun(R) ->
|
||||
@ -340,13 +317,9 @@ following code.
|
||||
{new,'#new-r'([])}.
|
||||
```
|
||||
|
||||
|
||||
|
||||
It is possible to modify the naming rules of exprecs, through the use
|
||||
of the following attributes (example reflecting the current rules):
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
-exprecs_prefix(["#", operation, "-"]).
|
||||
@ -354,7 +327,6 @@ of the following attributes (example reflecting the current rules):
|
||||
-exprecs_vfname([fname, "__", version]).
|
||||
```
|
||||
|
||||
|
||||
The lists must contain strings or any of the following control atoms:
|
||||
|
||||
* in `exprecs_prefix`: `operation`
|
||||
@ -364,13 +336,10 @@ The lists must contain strings or any of the following control atoms:
|
||||
* in `exprecs_vfname`: `operation`, `record`, `prefix`, `fname`, `version`
|
||||
|
||||
|
||||
|
||||
|
||||
Exprecs will substitute the control atoms with the string values of the
|
||||
corresponding items. The result will then be flattened and converted to an
|
||||
atom (a valid function or type name).
|
||||
|
||||
|
||||
`operation` is one of:
|
||||
|
||||
|
||||
@ -485,7 +454,6 @@ atom (a valid function or type name).
|
||||
### <a name="type-form">form()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre><code>
|
||||
form() = any()
|
||||
</code></pre>
|
||||
@ -493,11 +461,9 @@ form() = any()
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="type-forms">forms()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre><code>
|
||||
forms() = [<a href="#type-form">form()</a>]
|
||||
</code></pre>
|
||||
@ -505,16 +471,13 @@ forms() = [<a href="#type-form">form()</a>]
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="type-options">options()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre><code>
|
||||
options() = [{atom(), any()}]
|
||||
</code></pre>
|
||||
|
||||
|
||||
<a name="index"></a>
|
||||
|
||||
## Function Index ##
|
||||
@ -531,10 +494,8 @@ options() = [{atom(), any()}]
|
||||
|
||||
### parse_transform/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
parse_transform(Forms::<a href="#type-forms">forms()</a>, Options::<a href="#type-options">options()</a>) -> <a href="#type-forms">forms()</a>
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
|
@ -6,15 +6,14 @@
|
||||
* [Function Index](#index)
|
||||
* [Function Details](#functions)
|
||||
|
||||
|
||||
Generic parse transform library for Erlang.
|
||||
|
||||
__Authors:__ : Ulf Wiger ([`ulf.wiger@feuerlabs.com`](mailto:ulf.wiger@feuerlabs.com)).
|
||||
|
||||
<a name="description"></a>
|
||||
|
||||
## Description ##
|
||||
|
||||
|
||||
|
||||
...
|
||||
|
||||
|
||||
@ -28,7 +27,6 @@ __Authors:__ : Ulf Wiger ([`ulf.wiger@feuerlabs.com`](mailto:ulf.wiger@feuerlabs
|
||||
### <a name="type-form">form()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre><code>
|
||||
form() = any()
|
||||
</code></pre>
|
||||
@ -36,11 +34,9 @@ form() = any()
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="type-forms">forms()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre><code>
|
||||
forms() = [<a href="#type-form">form()</a>]
|
||||
</code></pre>
|
||||
@ -48,11 +44,9 @@ forms() = [<a href="#type-form">form()</a>]
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="type-insp_f">insp_f()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre><code>
|
||||
insp_f() = fun((<a href="#type-type">type()</a>, <a href="#type-form">form()</a>, #context{}, A) -> {boolean(), A})
|
||||
</code></pre>
|
||||
@ -60,11 +54,9 @@ insp_f() = fun((<a href="#type-type">type()</a>, <a href="#type-form">form()</a>
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="type-options">options()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre><code>
|
||||
options() = [{atom(), any()}]
|
||||
</code></pre>
|
||||
@ -72,11 +64,9 @@ options() = [{atom(), any()}]
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="type-type">type()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre><code>
|
||||
type() = atom()
|
||||
</code></pre>
|
||||
@ -84,11 +74,9 @@ type() = atom()
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="type-xform_f_df">xform_f_df()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre><code>
|
||||
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})
|
||||
</code></pre>
|
||||
@ -96,16 +84,13 @@ xform_f_df() = fun((<a href="#type-type">type()</a>, <a href="#type-form">form()
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="type-xform_f_rec">xform_f_rec()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre><code>
|
||||
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})
|
||||
</code></pre>
|
||||
|
||||
|
||||
<a name="index"></a>
|
||||
|
||||
## Function Index ##
|
||||
@ -136,83 +121,69 @@ Makes one pass.</td></tr></table>
|
||||
|
||||
### context/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
context(X1::Attr, Context) -> any()
|
||||
</code></pre>
|
||||
|
||||
<ul class="definitions"><li><code>Attr = module | function | arity | options</code></li></ul>
|
||||
|
||||
|
||||
Accessor function for the Context record.
|
||||
|
||||
<a name="depth_first-4"></a>
|
||||
|
||||
### depth_first/4 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
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()}
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="do_depth_first-4"></a>
|
||||
|
||||
### do_depth_first/4 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
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()}
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="do_insert_forms-4"></a>
|
||||
|
||||
### do_insert_forms/4 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
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>
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="do_inspect-4"></a>
|
||||
|
||||
### do_inspect/4 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
do_inspect(F::<a href="#type-insp_f">insp_f()</a>, Acc::term(), Forms::<a href="#type-forms">forms()</a>, Context::#context{}) -> term()
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="do_transform-4"></a>
|
||||
|
||||
### do_transform/4 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
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()}
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="error-3"></a>
|
||||
|
||||
### error/3 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
error(R::Reason, F::Form, I::Info) -> <a href="#type-throw">throw()</a>
|
||||
</code></pre>
|
||||
|
||||
<ul class="definitions"><li><code>Info = [{Key, Value}]</code></li></ul>
|
||||
|
||||
|
||||
|
||||
Used to report errors detected during the parse transform.
|
||||
|
||||
<a name="export_function-3"></a>
|
||||
@ -221,121 +192,106 @@ Used to report errors detected during the parse transform.
|
||||
|
||||
`export_function(F, Arity, Forms) -> any()`
|
||||
|
||||
|
||||
<a name="format_error-1"></a>
|
||||
|
||||
### format_error/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
format_error(Error::{atom(), term()}) -> iolist()
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="format_exception-2"></a>
|
||||
|
||||
### format_exception/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
format_exception(Class, Reason) -> String
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
Equivalent to [`format_exception(Class, Reason, 4)`](#format_exception-3).
|
||||
|
||||
<a name="format_exception-3"></a>
|
||||
|
||||
### format_exception/3 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
format_exception(Class, Reason, Lines) -> String
|
||||
</code></pre>
|
||||
|
||||
<ul class="definitions"><li><code>Class = error | throw | exit</code></li><li><code>Reason = term()</code></li><li><code>Lines = integer() | infinity</code></li></ul>
|
||||
|
||||
|
||||
Produces a few lines of user-friendly formatting of exception info
|
||||
|
||||
|
||||
|
||||
This function is very similar to the exception pretty-printing in the shell,
|
||||
but returns a string that can be used as error info e.g. by error forms
|
||||
handled by [`return/2`](#return-2). By default, the first 4 lines of the
|
||||
pretty-printed exception info are returned, but this can be controlled
|
||||
with the `Lines` parameter.
|
||||
|
||||
|
||||
Note that a stacktrace is generated inside this function.
|
||||
|
||||
<a name="function_exists-3"></a>
|
||||
|
||||
### function_exists/3 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
function_exists(Fname::atom(), Arity::integer(), Forms) -> boolean()
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
Checks whether the given function is defined in Forms.
|
||||
|
||||
<a name="get_attribute-2"></a>
|
||||
|
||||
### get_attribute/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
get_attribute(A, Forms) -> any()
|
||||
</code></pre>
|
||||
|
||||
<ul class="definitions"><li><code>A = atom()</code></li></ul>
|
||||
|
||||
|
||||
Returns the value of the first occurence of attribute A.
|
||||
|
||||
<a name="get_attribute-3"></a>
|
||||
|
||||
### get_attribute/3 ###
|
||||
|
||||
`get_attribute(A, Forms, Undef) -> any()`
|
||||
|
||||
|
||||
<a name="get_file-1"></a>
|
||||
|
||||
### get_file/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
get_file(Forms) -> string()
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
Returns the name of the file being compiled.
|
||||
|
||||
<a name="get_module-1"></a>
|
||||
|
||||
### get_module/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
get_module(Forms) -> atom()
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
Returns the name of the module being compiled.
|
||||
|
||||
<a name="get_orig_syntax_tree-1"></a>
|
||||
|
||||
### get_orig_syntax_tree/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
get_orig_syntax_tree(File) -> Forms
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
|
||||
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
|
||||
@ -345,86 +301,73 @@ uses epp_dodger).
|
||||
|
||||
### get_pos/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
get_pos(I::list()) -> integer()
|
||||
</code></pre>
|
||||
<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>
|
||||
|
||||
### initial_context/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
initial_context(Forms, Options) -> #context{}
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
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>
|
||||
|
||||
### inspect/4 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
inspect(F::Fun, Acc::Forms, Forms::Acc, Options) -> NewAcc
|
||||
</code></pre>
|
||||
|
||||
<ul class="definitions"><li><code>Fun = function()</code></li></ul>
|
||||
|
||||
|
||||
Equvalent to do_inspect(Fun,Acc,Forms,initial_context(Forms,Options)).
|
||||
|
||||
<a name="optionally_pretty_print-3"></a>
|
||||
|
||||
### optionally_pretty_print/3 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
optionally_pretty_print(Result::<a href="#type-forms">forms()</a>, Options::<a href="#type-options">options()</a>, Context::#context{}) -> ok
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="plain_transform-2"></a>
|
||||
|
||||
### plain_transform/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
plain_transform(Fun, Forms) -> <a href="#type-forms">forms()</a>
|
||||
</code></pre>
|
||||
|
||||
<ul class="definitions"><li><code>Fun = function()</code></li><li><code>Forms = <a href="#type-forms">forms()</a></code></li></ul>
|
||||
|
||||
|
||||
|
||||
Performs a transform of `Forms` using the fun `Fun(Form)`. `Form` is always
|
||||
an Erlang abstract form, i.e. it is not converted to syntax_tools
|
||||
representation. The intention of this transform is for the fun to have a
|
||||
catch-all clause returning `continue`. This will ensure that it stays robust
|
||||
against additions to the language.
|
||||
|
||||
|
||||
|
||||
`Fun(Form)` must return either of the following:
|
||||
|
||||
|
||||
|
||||
* `NewForm` - any valid form
|
||||
* `continue` - dig into the sub-expressions of the form
|
||||
* `{done, NewForm}` - Replace `Form` with `NewForm`; return all following
|
||||
forms unchanged
|
||||
* `{error, Reason}` - Abort transformation with an error message.
|
||||
|
||||
|
||||
Example - This transform fun would convert all instances of `P ! Msg` to
|
||||
`gproc:send(P, Msg)`:
|
||||
|
||||
@ -445,33 +388,30 @@ Example - This transform fun would convert all instances of `P ! Msg` to
|
||||
|
||||
### pp_beam/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
pp_beam(Beam::<a href="file.md#type-filename">file:filename()</a>) -> string() | {error, Reason}
|
||||
</code></pre>
|
||||
<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>
|
||||
|
||||
### pp_beam/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
pp_beam(Beam::<a href="#type-filename">filename()</a>, Out::<a href="#type-filename">filename()</a>) -> ok | {error, Reason}
|
||||
</code></pre>
|
||||
<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>
|
||||
|
||||
### pp_src/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
pp_src(Res::Forms, Out::<a href="#type-filename">filename()</a>) -> ok
|
||||
</code></pre>
|
||||
@ -485,19 +425,16 @@ Pretty-prints the erlang source code corresponding to Forms into Out
|
||||
|
||||
`replace_function(F, Arity, NewForm, Forms) -> any()`
|
||||
|
||||
|
||||
<a name="replace_function-5"></a>
|
||||
|
||||
### replace_function/5 ###
|
||||
|
||||
`replace_function(F, Arity, NewForm, Forms, Opts) -> any()`
|
||||
|
||||
|
||||
<a name="return-2"></a>
|
||||
|
||||
### return/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
return(Forms, Context) -> Forms | {error, Es, Ws} | {warnings, Forms, Ws}
|
||||
</code></pre>
|
||||
@ -511,7 +448,6 @@ a bit of care. The easiest way is to simply produce an `{error, Err}` or
|
||||
removes them from the form list (otherwise, the linter will crash), and
|
||||
produces a return value that the compiler can work with.
|
||||
|
||||
|
||||
The format of the `error` and `warning` "forms" must be
|
||||
`{Tag, {Pos, Module, Info}}`, where:
|
||||
|
||||
@ -533,7 +469,6 @@ using the function [`format_exception/2`](#format_exception-2).
|
||||
|
||||
### revert/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
revert(Tree) -> Forms
|
||||
</code></pre>
|
||||
@ -545,7 +480,6 @@ 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.
|
||||
|
||||
|
||||
Note2: R16B03 introduced a bug, where forms produced by
|
||||
`erl_syntax:revert/1` (specifically, implicit funs) could crash the linter.
|
||||
This function works around that limitation, after first verifying that it's
|
||||
@ -557,7 +491,6 @@ variable will be removed when R16B03 is no longer 'supported'.
|
||||
|
||||
### revert_form/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
revert_form(F::Tree) -> Form
|
||||
</code></pre>
|
||||
@ -569,12 +502,10 @@ Reverts a single form back from Syntax Tools format to Erlang forms.
|
||||
completely revert attribute forms. This function deals properly with those
|
||||
cases.
|
||||
|
||||
|
||||
Note that the Erlang forms are a subset of the Syntax Tools
|
||||
syntax tree, so this function is safe to call even on a regular Erlang
|
||||
form.
|
||||
|
||||
|
||||
Note2: R16B03 introduced a bug, where forms produced by
|
||||
`erl_syntax:revert/1` (specifically, implicit funs) could crash the linter.
|
||||
This function works around that limitation, after first verifying that it's
|
||||
@ -586,23 +517,20 @@ variable will be removed when R16B03 is no longer 'supported'.
|
||||
|
||||
### top/3 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
top(F::function(), Forms::<a href="#type-forms">forms()</a>, Options::list()) -> <a href="#type-forms">forms()</a> | {error, term()}
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="transform-4"></a>
|
||||
|
||||
### transform/4 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
transform(Fun, Acc, Forms, Options) -> {TransformedForms, NewAcc}
|
||||
</code></pre>
|
||||
|
||||
<ul class="definitions"><li><code>Fun = function()</code></li><li><code>Options = [{Key, Value}]</code></li></ul>
|
||||
|
||||
|
||||
Makes one pass
|
||||
|
||||
|
@ -5,15 +5,14 @@
|
||||
* [Function Index](#index)
|
||||
* [Function Details](#functions)
|
||||
|
||||
|
||||
Parse transform for code generation pseduo functions.
|
||||
|
||||
__Authors:__ : Ulf Wiger ([`ulf@feuerlabs.com`](mailto:ulf@feuerlabs.com)).
|
||||
|
||||
<a name="description"></a>
|
||||
|
||||
## Description ##
|
||||
|
||||
|
||||
|
||||
...
|
||||
|
||||
<a name="index"></a>
|
||||
@ -37,57 +36,40 @@ representing the abstract form of that code.</td></tr></table>
|
||||
|
||||
`format_error(E) -> any()`
|
||||
|
||||
|
||||
<a name="parse_transform-2"></a>
|
||||
|
||||
### parse_transform/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
parse_transform(Forms, Options) -> NewForms
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
|
||||
Searches for calls to pseudo functions in the module `codegen`,
|
||||
and converts the corresponding erlang code to a data structure
|
||||
representing the abstract form of that code.
|
||||
|
||||
|
||||
|
||||
The purpose of these functions is to let the programmer write
|
||||
the actual code that is to be generated, rather than manually
|
||||
writing abstract forms, which is more error prone and cannot be
|
||||
checked by the compiler until the generated module is compiled.
|
||||
|
||||
|
||||
|
||||
Supported functions:
|
||||
|
||||
|
||||
|
||||
|
||||
## gen_function/2 ##
|
||||
|
||||
|
||||
|
||||
Usage: `codegen:gen_function(Name, Fun)`
|
||||
|
||||
|
||||
|
||||
Substitutes the abstract code for a function with name `Name`
|
||||
and the same behaviour as `Fun`.
|
||||
|
||||
|
||||
`Fun` can either be a anonymous `fun`, which is then converted to
|
||||
a named function, or it can be an `implicit fun`, e.g.
|
||||
`fun is_member/2`. In the latter case, the referenced function is fetched
|
||||
and converted to an abstract form representation. It is also renamed
|
||||
so that the generated function has the name `Name`.
|
||||
|
||||
|
||||
|
||||
Another alternative is to wrap a fun inside a list comprehension, e.g.
|
||||
|
||||
```
|
||||
@ -101,8 +83,6 @@ Another alternative is to wrap a fun inside a list comprehension, e.g.
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
Calling the above with `f(foo, [{1,a},{2,b},{3,c}])` will result in
|
||||
generated code corresponding to:
|
||||
|
||||
@ -114,27 +94,17 @@ generated code corresponding to:
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## gen_functions/1 ##
|
||||
|
||||
|
||||
|
||||
Takes a list of `{Name, Fun}` tuples and produces a list of abstract
|
||||
data objects, just as if one had written
|
||||
`[codegen:gen_function(N1,F1),codegen:gen_function(N2,F2),...]`.
|
||||
|
||||
|
||||
|
||||
|
||||
## exprs/1 ##
|
||||
|
||||
|
||||
|
||||
Usage: `codegen:exprs(Fun)`
|
||||
|
||||
|
||||
|
||||
`Fun` is either an anonymous function, or an implicit fun with only one
|
||||
function clause. This "function" takes the body of the fun and produces
|
||||
a data type representing the abstract form of the list of expressions in
|
||||
@ -142,43 +112,26 @@ the body. The arguments of the function clause are ignored, but can be
|
||||
used to ensure that all necessary variables are known to the compiler.
|
||||
|
||||
|
||||
|
||||
|
||||
## gen_module/3 ##
|
||||
|
||||
|
||||
|
||||
Generates abstract forms for a complete module definition.
|
||||
|
||||
|
||||
|
||||
Usage: `codegen:gen_module(ModuleName, Exports, Functions)`
|
||||
|
||||
|
||||
|
||||
`ModuleName` is either an atom or a `{'$var', V}` reference.
|
||||
|
||||
|
||||
|
||||
`Exports` is a list of `{Function, Arity}` tuples.
|
||||
|
||||
|
||||
|
||||
`Functions` is a list of `{Name, Fun}` tuples analogous to that for
|
||||
`gen_functions/1`.
|
||||
|
||||
|
||||
|
||||
|
||||
## Variable substitution ##
|
||||
|
||||
|
||||
|
||||
It is possible to do some limited expansion (importing a value
|
||||
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:
|
||||
|
||||
```
|
||||
@ -187,7 +140,6 @@ Example:
|
||||
codegen:gen_function(Name, fun(L) -> lists:member({'$var',X}, L) end).
|
||||
```
|
||||
|
||||
|
||||
After transformation, calling `gen(contains_17, 17)` will yield the
|
||||
abstract form corresponding to:
|
||||
|
||||
@ -198,17 +150,12 @@ abstract form corresponding to:
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## Form substitution ##
|
||||
|
||||
|
||||
|
||||
It is possible to inject abstract forms, using the construct
|
||||
`{'$form', F}`, where `F` is bound to a parsed form in
|
||||
the scope of the call to `gen_function/2`.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
@ -217,7 +164,6 @@ Example:
|
||||
codegen:gen_function(Name, fun(X) -> X =:= {'$form',F} end).
|
||||
```
|
||||
|
||||
|
||||
After transformation, calling `gen(is_foo, {atom,0,foo})` will yield the
|
||||
abstract form corresponding to:
|
||||
|
||||
|
@ -5,8 +5,6 @@
|
||||
* [Function Index](#index)
|
||||
* [Function Details](#functions)
|
||||
|
||||
|
||||
|
||||
<a name="types"></a>
|
||||
|
||||
## Data Types ##
|
||||
@ -17,7 +15,6 @@
|
||||
### <a name="type-compile_options">compile_options()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre><code>
|
||||
compile_options() = [term()]
|
||||
</code></pre>
|
||||
@ -25,16 +22,13 @@ compile_options() = [term()]
|
||||
|
||||
|
||||
|
||||
|
||||
### <a name="type-erlang_form">erlang_form()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre><code>
|
||||
erlang_form() = term()
|
||||
</code></pre>
|
||||
|
||||
|
||||
<a name="index"></a>
|
||||
|
||||
## Function Index ##
|
||||
@ -51,72 +45,59 @@ erlang_form() = term()
|
||||
|
||||
### abstract_code/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
abstract_code(BeamFile::binary()) -> <a href="#type-erlang_form">erlang_form()</a>
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="beam_file-1"></a>
|
||||
|
||||
### beam_file/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
beam_file(Module::module()) -> binary()
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="compile_and_load_forms-1"></a>
|
||||
|
||||
### compile_and_load_forms/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
compile_and_load_forms(AbsCode::<a href="#type-erlang_form">erlang_form()</a>) -> ok
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="compile_and_load_forms-2"></a>
|
||||
|
||||
### compile_and_load_forms/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
compile_and_load_forms(AbsCode::<a href="#type-erlang_form">erlang_form()</a>, Opts::<a href="#type-compile_options">compile_options()</a>) -> ok
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="compile_options-1"></a>
|
||||
|
||||
### compile_options/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
compile_options(BeamFile::binary() | module()) -> <a href="#type-compile_options">compile_options()</a>
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="rename_module-2"></a>
|
||||
|
||||
### rename_module/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
rename_module(T::<a href="#type-erlang_form">erlang_form()</a>, NewName::module()) -> <a href="#type-erlang_form">erlang_form()</a>
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="transform_module-3"></a>
|
||||
|
||||
### transform_module/3 ###
|
||||
|
||||
`transform_module(Mod, PT, Options) -> any()`
|
||||
|
||||
|
||||
|
@ -5,21 +5,19 @@
|
||||
* [Function Index](#index)
|
||||
* [Function Details](#functions)
|
||||
|
||||
|
||||
Generic parse transform library for Erlang.
|
||||
|
||||
__Authors:__ : Ulf Wiger ([`ulf@feuerlabs.com`](mailto:ulf@feuerlabs.com)).
|
||||
|
||||
<a name="description"></a>
|
||||
|
||||
## Description ##
|
||||
|
||||
|
||||
|
||||
This module contains some useful utility functions for inspecting
|
||||
the results of parse transforms or code generation.
|
||||
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:
|
||||
|
||||
```
|
||||
@ -27,10 +25,8 @@ Using e.g. the following bash alias:
|
||||
alias pp='escript $PARSE_TRANS_ROOT/ebin/parse_trans_pp.beam'
|
||||
```
|
||||
|
||||
|
||||
a file could be pretty-printed using the following command:
|
||||
|
||||
|
||||
`$ pp ex_codegen.beam | less`<a name="index"></a>
|
||||
|
||||
## Function Index ##
|
||||
@ -51,44 +47,39 @@ Erlang source code, storing it in the file Out.</td></tr><tr><td valign="top"><a
|
||||
|
||||
### main/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
main(X1::[string()]) -> any()
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="pp_beam-1"></a>
|
||||
|
||||
### pp_beam/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
pp_beam(Beam::<a href="#type-filename">filename()</a>) -> string() | {error, Reason}
|
||||
</code></pre>
|
||||
<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>
|
||||
|
||||
### pp_beam/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
pp_beam(Beam::<a href="#type-filename">filename()</a>, Out::<a href="#type-filename">filename()</a>) -> ok | {error, Reason}
|
||||
</code></pre>
|
||||
<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>
|
||||
|
||||
### pp_src/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
pp_src(Forms0::Forms, Out::<a href="#type-filename">filename()</a>) -> ok
|
||||
</code></pre>
|
||||
|
@ -27,10 +27,10 @@ div.spec {
|
||||
margin-left: 2em;
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
a.module,a.package {
|
||||
a.module {
|
||||
text-decoration:none
|
||||
}
|
||||
a.module:hover,a.package:hover {
|
||||
a.module:hover {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
ul.definitions {
|
||||
|
Loading…
Reference in New Issue
Block a user