mirror of
https://github.com/valitydev/parse_trans.git
synced 2024-11-06 00:25:16 +00:00
set uwiger/parse_trans as root, fix email & copyrights
This commit is contained in:
parent
2adfbfcc17
commit
eaf461516e
16
README.md
16
README.md
@ -1,16 +1,16 @@
|
||||
|
||||
|
||||
#The parse_trans application#
|
||||
# The parse_trans application #
|
||||
|
||||
|
||||
##Modules##
|
||||
## Modules ##
|
||||
|
||||
|
||||
<table width="100%" border="0" summary="list of modules">
|
||||
<tr><td><a href="http://github.com/esl/parse_trans/blob/master/doc/ct_expand.md" class="module">ct_expand</a></td></tr>
|
||||
<tr><td><a href="http://github.com/esl/parse_trans/blob/master/doc/exprecs.md" class="module">exprecs</a></td></tr>
|
||||
<tr><td><a href="http://github.com/esl/parse_trans/blob/master/doc/parse_trans.md" class="module">parse_trans</a></td></tr>
|
||||
<tr><td><a href="http://github.com/esl/parse_trans/blob/master/doc/parse_trans_codegen.md" class="module">parse_trans_codegen</a></td></tr>
|
||||
<tr><td><a href="http://github.com/esl/parse_trans/blob/master/doc/parse_trans_mod.md" class="module">parse_trans_mod</a></td></tr>
|
||||
<tr><td><a href="http://github.com/esl/parse_trans/blob/master/doc/parse_trans_pp.md" class="module">parse_trans_pp</a></td></tr></table>
|
||||
<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,9 +1,9 @@
|
||||
|
||||
|
||||
#The parse_trans application#
|
||||
# The parse_trans application #
|
||||
|
||||
|
||||
##Modules##
|
||||
## Modules ##
|
||||
|
||||
|
||||
<table width="100%" border="0" summary="list of modules">
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
#Module ct_expand#
|
||||
# Module ct_expand #
|
||||
* [Description](#description)
|
||||
* [Data Types](#types)
|
||||
* [Function Index](#index)
|
||||
@ -8,13 +8,12 @@
|
||||
|
||||
|
||||
Compile-time expansion utility.
|
||||
__Authors:__ : Ulf Wiger ([`ulf@feuerlabs.com`](mailto:ulf@feuerlabs.com)).
|
||||
<a name="description"></a>
|
||||
|
||||
## Description ##
|
||||
|
||||
|
||||
__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.
|
||||
@ -22,50 +21,75 @@ 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),
|
||||
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)'.
|
||||
|
||||
<a name="types"></a>
|
||||
|
||||
##Data Types##
|
||||
## Data Types ##
|
||||
|
||||
|
||||
|
||||
|
||||
###<a name="type-form">form()</a>##
|
||||
### <a name="type-form">form()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre>form() = any()</pre>
|
||||
<pre><code>
|
||||
form() = any()
|
||||
</code></pre>
|
||||
|
||||
|
||||
|
||||
###<a name="type-forms">forms()</a>##
|
||||
|
||||
|
||||
### <a name="type-forms">forms()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre>forms() = [<a href="#type-form">form()</a>]</pre>
|
||||
<pre><code>
|
||||
forms() = [<a href="#type-form">form()</a>]
|
||||
</code></pre>
|
||||
|
||||
|
||||
|
||||
###<a name="type-options">options()</a>##
|
||||
|
||||
|
||||
### <a name="type-options">options()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre>options() = [{atom(), any()}]</pre>
|
||||
<pre><code>
|
||||
options() = [{atom(), any()}]
|
||||
</code></pre>
|
||||
|
||||
|
||||
<a name="index"></a>
|
||||
|
||||
##Function Index##
|
||||
## Function Index ##
|
||||
|
||||
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#extract_fun-3">extract_fun/3</a></td><td></td></tr><tr><td valign="top"><a href="#lfun_rewrite-2">lfun_rewrite/2</a></td><td></td></tr><tr><td valign="top"><a href="#parse_transform-2">parse_transform/2</a></td><td></td></tr></table>
|
||||
@ -73,34 +97,30 @@ or adding a compiler attribute -ct_expand_trace(Flags) will enable a form of cal
|
||||
|
||||
<a name="functions"></a>
|
||||
|
||||
##Function Details##
|
||||
## Function Details ##
|
||||
|
||||
<a name="extract_fun-3"></a>
|
||||
|
||||
###extract_fun/3##
|
||||
|
||||
|
||||
|
||||
### extract_fun/3 ###
|
||||
|
||||
`extract_fun(Name, Arity, Forms) -> any()`
|
||||
|
||||
|
||||
<a name="lfun_rewrite-2"></a>
|
||||
|
||||
###lfun_rewrite/2##
|
||||
|
||||
|
||||
|
||||
### lfun_rewrite/2 ###
|
||||
|
||||
`lfun_rewrite(Exprs, Forms) -> any()`
|
||||
|
||||
|
||||
<a name="parse_transform-2"></a>
|
||||
|
||||
###parse_transform/2##
|
||||
### parse_transform/2 ###
|
||||
|
||||
|
||||
|
||||
|
||||
<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>
|
||||
<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,3 +1,4 @@
|
||||
%% encoding: UTF-8
|
||||
{application,parse_trans}.
|
||||
{packages,[]}.
|
||||
{modules,[ct_expand,exprecs,parse_trans,parse_trans_codegen,parse_trans_mod,
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
#Module exprecs#
|
||||
# Module exprecs #
|
||||
* [Description](#description)
|
||||
* [Data Types](#types)
|
||||
* [Function Index](#index)
|
||||
@ -8,13 +8,10 @@
|
||||
|
||||
|
||||
Parse transform for generating record access functions.
|
||||
__Authors:__ : Ulf Wiger ([`ulf@wiger.net`](mailto:ulf@wiger.net)).
|
||||
<a name="description"></a>
|
||||
|
||||
|
||||
|
||||
__Authors:__ : Ulf Wiger ([`ulf.wiger@ericsson.com`](mailto:ulf.wiger@ericsson.com)).<a name="description"></a>
|
||||
|
||||
##Description##
|
||||
|
||||
## Description ##
|
||||
|
||||
This parse transform can be used to reduce compile-time
|
||||
dependencies in large systems.
|
||||
@ -36,8 +33,13 @@ 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:
|
||||
<pre>
|
||||
to lay out access functions for the exported records:
|
||||
|
||||
|
||||
As an example, consider the following module:
|
||||
|
||||
```
|
||||
|
||||
-module(test_exprecs).
|
||||
-export([f/0]).
|
||||
-compile({parse_transform, exprecs}).
|
||||
@ -47,10 +49,18 @@ to lay out access functions for the exported records:As an example, consider the
|
||||
-record(s,{a}).
|
||||
-export_records([r,s]).
|
||||
f() ->
|
||||
{new,'#new-r'([])}.</pre>
|
||||
{new,'#new-r'([])}.
|
||||
```
|
||||
|
||||
|
||||
|
||||
Compiling this (assuming exprecs is in the path) will produce the
|
||||
following code.<pre>
|
||||
following code.
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
-module(test_exprecs).
|
||||
-compile({pt_pp_src,true}).
|
||||
-export([f/0]).
|
||||
@ -327,13 +337,25 @@ following code.<pre>
|
||||
'#lens-s'(Attr) ->
|
||||
error(bad_record_op, ['#lens-s', Attr]).
|
||||
f() ->
|
||||
{new,'#new-r'([])}.</pre>
|
||||
{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):<pre>
|
||||
of the following attributes (example reflecting the current rules):
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
-exprecs_prefix(["#", operation, "-"]).
|
||||
-exprecs_fname([prefix, record]).
|
||||
-exprecs_vfname([fname, "__", version]).</pre>The lists must contain strings or any of the following control atoms:
|
||||
-exprecs_vfname([fname, "__", version]).
|
||||
```
|
||||
|
||||
|
||||
The lists must contain strings or any of the following control atoms:
|
||||
|
||||
* in `exprecs_prefix`: `operation`
|
||||
|
||||
@ -343,9 +365,13 @@ of the following attributes (example reflecting the current rules):<pre>
|
||||
|
||||
|
||||
|
||||
|
||||
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:
|
||||
atom (a valid function or type name).
|
||||
|
||||
|
||||
`operation` is one of:
|
||||
|
||||
|
||||
|
||||
@ -451,35 +477,47 @@ atom (a valid function or type name).`operation` is one of:
|
||||
|
||||
<a name="types"></a>
|
||||
|
||||
##Data Types##
|
||||
## Data Types ##
|
||||
|
||||
|
||||
|
||||
|
||||
###<a name="type-form">form()</a>##
|
||||
### <a name="type-form">form()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre>form() = any()</pre>
|
||||
<pre><code>
|
||||
form() = any()
|
||||
</code></pre>
|
||||
|
||||
|
||||
|
||||
###<a name="type-forms">forms()</a>##
|
||||
|
||||
|
||||
### <a name="type-forms">forms()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre>forms() = [<a href="#type-form">form()</a>]</pre>
|
||||
<pre><code>
|
||||
forms() = [<a href="#type-form">form()</a>]
|
||||
</code></pre>
|
||||
|
||||
|
||||
|
||||
###<a name="type-options">options()</a>##
|
||||
|
||||
|
||||
### <a name="type-options">options()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre>options() = [{atom(), any()}]</pre>
|
||||
<pre><code>
|
||||
options() = [{atom(), any()}]
|
||||
</code></pre>
|
||||
|
||||
|
||||
<a name="index"></a>
|
||||
|
||||
##Function Index##
|
||||
## Function Index ##
|
||||
|
||||
|
||||
<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>
|
||||
@ -487,16 +525,16 @@ atom (a valid function or type name).`operation` is one of:
|
||||
|
||||
<a name="functions"></a>
|
||||
|
||||
##Function Details##
|
||||
## Function Details ##
|
||||
|
||||
<a name="parse_transform-2"></a>
|
||||
|
||||
###parse_transform/2##
|
||||
### parse_transform/2 ###
|
||||
|
||||
|
||||
|
||||
|
||||
<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>
|
||||
<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,6 +1,6 @@
|
||||
|
||||
|
||||
#Module parse_trans#
|
||||
# Module parse_trans #
|
||||
* [Description](#description)
|
||||
* [Data Types](#types)
|
||||
* [Function Index](#index)
|
||||
@ -8,79 +8,107 @@
|
||||
|
||||
|
||||
Generic parse transform library for Erlang.
|
||||
__Authors:__ : Ulf Wiger ([`ulf.wiger@feuerlabs.com`](mailto:ulf.wiger@feuerlabs.com)).
|
||||
<a name="description"></a>
|
||||
|
||||
## Description ##
|
||||
|
||||
|
||||
__Authors:__ : Ulf Wiger ([`ulf.wiger@feuerlabs.com`](mailto:ulf.wiger@feuerlabs.com)).<a name="description"></a>
|
||||
|
||||
##Description##
|
||||
|
||||
|
||||
...
|
||||
|
||||
|
||||
<a name="types"></a>
|
||||
|
||||
##Data Types##
|
||||
## Data Types ##
|
||||
|
||||
|
||||
|
||||
|
||||
###<a name="type-form">form()</a>##
|
||||
### <a name="type-form">form()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre>form() = any()</pre>
|
||||
<pre><code>
|
||||
form() = any()
|
||||
</code></pre>
|
||||
|
||||
|
||||
|
||||
###<a name="type-forms">forms()</a>##
|
||||
|
||||
|
||||
### <a name="type-forms">forms()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre>forms() = [<a href="#type-form">form()</a>]</pre>
|
||||
<pre><code>
|
||||
forms() = [<a href="#type-form">form()</a>]
|
||||
</code></pre>
|
||||
|
||||
|
||||
|
||||
###<a name="type-insp_f">insp_f()</a>##
|
||||
|
||||
|
||||
### <a name="type-insp_f">insp_f()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre>insp_f() = fun((<a href="#type-type">type()</a>, <a href="#type-form">form()</a>, #context{}, A) -> {boolean(), A})</pre>
|
||||
<pre><code>
|
||||
insp_f() = fun((<a href="#type-type">type()</a>, <a href="#type-form">form()</a>, #context{}, A) -> {boolean(), A})
|
||||
</code></pre>
|
||||
|
||||
|
||||
|
||||
###<a name="type-options">options()</a>##
|
||||
|
||||
|
||||
### <a name="type-options">options()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre>options() = [{atom(), any()}]</pre>
|
||||
<pre><code>
|
||||
options() = [{atom(), any()}]
|
||||
</code></pre>
|
||||
|
||||
|
||||
|
||||
###<a name="type-type">type()</a>##
|
||||
|
||||
|
||||
### <a name="type-type">type()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre>type() = atom()</pre>
|
||||
<pre><code>
|
||||
type() = atom()
|
||||
</code></pre>
|
||||
|
||||
|
||||
|
||||
###<a name="type-xform_f_df">xform_f_df()</a>##
|
||||
|
||||
|
||||
### <a name="type-xform_f_df">xform_f_df()</a> ###
|
||||
|
||||
|
||||
|
||||
<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>
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
###<a name="type-xform_f_rec">xform_f_rec()</a>##
|
||||
|
||||
|
||||
### <a name="type-xform_f_rec">xform_f_rec()</a> ###
|
||||
|
||||
|
||||
|
||||
<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>
|
||||
<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##
|
||||
## Function Index ##
|
||||
|
||||
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#context-2">context/2</a></td><td>
|
||||
@ -102,295 +130,279 @@ Makes one pass.</td></tr></table>
|
||||
|
||||
<a name="functions"></a>
|
||||
|
||||
##Function Details##
|
||||
## Function Details ##
|
||||
|
||||
<a name="context-2"></a>
|
||||
|
||||
###context/2##
|
||||
### context/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
context(X1::Attr, Context) -> any()
|
||||
</code></pre>
|
||||
|
||||
<ul class="definitions"><li><code>Attr = module | function | arity | options</code></li></ul>
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
### depth_first/4 ###
|
||||
|
||||
|
||||
|
||||
|
||||
Accessor function for the Context record.<a name="depth_first-4"></a>
|
||||
|
||||
###depth_first/4##
|
||||
|
||||
|
||||
|
||||
|
||||
<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>
|
||||
<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##
|
||||
### do_depth_first/4 ###
|
||||
|
||||
|
||||
|
||||
|
||||
<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>
|
||||
<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##
|
||||
### do_insert_forms/4 ###
|
||||
|
||||
|
||||
|
||||
|
||||
<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>
|
||||
<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##
|
||||
### do_inspect/4 ###
|
||||
|
||||
|
||||
|
||||
|
||||
<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>
|
||||
<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##
|
||||
### do_transform/4 ###
|
||||
|
||||
|
||||
|
||||
|
||||
<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>
|
||||
<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##
|
||||
### 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.
|
||||
|
||||
<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="export_function-3"></a>
|
||||
|
||||
###export_function/3##
|
||||
|
||||
|
||||
<a name="export_function-3"></a>
|
||||
|
||||
### export_function/3 ###
|
||||
|
||||
`export_function(F, Arity, Forms) -> any()`
|
||||
|
||||
|
||||
<a name="format_error-1"></a>
|
||||
|
||||
###format_error/1##
|
||||
### format_error/1 ###
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>format_error(Error::{atom(), term()}) -> iolist()</pre>
|
||||
<br></br>
|
||||
<pre><code>
|
||||
format_error(Error::{atom(), term()}) -> iolist()
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="format_exception-2"></a>
|
||||
|
||||
###format_exception/2##
|
||||
### 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>format_exception(Class, Reason) -> String</pre>
|
||||
<br></br>
|
||||
|
||||
|
||||
|
||||
|
||||
Equivalent to [`format_exception(Class, Reason, 4)`](#format_exception-3).<a name="format_exception-3"></a>
|
||||
|
||||
###format_exception/3##
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>format_exception(Class, Reason, Lines) -> String</pre>
|
||||
<ul class="definitions"><li><pre>Class = error | throw | exit</pre></li><li><pre>Reason = term()</pre></li><li><pre>Lines = integer() | infinity</pre></li></ul>
|
||||
|
||||
|
||||
<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##
|
||||
with the `Lines` parameter.
|
||||
|
||||
|
||||
Note that a stacktrace is generated inside this function.
|
||||
<a name="function_exists-3"></a>
|
||||
|
||||
### function_exists/3 ###
|
||||
|
||||
|
||||
<pre>function_exists(Fname::atom(), Arity::integer(), Forms) -> boolean()</pre>
|
||||
<br></br>
|
||||
<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>
|
||||
|
||||
Checks whether the given function is defined in Forms.<a name="get_attribute-2"></a>
|
||||
|
||||
###get_attribute/2##
|
||||
|
||||
|
||||
|
||||
|
||||
<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_attribute-3"></a>
|
||||
|
||||
###get_attribute/3##
|
||||
<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##
|
||||
### get_file/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
get_file(Forms) -> string()
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<pre>get_file(Forms) -> string()</pre>
|
||||
<br></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>
|
||||
|
||||
Returns the name of the file being compiled.<a name="get_module-1"></a>
|
||||
|
||||
###get_module/1##
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>get_module(Forms) -> atom()</pre>
|
||||
<br></br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Returns the name of the module being compiled.<a name="get_orig_syntax_tree-1"></a>
|
||||
|
||||
###get_orig_syntax_tree/1##
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>get_orig_syntax_tree(File) -> Forms</pre>
|
||||
<br></br>
|
||||
|
||||
|
||||
### 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
|
||||
uses epp_dodger).<a name="get_pos-1"></a>
|
||||
|
||||
###get_pos/1##
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>get_pos(I::list()) -> integer()</pre>
|
||||
<br></br>
|
||||
uses epp_dodger).
|
||||
|
||||
<a name="get_pos-1"></a>
|
||||
|
||||
### 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>initial_context(Forms, Options) -> #context{}</pre>
|
||||
<br></br>
|
||||
(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>
|
||||
name and the options passed to the transform function.
|
||||
<a name="inspect-4"></a>
|
||||
|
||||
###inspect/4##
|
||||
### 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>
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
### optionally_pretty_print/3 ###
|
||||
|
||||
|
||||
|
||||
|
||||
Equvalent to do_inspect(Fun,Acc,Forms,initial_context(Forms,Options)).<a name="optionally_pretty_print-3"></a>
|
||||
|
||||
###optionally_pretty_print/3##
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>optionally_pretty_print(Result::<a href="#type-forms">forms()</a>, Options::<a href="#type-options">options()</a>, Context::#context{}) -> ok</pre>
|
||||
<br></br>
|
||||
<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>plain_transform(Fun, Forms) -> <a href="#type-forms">forms()</a></pre>
|
||||
<ul class="definitions"><li><pre>Fun = function()</pre></li><li><pre>Forms = <a href="#type-forms">forms()</a></pre></li></ul>
|
||||
### 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>
|
||||
|
||||
|
||||
|
||||
@ -400,15 +412,24 @@ 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
|
||||
* `{error, Reason}` - Abort transformation with an error message.
|
||||
|
||||
|
||||
Example - This transform fun would convert all instances of `P ! Msg` to
|
||||
`gproc:send(P, Msg)`:
|
||||
<pre>
|
||||
|
||||
```
|
||||
|
||||
parse_transform(Forms, _Options) ->
|
||||
parse_trans:plain_transform(fun do_transform/1, Forms).
|
||||
do_transform({'op', L, '!', Lhs, Rhs}) ->
|
||||
@ -417,80 +438,74 @@ forms unchanged
|
||||
{call, L, {remote, L, {atom, L, gproc}, {atom, L, send}},
|
||||
[NewLhs, NewRhs]};
|
||||
do_transform(_) ->
|
||||
continue.</pre><a name="pp_beam-1"></a>
|
||||
|
||||
###pp_beam/1##
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>pp_beam(Beam::<a href="file.md#type-filename">file:filename()</a>) -> string() | {error, Reason}</pre>
|
||||
<br></br>
|
||||
continue.
|
||||
```
|
||||
|
||||
<a name="pp_beam-1"></a>
|
||||
|
||||
### 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>pp_beam(Beam::<a href="#type-filename">filename()</a>, Out::<a href="#type-filename">filename()</a>) -> ok | {error, Reason}</pre>
|
||||
<br></br>
|
||||
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>pp_src(Res::Forms, Out::<a href="#type-filename">filename()</a>) -> ok</pre>
|
||||
<br></br>
|
||||
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>
|
||||
<br />
|
||||
|
||||
Pretty-prints the erlang source code corresponding to Forms into Out
|
||||
|
||||
<a name="replace_function-4"></a>
|
||||
|
||||
###replace_function/4##
|
||||
|
||||
|
||||
|
||||
### replace_function/4 ###
|
||||
|
||||
`replace_function(F, Arity, NewForm, Forms) -> any()`
|
||||
|
||||
|
||||
<a name="return-2"></a>
|
||||
|
||||
###return/2##
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>return(Forms, Context) -> Forms | {error, Es, Ws} | {warnings, Forms, Ws}</pre>
|
||||
<br></br>
|
||||
|
||||
### return/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
return(Forms, Context) -> Forms | {error, Es, Ws} | {warnings, Forms, Ws}
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
Checks the transformed result for errors and warnings
|
||||
|
||||
|
||||
Errors and warnings can be produced from inside a parse transform, with
|
||||
a bit of care. The easiest way is to simply produce an `{error, Err}` or
|
||||
`{warning, Warn}` form in place. This function finds such forms, and
|
||||
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
|
||||
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:
|
||||
|
||||
* `Tag :: error | warning`
|
||||
@ -504,24 +519,21 @@ produces a return value that the compiler can work with.The format of the `error
|
||||
|
||||
|
||||
|
||||
|
||||
If the error is in the form of a caught exception, `Info` may be produced
|
||||
using the function [`format_exception/2`](#format_exception-2).<a name="revert-1"></a>
|
||||
|
||||
###revert/1##
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>revert(Tree) -> Forms</pre>
|
||||
<br></br>
|
||||
using the function [`format_exception/2`](#format_exception-2).
|
||||
|
||||
<a name="revert-1"></a>
|
||||
|
||||
### revert/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
revert(Tree) -> Forms
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
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.
|
||||
@ -532,22 +544,20 @@ Note2: R16B03 introduced a bug, where forms produced by
|
||||
This function works around that limitation, after first verifying that it's
|
||||
necessary to do so. Use of the workaround can be forced with the help of
|
||||
the `parse_trans` environment variable {revert_workaround, true}. This
|
||||
variable will be removed when R16B03 is no longer 'supported'.<a name="revert_form-1"></a>
|
||||
|
||||
###revert_form/1##
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>revert_form(F::Tree) -> Form</pre>
|
||||
<br></br>
|
||||
variable will be removed when R16B03 is no longer 'supported'.
|
||||
|
||||
<a name="revert_form-1"></a>
|
||||
|
||||
### revert_form/1 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
revert_form(F::Tree) -> Form
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
Reverts a single form back from Syntax Tools format to Erlang forms.
|
||||
|
||||
|
||||
`erl_syntax:revert/1` has had a long-standing bug where it doesn't
|
||||
completely revert attribute forms. This function deals properly with those
|
||||
cases.
|
||||
@ -563,28 +573,29 @@ Note2: R16B03 introduced a bug, where forms produced by
|
||||
This function works around that limitation, after first verifying that it's
|
||||
necessary to do so. Use of the workaround can be forced with the help of
|
||||
the `parse_trans` environment variable {revert_workaround, true}. This
|
||||
variable will be removed when R16B03 is no longer 'supported'.<a name="top-3"></a>
|
||||
variable will be removed when R16B03 is no longer 'supported'.
|
||||
|
||||
###top/3##
|
||||
<a name="top-3"></a>
|
||||
|
||||
### top/3 ###
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>top(F::function(), Forms::<a href="#type-forms">forms()</a>, Options::list()) -> <a href="#type-forms">forms()</a> | {error, term()}</pre>
|
||||
<br></br>
|
||||
<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##
|
||||
### 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>
|
||||
|
||||
|
||||
<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
|
||||
Makes one pass
|
||||
|
@ -1,24 +1,24 @@
|
||||
|
||||
|
||||
#Module parse_trans_codegen#
|
||||
# Module parse_trans_codegen #
|
||||
* [Description](#description)
|
||||
* [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 ##
|
||||
|
||||
|
||||
__Authors:__ : Ulf Wiger ([`ulf@feuerlabs.com`](mailto:ulf@feuerlabs.com)).<a name="description"></a>
|
||||
|
||||
##Description##
|
||||
|
||||
|
||||
...
|
||||
|
||||
<a name="index"></a>
|
||||
|
||||
##Function Index##
|
||||
## Function Index ##
|
||||
|
||||
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#format_error-1">format_error/1</a></td><td></td></tr><tr><td valign="top"><a href="#parse_transform-2">parse_transform/2</a></td><td>
|
||||
@ -29,30 +29,24 @@ representing the abstract form of that code.</td></tr></table>
|
||||
|
||||
<a name="functions"></a>
|
||||
|
||||
##Function Details##
|
||||
## Function Details ##
|
||||
|
||||
<a name="format_error-1"></a>
|
||||
|
||||
###format_error/1##
|
||||
|
||||
|
||||
|
||||
### format_error/1 ###
|
||||
|
||||
`format_error(E) -> any()`
|
||||
|
||||
|
||||
<a name="parse_transform-2"></a>
|
||||
|
||||
###parse_transform/2##
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>parse_transform(Forms, Options) -> NewForms</pre>
|
||||
<br></br>
|
||||
|
||||
|
||||
### parse_transform/2 ###
|
||||
|
||||
|
||||
<pre><code>
|
||||
parse_transform(Forms, Options) -> NewForms
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
|
||||
@ -60,20 +54,33 @@ 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##
|
||||
|
||||
|
||||
|
||||
## 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
|
||||
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
|
||||
@ -82,79 +89,141 @@ so that the generated function has the name `Name`.
|
||||
|
||||
|
||||
Another alternative is to wrap a fun inside a list comprehension, e.g.
|
||||
<pre>
|
||||
|
||||
```
|
||||
|
||||
f(Name, L) ->
|
||||
codegen:gen_function(
|
||||
Name,
|
||||
[ fun({'$var',X}) ->
|
||||
{'$var', Y}
|
||||
end || {X, Y} <- L ]).</pre>
|
||||
end || {X, Y} <- L ]).
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
Calling the above with `f(foo, [{1,a},{2,b},{3,c}])` will result in
|
||||
generated code corresponding to:
|
||||
<pre>
|
||||
|
||||
```
|
||||
|
||||
foo(1) -> a;
|
||||
foo(2) -> b;
|
||||
foo(3) -> c.</pre>
|
||||
foo(3) -> c.
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## gen_functions/1 ##
|
||||
|
||||
##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##
|
||||
|
||||
|
||||
|
||||
## 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
|
||||
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##
|
||||
|
||||
|
||||
|
||||
## 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##
|
||||
|
||||
|
||||
|
||||
## 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:
|
||||
<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>
|
||||
`V` is a bound variable in the scope of the call to `gen_function/2`.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
|
||||
gen(Name, X) ->
|
||||
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:
|
||||
|
||||
```
|
||||
|
||||
contains_17(L) ->
|
||||
lists:member(17, L).
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## Form substitution ##
|
||||
|
||||
##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:
|
||||
<pre>
|
||||
the scope of the call to `gen_function/2`.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
|
||||
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
|
||||
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:
|
||||
<pre>
|
||||
|
||||
```
|
||||
|
||||
is_foo(X) ->
|
||||
X =:= foo.</pre>
|
||||
X =:= foo.
|
||||
```
|
||||
|
||||
|
@ -1,37 +1,43 @@
|
||||
|
||||
|
||||
#Module parse_trans_mod#
|
||||
# Module parse_trans_mod #
|
||||
* [Data Types](#types)
|
||||
* [Function Index](#index)
|
||||
* [Function Details](#functions)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="types"></a>
|
||||
|
||||
##Data Types##
|
||||
## Data Types ##
|
||||
|
||||
|
||||
|
||||
|
||||
###<a name="type-compile_options">compile_options()</a>##
|
||||
### <a name="type-compile_options">compile_options()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre>compile_options() = [term()]</pre>
|
||||
<pre><code>
|
||||
compile_options() = [term()]
|
||||
</code></pre>
|
||||
|
||||
|
||||
|
||||
###<a name="type-erlang_form">erlang_form()</a>##
|
||||
|
||||
|
||||
### <a name="type-erlang_form">erlang_form()</a> ###
|
||||
|
||||
|
||||
|
||||
<pre>erlang_form() = term()</pre>
|
||||
<pre><code>
|
||||
erlang_form() = term()
|
||||
</code></pre>
|
||||
|
||||
|
||||
<a name="index"></a>
|
||||
|
||||
##Function Index##
|
||||
## Function Index ##
|
||||
|
||||
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#abstract_code-1">abstract_code/1</a></td><td></td></tr><tr><td valign="top"><a href="#beam_file-1">beam_file/1</a></td><td></td></tr><tr><td valign="top"><a href="#compile_and_load_forms-1">compile_and_load_forms/1</a></td><td></td></tr><tr><td valign="top"><a href="#compile_and_load_forms-2">compile_and_load_forms/2</a></td><td></td></tr><tr><td valign="top"><a href="#compile_options-1">compile_options/1</a></td><td></td></tr><tr><td valign="top"><a href="#rename_module-2">rename_module/2</a></td><td></td></tr><tr><td valign="top"><a href="#transform_module-3">transform_module/3</a></td><td></td></tr></table>
|
||||
@ -39,80 +45,78 @@
|
||||
|
||||
<a name="functions"></a>
|
||||
|
||||
##Function Details##
|
||||
## Function Details ##
|
||||
|
||||
<a name="abstract_code-1"></a>
|
||||
|
||||
###abstract_code/1##
|
||||
### abstract_code/1 ###
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>abstract_code(BeamFile::binary()) -> <a href="#type-erlang_form">erlang_form()</a></pre>
|
||||
<br></br>
|
||||
<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##
|
||||
### beam_file/1 ###
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>beam_file(Module::module()) -> binary()</pre>
|
||||
<br></br>
|
||||
<pre><code>
|
||||
beam_file(Module::module()) -> binary()
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="compile_and_load_forms-1"></a>
|
||||
|
||||
###compile_and_load_forms/1##
|
||||
### compile_and_load_forms/1 ###
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>compile_and_load_forms(AbsCode::<a href="#type-erlang_form">erlang_form()</a>) -> ok</pre>
|
||||
<br></br>
|
||||
<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##
|
||||
### compile_and_load_forms/2 ###
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>compile_and_load_forms(AbsCode::<a href="#type-erlang_form">erlang_form()</a>, Opts::<a href="#type-compile_options">compile_options()</a>) -> ok</pre>
|
||||
<br></br>
|
||||
<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##
|
||||
### compile_options/1 ###
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>compile_options(BeamFile::binary() | module()) -> <a href="#type-compile_options">compile_options()</a></pre>
|
||||
<br></br>
|
||||
<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##
|
||||
### rename_module/2 ###
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>rename_module(T::<a href="#type-erlang_form">erlang_form()</a>, NewName::module()) -> <a href="#type-erlang_form">erlang_form()</a></pre>
|
||||
<br></br>
|
||||
<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/3 ###
|
||||
|
||||
`transform_module(Mod, PT, Options) -> any()`
|
||||
|
||||
|
||||
|
@ -1,31 +1,39 @@
|
||||
|
||||
|
||||
#Module parse_trans_pp#
|
||||
# Module parse_trans_pp #
|
||||
* [Description](#description)
|
||||
* [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 ##
|
||||
|
||||
|
||||
__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:
|
||||
<pre>
|
||||
alias pp='escript $PARSE_TRANS_ROOT/ebin/parse_trans_pp.beam'</pre>
|
||||
pretty-print debug info in a .beam file from a Linux shell.
|
||||
|
||||
|
||||
a file could be pretty-printed using the following command:`$ pp ex_codegen.beam | less`<a name="index"></a>
|
||||
Using e.g. the following bash alias:
|
||||
|
||||
##Function Index##
|
||||
```
|
||||
|
||||
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 ##
|
||||
|
||||
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#main-1">main/1</a></td><td></td></tr><tr><td valign="top"><a href="#pp_beam-1">pp_beam/1</a></td><td>
|
||||
@ -37,60 +45,54 @@ Erlang source code, storing it in the file Out.</td></tr><tr><td valign="top"><a
|
||||
|
||||
<a name="functions"></a>
|
||||
|
||||
##Function Details##
|
||||
## Function Details ##
|
||||
|
||||
<a name="main-1"></a>
|
||||
|
||||
###main/1##
|
||||
### main/1 ###
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>main(X1::[string()]) -> any()</pre>
|
||||
<br></br>
|
||||
<pre><code>
|
||||
main(X1::[string()]) -> any()
|
||||
</code></pre>
|
||||
<br />
|
||||
|
||||
|
||||
<a name="pp_beam-1"></a>
|
||||
|
||||
###pp_beam/1##
|
||||
|
||||
|
||||
|
||||
|
||||
<pre>pp_beam(Beam::<a href="#type-filename">filename()</a>) -> string() | {error, Reason}</pre>
|
||||
<br></br>
|
||||
|
||||
### 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>pp_beam(Beam::<a href="#type-filename">filename()</a>, Out::<a href="#type-filename">filename()</a>) -> ok | {error, Reason}</pre>
|
||||
<br></br>
|
||||
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>pp_src(Forms0::Forms, Out::<a href="#type-filename">filename()</a>) -> ok</pre>
|
||||
<br></br>
|
||||
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>
|
||||
<br />
|
||||
|
||||
Pretty-prints the erlang source code corresponding to Forms into Out
|
||||
|
||||
|
@ -10,16 +10,16 @@
|
||||
%%
|
||||
%% The Original Code is parse_trans-2.0.
|
||||
%%
|
||||
%% Copyright (c) 2010 Erlang Solutions Ltd.
|
||||
%% Copyright (c) 2014 Ericsson AB
|
||||
%%
|
||||
%% Contributor(s): ______________________________________.
|
||||
|
||||
%%-------------------------------------------------------------------
|
||||
%% File : codegen.hrl
|
||||
%% @author : Ulf Wiger <ulf.wiger@erlang-solutions.com>
|
||||
%% @author : Ulf Wiger <ulf@wiger.net>
|
||||
%% @end
|
||||
%% Description :
|
||||
%% Description :
|
||||
%%
|
||||
%% Created : 25 Feb 2010 by Ulf Wiger <ulf.wiger@erlang-solutions.com>
|
||||
%% Created : 25 Feb 2010 by Ulf Wiger <ulf@wiger.net>
|
||||
%%-------------------------------------------------------------------
|
||||
-compile({parse_transform, parse_trans_codegen}).
|
||||
|
@ -10,16 +10,16 @@
|
||||
%%
|
||||
%% The Original Code is exprecs-0.2.
|
||||
%%
|
||||
%% Copyright (c) 2010 Erlang Solutions Ltd.
|
||||
%% Copyright (c) 2014 Ericsson AB
|
||||
%%
|
||||
%% Contributor(s): ______________________________________.
|
||||
|
||||
%%-------------------------------------------------------------------
|
||||
%% File : exprecs.hrl
|
||||
%% @author : Ulf Wiger <ulf.wiger@erlang-solutions.com>
|
||||
%% @author : Ulf Wiger <ulf@wiger.net>
|
||||
%% @end
|
||||
%% Description :
|
||||
%% Description :
|
||||
%%
|
||||
%% Created : 25 Feb 2010 by Ulf Wiger <ulf.wiger@erlang-solutions.com>
|
||||
%% Created : 25 Feb 2010 by Ulf Wiger <ulf@wiger.net>
|
||||
%%-------------------------------------------------------------------
|
||||
-compile({parse_transform, exprecs}).
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
{erl_opts, [debug_info]}.
|
||||
{xref_checks, [undefined_function_calls]}.
|
||||
{deps, [{edown, ".*", {git, "git://github.com/esl/edown.git", "HEAD"}}]}.
|
||||
{deps, [{edown, ".*", {git, "git://github.com/uwiger/edown.git", "0.5"}}]}.
|
||||
{edoc_opts, [{doclet, edown_doclet},
|
||||
{top_level_readme,
|
||||
{"./README.md",
|
||||
"http://github.com/esl/parse_trans"}}]}.
|
||||
"http://github.com/uwiger/parse_trans"}}]}.
|
||||
|
@ -10,7 +10,7 @@
|
||||
%%
|
||||
%% The Original Code is exprecs-0.2.
|
||||
%%
|
||||
%% Copyright (c) 2010 Erlang Solutions Ltd.
|
||||
%% Copyright (c) 2014 Ericsson AB
|
||||
%% The Initial Developer of the Original Code is Ericsson AB.
|
||||
%% Portions created by Ericsson are Copyright (C), 2006, Ericsson AB.
|
||||
%% All Rights Reserved.
|
||||
@ -19,12 +19,12 @@
|
||||
|
||||
%%-------------------------------------------------------------------
|
||||
%% File : exprecs.erl
|
||||
%% @author : Ulf Wiger <ulf.wiger@ericsson.com>
|
||||
%% @author : Ulf Wiger <ulf@wiger.net>
|
||||
%% @end
|
||||
%% Description :
|
||||
%%
|
||||
%% Created : 13 Feb 2006 by Ulf Wiger <ulf.wiger@ericsson.com>
|
||||
%% Rewritten: Jan-Feb 2010 by Ulf Wiger <ulf.wiger@elang-solutions.com>
|
||||
%% Created : 13 Feb 2006 by Ulf Wiger <ulf@wiger.net>
|
||||
%% Rewritten: Jan-Feb 2010 by Ulf Wiger <ulf@wiger.net>
|
||||
%%-------------------------------------------------------------------
|
||||
|
||||
%% @doc Parse transform for generating record access functions.
|
||||
|
@ -1,5 +1,5 @@
|
||||
%%============================================================================
|
||||
%% Copyright 2011 Erlang Solutions Ltd.
|
||||
%% Copyright 2014 Ulf Wiger
|
||||
%%
|
||||
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||
%% you may not use this file except in compliance with the License.
|
||||
@ -14,7 +14,7 @@
|
||||
%% limitations under the License.
|
||||
%%============================================================================
|
||||
%%
|
||||
%% Based on meck_mod.erl from http://github.com/esl/meck.git
|
||||
%% Based on meck_mod.erl from http://github.com/eproxus/meck.git
|
||||
%% Original author: Adam Lindberg
|
||||
%%
|
||||
-module(parse_trans_mod).
|
||||
|
Loading…
Reference in New Issue
Block a user