diff --git a/README.md b/README.md new file mode 100644 index 0000000..1eedb13 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +Parse Transform Utility Library +=============================== + +This application contains some utility functions that +make it easier to write maintainable parse transforms +for erlang. The library uses Syntax Tools, which may seem +unwieldy at first. However, I recommend getting acquainted +with Syntax Tools; it has many advantages in for parse +transforms. + +Documentation +------------- +The EDoc is generated using the EDown extension, in order +to make it easy to read online on Github. To generate +normal edoc, update `rebar.config` to remove the edown- +related dependencies and edoc options. diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..3962e7a --- /dev/null +++ b/doc/README.md @@ -0,0 +1,93 @@ + + +#The parse_trans application# +The parse_trans application +=========================== +A generic parse transform library +This library is intended to simplify the task of writing parse transform +modules for Erlang. +__Authors:__ Ulf Wiger ([`ulf.wiger@erlang-consulting.com`](mailto:ulf.wiger@erlang-consulting.com)). +A generic parse transform library +This library is intended to simplify the task of writing parse transform +modules for Erlang. + + + +#Introduction to parse transforms# + + + + +##The simplest transform## + + + +The very simplest transform we can make is one that doesn't +change a thing. For convenience, we will at least print the forms. +This will enlighten us as to what the forms actually look like. + + +
+-module(test_pt).
+
+-export([parse_transform/2]).
+
+parse_transform(Forms, _Options) ->
+    io:fwrite("Forms = ~p~n", [Forms]),
+    Forms.
+
+ + + +Trying this with a very simple module: + + +
+-module(ex1).
+-export([add/2]).
+
+add(X,Y) ->
+    X + Y.
+
+ + + +
+1> c(ex1, [{parse_transform,test_pt}]).
+Forms = [{attribute,1,file,{"./ex1.erl",1}},
+         {attribute,1,module,ex1},
+         {attribute,2,export,[{add,2}]},
+         {function,4,add,2,
+                   [{clause,4,
+                            [{var,4,'X'},{var,4,'Y'}],
+                            [],
+                            [{op,5,'+',{var,5,'X'},{var,5,'Y'}}]}]},
+         {eof,6}]
+{ok,ex1}
+
+ + + + +##`transform/4`## + + +... + + + + +#Current limitations# + + +... + + +##Modules## + + + + + + +
ct_expand
exprecs
parse_trans
parse_trans_codegen
parse_trans_pp
diff --git a/doc/ct_expand.html b/doc/ct_expand.html deleted file mode 100644 index 0996c7a..0000000 --- a/doc/ct_expand.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -Module ct_expand - - - - -
- -

Module ct_expand

-Compile-time expansion utility. - -

Authors: : Ulf Wiger (ulf.wiger@erlang-solutions.com).

- -

Description

Compile-time expansion utility

- -

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]. - -

Function Index

- -
parse_transform/2
- -

Function Details

- -

parse_transform/2

-
-

parse_transform(Forms, Options) -> any()

-
-
- - -

Generated by EDoc, Sep 5 2010, 14:28:44.

- - diff --git a/doc/ct_expand.md b/doc/ct_expand.md new file mode 100644 index 0000000..a31f2b0 --- /dev/null +++ b/doc/ct_expand.md @@ -0,0 +1,49 @@ +Module ct_expand +================ + + +#Module ct_expand# +* [Description](#description) +* [Function Index](#index) +* [Function Details](#functions) +Compile-time expansion utility. +__Authors:__ : Ulf Wiger ([`ulf.wiger@erlang-solutions.com`](mailto:ulf.wiger@erlang-solutions.com)). + +##Description## + +Compile-time expansion utility + + +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]`. + + +##Function Index## + +
parse_transform/2
+ + + + +##Function Details## + + + + +###parse_transform/2## + + +`parse_transform(Forms, Options) -> any()` + +_Generated by EDoc, Oct 23 2010, 21:00:45._ \ No newline at end of file diff --git a/doc/exprecs.html b/doc/exprecs.html deleted file mode 100644 index cd219ad..0000000 --- a/doc/exprecs.html +++ /dev/null @@ -1,122 +0,0 @@ - - - -Module exprecs - - - - -
- -

Module exprecs

-Parse transform for generating record access functions. - -

Authors: : Ulf Wiger (ulf.wiger@ericsson.com).

- -

Description

Parse transform for generating record access functions. -

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:

- -
-  -module(test_exprecs).
- 
-  -record(r, {a, b, c}).
-  -export_records([r]).
- 
-  -export(['#new-'/1, '#info-'/1, '#info-'/2, '#pos-'/2,
-           '#is_record-'/2, '#get-'/2, '#set-'/2, '#fromlist-'/2,
-           '#new-r'/0, '#new-r'/1, '#get-r'/2, '#set-r'/2,
-           '#pos-r'/1, '#fromlist-r'/2, '#info-r'/1]).
- 
-  '#new-'(r) -> '#new-r'().
- 
-  '#info-'(RecName) -> '#info-'(RecName, fields).
- 
-  '#info-'(r, Info) -> '#info-r'(Info).
- 
-  '#pos-'(r, Attr) -> '#pos-r'(Attr).
- 
-  '#is_record-'(r, Rec)
-      when tuple_size(Rec) == 3, element(1, Rec) == r ->
-      true;
-  '#is_record-'(_, _) -> false.
- 
-  '#get-'(Attrs, Rec) when is_record(Rec, r) ->
-      '#get-r'(Attrs, Rec).
- 
-  '#set-'(Vals, Rec) when is_record(Rec, r) ->
-      '#set-r'(Vals, Rec).
- 
-  '#fromlist-'(Vals, Rec) when is_record(Rec, r) ->
-      '#fromlist-r'(Vals, Rec).
- 
-  '#new-r'() -> #r{}.
- 
-  '#new-r'(Vals) -> '#set-r'(Vals, #r{}).
- 
-  '#get-r'(Attrs, R) when is_list(Attrs) ->
-      ['#get-r'(A, R) || A <- Attrs];
-  '#get-r'(a, R) -> R#r.a;
-  '#get-r'(b, R) -> R#r.b;
-  '#get-r'(c, R) -> R#r.c;
-  '#get-r'(Attr, R) ->
-      erlang:error(bad_record_op, ['#get-r', Attr, R]).
- 
-  '#set-r'(Vals, Rec) ->
-      F = fun ([], R, _F1) -> R;
-              ([{a, V} | T], R, F1) -> F1(T, R#r{a = V}, F1);
-              ([{b, V} | T], R, F1) -> F1(T, R#r{b = V}, F1);
-              ([{c, V} | T], R, F1) -> F1(T, R#r{c = V}, F1);
-              (Vs, R, _) ->
-                  erlang:error(bad_record_op, ['#set-r', Vs, R])
-          end,
-      F(Vals, Rec, F).
- 
-  '#fromlist-r'(Vals, Rec) ->
-      AttrNames = [{a, 2}, {b, 3}, {c, 4}],
-      F = fun ([], R, _F1) -> R;
-              ([{H, Pos} | T], R, F1) ->
-                  case lists:keyfind(H, 1, Vals) of
-                    false -> F1(T, R, F1);
-                    {_, Val} -> F1(T, setelement(Pos, R, Val), F1)
-                  end
-          end,
-      F(AttrNames, Rec, F).
- 
-  '#pos-r'(a) -> 2;
-  '#pos-r'(b) -> 3;
-  '#pos-r'(c) -> 4;
-  '#pos-r'(_) -> 0.
- 
-  '#info-r'(fields) -> record_info(fields, r);
-  '#info-r'(size) -> record_info(size, r).
-  
-

Function Index

- -
parse_transform/2
- -

Function Details

- -

parse_transform/2

-
-

parse_transform(Forms, Options) -> any()

-
-
- - -

Generated by EDoc, Sep 5 2010, 14:28:44.

- - diff --git a/doc/exprecs.md b/doc/exprecs.md new file mode 100644 index 0000000..3dbe10c --- /dev/null +++ b/doc/exprecs.md @@ -0,0 +1,128 @@ +Module exprecs +============== + + +#Module exprecs# +* [Description](#description) +* [Function Index](#index) +* [Function Details](#functions) +Parse transform for generating record access functions. +__Authors:__ : Ulf Wiger ([`ulf.wiger@ericsson.com`](mailto:ulf.wiger@ericsson.com)). + +##Description## +Parse transform for generating record access functions. + +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: + + +
+  -module(test_exprecs).
+ 
+  -record(r, {a, b, c}).
+  -export_records([r]).
+ 
+  -export(['#new-'/1, '#info-'/1, '#info-'/2, '#pos-'/2,
+           '#is_record-'/2, '#get-'/2, '#set-'/2, '#fromlist-'/2,
+           '#new-r'/0, '#new-r'/1, '#get-r'/2, '#set-r'/2,
+           '#pos-r'/1, '#fromlist-r'/2, '#info-r'/1]).
+ 
+  '#new-'(r) -> '#new-r'().
+ 
+  '#info-'(RecName) -> '#info-'(RecName, fields).
+ 
+  '#info-'(r, Info) -> '#info-r'(Info).
+ 
+  '#pos-'(r, Attr) -> '#pos-r'(Attr).
+ 
+  '#is_record-'(r, Rec)
+      when tuple_size(Rec) == 3, element(1, Rec) == r ->
+      true;
+  '#is_record-'(_, _) -> false.
+ 
+  '#get-'(Attrs, Rec) when is_record(Rec, r) ->
+      '#get-r'(Attrs, Rec).
+ 
+  '#set-'(Vals, Rec) when is_record(Rec, r) ->
+      '#set-r'(Vals, Rec).
+ 
+  '#fromlist-'(Vals, Rec) when is_record(Rec, r) ->
+      '#fromlist-r'(Vals, Rec).
+ 
+  '#new-r'() -> #r{}.
+ 
+  '#new-r'(Vals) -> '#set-r'(Vals, #r{}).
+ 
+  '#get-r'(Attrs, R) when is_list(Attrs) ->
+      ['#get-r'(A, R) || A <- Attrs];
+  '#get-r'(a, R) -> R#r.a;
+  '#get-r'(b, R) -> R#r.b;
+  '#get-r'(c, R) -> R#r.c;
+  '#get-r'(Attr, R) ->
+      erlang:error(bad_record_op, ['#get-r', Attr, R]).
+ 
+  '#set-r'(Vals, Rec) ->
+      F = fun ([], R, _F1) -> R;
+              ([{a, V} | T], R, F1) -> F1(T, R#r{a = V}, F1);
+              ([{b, V} | T], R, F1) -> F1(T, R#r{b = V}, F1);
+              ([{c, V} | T], R, F1) -> F1(T, R#r{c = V}, F1);
+              (Vs, R, _) ->
+                  erlang:error(bad_record_op, ['#set-r', Vs, R])
+          end,
+      F(Vals, Rec, F).
+ 
+  '#fromlist-r'(Vals, Rec) ->
+      AttrNames = [{a, 2}, {b, 3}, {c, 4}],
+      F = fun ([], R, _F1) -> R;
+              ([{H, Pos} | T], R, F1) ->
+                  case lists:keyfind(H, 1, Vals) of
+                    false -> F1(T, R, F1);
+                    {_, Val} -> F1(T, setelement(Pos, R, Val), F1)
+                  end
+          end,
+      F(AttrNames, Rec, F).
+ 
+  '#pos-r'(a) -> 2;
+  '#pos-r'(b) -> 3;
+  '#pos-r'(c) -> 4;
+  '#pos-r'(_) -> 0.
+ 
+  '#info-r'(fields) -> record_info(fields, r);
+  '#info-r'(size) -> record_info(size, r).
+  
+ + +##Function Index## + +
parse_transform/2
+ + + + +##Function Details## + + + + +###parse_transform/2## + + +`parse_transform(Forms, Options) -> any()` + +_Generated by EDoc, Oct 23 2010, 21:00:45._ \ No newline at end of file diff --git a/doc/index.html b/doc/index.html deleted file mode 100644 index e7dc41a..0000000 --- a/doc/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - -The parse_trans application - - - - - - -<h2>This page uses frames</h2> -<p>Your browser does not accept frames. -<br>You should go to the <a href="overview-summary.html">non-frame version</a> instead. -</p> - - - \ No newline at end of file diff --git a/doc/modules-frame.html b/doc/modules-frame.html deleted file mode 100644 index e46be1f..0000000 --- a/doc/modules-frame.html +++ /dev/null @@ -1,16 +0,0 @@ - - - -The parse_trans application - - - -

Modules

- - - - - -
ct_expand
exprecs
parse_trans
parse_trans_codegen
parse_trans_pp
- - \ No newline at end of file diff --git a/doc/overview-summary.html b/doc/overview-summary.html deleted file mode 100644 index e4e399d..0000000 --- a/doc/overview-summary.html +++ /dev/null @@ -1,68 +0,0 @@ - - - -The parse_trans application - - - - -

The parse_trans application

-

Authors: Ulf Wiger (ulf.wiger@erlang-consulting.com).

-

A generic parse transform library -This library is intended to simplify the task of writing parse transform -modules for Erlang.

- -

Introduction to parse transforms

- -

The simplest transform

- -

The very simplest transform we can make is one that doesn't -change a thing. For convenience, we will at least print the forms. -This will enlighten us as to what the forms actually look like.

- -
--module(test_pt).
-
--export([parse_transform/2]).
-
-parse_transform(Forms, _Options) ->
-    io:fwrite("Forms = ~p~n", [Forms]),
-    Forms.
-
- -

Trying this with a very simple module:

- -
--module(ex1).
--export([add/2]).
-
-add(X,Y) ->
-    X + Y.
-
- -
-1> c(ex1, [{parse_transform,test_pt}]).
-Forms = [{attribute,1,file,{"./ex1.erl",1}},
-         {attribute,1,module,ex1},
-         {attribute,2,export,[{add,2}]},
-         {function,4,add,2,
-                   [{clause,4,
-                            [{var,4,'X'},{var,4,'Y'}],
-                            [],
-                            [{op,5,'+',{var,5,'X'},{var,5,'Y'}}]}]},
-         {eof,6}]
-{ok,ex1}
-
- -

transform/4

-

...

- - -

Current limitations

-

...

- -
- -

Generated by EDoc, Sep 5 2010, 14:28:44.

- - diff --git a/doc/packages-frame.html b/doc/packages-frame.html deleted file mode 100644 index 85b55e8..0000000 --- a/doc/packages-frame.html +++ /dev/null @@ -1,11 +0,0 @@ - - - -The parse_trans application - - - -

Packages

-
- - \ No newline at end of file diff --git a/doc/parse_trans.html b/doc/parse_trans.html deleted file mode 100644 index c7d412d..0000000 --- a/doc/parse_trans.html +++ /dev/null @@ -1,217 +0,0 @@ - - - -Module parse_trans - - - - -
- -

Module parse_trans

-Generic parse transform library for Erlang. - -

Authors: : Ulf Wiger (ulf.wiger@erlang-consulting.com).

- -

Description

Generic parse transform library for Erlang.

- -

...

- -

Function Index

- - - - - - - - - - - - - - - - - - - - - - - -
context/2 - Accessor function for the Context record.
depth_first/4
do_depth_first/4
do_insert_forms/4
do_inspect/4
do_transform/4
error/3.
format_error/1
function_exists/3 - Checks whether the given function is defined in Forms.
get_attribute/2 - Returns the value of the first occurence of attribute A.
get_file/1 - Returns the name of the file being compiled.
get_module/1 - Returns the name of the module being compiled.
get_orig_syntax_tree/1.
get_pos/1 - Tries to retrieve the line number from an erl_syntax form.
initial_context/2 - Initializes a context record.
inspect/4 - Equvalent to do_inspect(Fun,Acc,Forms,initial_context(Forms,Options)).
optionally_pretty_print/3
pp_beam/1 - Reads debug_info from the beam file Beam and returns a string containing - the pretty-printed corresponding erlang source code.
pp_beam/2 - Reads debug_info from the beam file Beam and pretty-prints it as - Erlang source code, storing it in the file Out.
pp_src/2Pretty-prints the erlang source code corresponding to Forms into Out.
revert/1Reverts back from Syntax Tools format to Erlang forms.
top/3
transform/4 - Makes one pass.
- -

Function Details

- -

context/2

-
-

context(X1::Attr, Context) -> any() -

-

- Accessor function for the Context record.

- -

depth_first/4

-
-

depth_first(Fun, Acc, Forms, Options) -> any()

-
- -

do_depth_first/4

-
-

do_depth_first(F, Acc, Forms, Context) -> any()

-
- -

do_insert_forms/4

-
-

do_insert_forms(X1, Insert, Forms, Context) -> any()

-
- -

do_inspect/4

-
-

do_inspect(F, Acc, Forms, Context) -> any()

-
- -

do_transform/4

-
-

do_transform(F, Acc, Forms, Context) -> any()

-
- -

error/3

-
-

error(R::Reason, F::Form, I::Info) -> throw() -

-

-

Used to report errors detected during the parse transform.

- -

format_error/1

-
-

format_error(X1) -> any()

-
- -

function_exists/3

-
-

function_exists(Fname::atom(), Arity::integer(), Forms) -> boolean()

-

- Checks whether the given function is defined in Forms.

- -

get_attribute/2

-
-

get_attribute(A, Forms) -> any() -

-

- Returns the value of the first occurence of attribute A.

- -

get_file/1

-
-

get_file(Forms) -> string()

-

- Returns the name of the file being compiled.

- -

get_module/1

-
-

get_module(Forms) -> atom()

-

- Returns the name of the module being compiled.

- -

get_orig_syntax_tree/1

-
-

get_orig_syntax_tree(File) -> Forms

-

-

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).

- -

get_pos/1

-
-

get_pos(I::list()) -> integer()

-

- Tries to retrieve the line number from an erl_syntax form. Returns a - (very high) dummy number if not successful.

- -

initial_context/2

-
-

initial_context(Forms, Options) -> #context{}

-

- 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.

- -

inspect/4

-
-

inspect(F::Fun, Acc::Forms, Forms::Acc, Options) -> NewAcc -

-

- Equvalent to do_inspect(Fun,Acc,Forms,initial_context(Forms,Options)).

- -

optionally_pretty_print/3

-
-

optionally_pretty_print(Result, Options, Context) -> any()

-
- -

pp_beam/1

-
-

pp_beam(Beam::filename()) -> string() | {error, Reason}

-

- Reads debug_info from the beam file Beam and returns a string containing - the pretty-printed corresponding erlang source code.

- -

pp_beam/2

-
-

pp_beam(Beam::filename(), Out::filename()) -> ok | {error, Reason}

-

- Reads debug_info from the beam file Beam and pretty-prints it as - Erlang source code, storing it in the file Out.

- -

pp_src/2

-
-

pp_src(Res::Forms, Out::filename()) -> ok

-

Pretty-prints the erlang source code corresponding to Forms into Out -

- -

revert/1

-
-

revert(Tree) -> Forms

-

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.

- -

top/3

-
-

top(F, Forms, Options) -> any()

-
- -

transform/4

-
-

transform(Fun, Acc, Forms, Options) -> {TransformedForms, NewAcc} -

-

- Makes one pass

-
- - -

Generated by EDoc, Sep 5 2010, 14:28:44.

- - diff --git a/doc/parse_trans.md b/doc/parse_trans.md new file mode 100644 index 0000000..543ef46 --- /dev/null +++ b/doc/parse_trans.md @@ -0,0 +1,276 @@ +Module parse_trans +================== + + +#Module parse_trans# +* [Description](#description) +* [Function Index](#index) +* [Function Details](#functions) +Generic parse transform library for Erlang. +__Authors:__ : Ulf Wiger ([`ulf.wiger@erlang-consulting.com`](mailto:ulf.wiger@erlang-consulting.com)). + +##Description## + +Generic parse transform library for Erlang. + + +... + + +##Function Index## + +
context/2 + Accessor function for the Context record.
depth_first/4
do_depth_first/4
do_insert_forms/4
do_inspect/4
do_transform/4
error/3.
format_error/1
function_exists/3 + Checks whether the given function is defined in Forms.
get_attribute/2 + Returns the value of the first occurence of attribute A.
get_file/1 + Returns the name of the file being compiled.
get_module/1 + Returns the name of the module being compiled.
get_orig_syntax_tree/1.
get_pos/1 + Tries to retrieve the line number from an erl_syntax form.
initial_context/2 + Initializes a context record.
inspect/4 + Equvalent to do_inspect(Fun,Acc,Forms,initial_context(Forms,Options)).
optionally_pretty_print/3
pp_beam/1 + Reads debug_info from the beam file Beam and returns a string containing + the pretty-printed corresponding erlang source code.
pp_beam/2 + Reads debug_info from the beam file Beam and pretty-prints it as + Erlang source code, storing it in the file Out.
pp_src/2Pretty-prints the erlang source code corresponding to Forms into Out.
revert/1Reverts back from Syntax Tools format to Erlang forms.
top/3
transform/4 + Makes one pass.
+ + + + +##Function Details## + + + + +###context/2## + + +`context(X1::Attr, Context) -> any()`* `Attr = module | function | arity | options` + + + + Accessor function for the Context record. + + + +###depth_first/4## + + +`depth_first(Fun, Acc, Forms, Options) -> any()` + + + + +###do_depth_first/4## + + +`do_depth_first(F, Acc, Forms, Context) -> any()` + + + + +###do_insert_forms/4## + + +`do_insert_forms(X1, Insert, Forms, Context) -> any()` + + + + +###do_inspect/4## + + +`do_inspect(F, Acc, Forms, Context) -> any()` + + + + +###do_transform/4## + + +`do_transform(F, Acc, Forms, Context) -> any()` + + + + +###error/3## + + +`error(R::Reason, F::Form, I::Info) -> [throw()](#type-throw)`* `Info = [{Key, Value}]` + + + + +Used to report errors detected during the parse transform. + + + +###format_error/1## + + +`format_error(X1) -> any()` + + + + +###function_exists/3## + + +`function_exists(Fname::atom(), Arity::integer(), Forms) -> [boolean()](#type-boolean)` + + + Checks whether the given function is defined in Forms. + + + +###get_attribute/2## + + +`get_attribute(A, Forms) -> any()`* `A = atom()` + + + + Returns the value of the first occurence of attribute A. + + + +###get_file/1## + + +`get_file(Forms) -> string()` + + + Returns the name of the file being compiled. + + + +###get_module/1## + + +`get_module(Forms) -> atom()` + + + Returns the name of the module being compiled. + + + +###get_orig_syntax_tree/1## + + +`get_orig_syntax_tree(File) -> Forms` + + + +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). + + + +###get_pos/1## + + +`get_pos(I::list()) -> integer()` + + + Tries to retrieve the line number from an erl_syntax form. Returns a + (very high) dummy number if not successful. + + + +###initial_context/2## + + +`initial_context(Forms, Options) -> #context{}` + + + 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. + + + +###inspect/4## + + +`inspect(F::Fun, Acc::Forms, Forms::Acc, Options) -> NewAcc`* `Fun = function()` + + + + Equvalent to do_inspect(Fun,Acc,Forms,initial_context(Forms,Options)). + + + +###optionally_pretty_print/3## + + +`optionally_pretty_print(Result, Options, Context) -> any()` + + + + +###pp_beam/1## + + +`pp_beam(Beam::[filename()](#type-filename)) -> string() | {error, Reason}` + + + Reads debug_info from the beam file Beam and returns a string containing + the pretty-printed corresponding erlang source code. + + + +###pp_beam/2## + + +`pp_beam(Beam::[filename()](#type-filename), Out::[filename()](#type-filename)) -> ok | {error, Reason}` + + + Reads debug_info from the beam file Beam and pretty-prints it as + Erlang source code, storing it in the file Out. + + + +###pp_src/2## + + +`pp_src(Res::Forms, Out::[filename()](#type-filename)) -> ok` + +Pretty-prints the erlang source code corresponding to Forms into Out + + + + +###revert/1## + + +`revert(Tree) -> Forms` + +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. + + + +###top/3## + + +`top(F, Forms, Options) -> any()` + + + + +###transform/4## + + +`transform(Fun, Acc, Forms, Options) -> {TransformedForms, NewAcc}`* `Fun = function()` +* `Options = [{Key, Value}]` + + + + Makes one pass +_Generated by EDoc, Oct 23 2010, 21:00:44._ \ No newline at end of file diff --git a/doc/parse_trans_codegen.html b/doc/parse_trans_codegen.html deleted file mode 100644 index 1106790..0000000 --- a/doc/parse_trans_codegen.html +++ /dev/null @@ -1,96 +0,0 @@ - - - -Module parse_trans_codegen - - - - -
- -

Module parse_trans_codegen

-Parse transform for code generation pseduo functions. - -

Authors: : Ulf Wiger (ulf.wiger@erlang-solutions.com).

- -

Description

Parse transform for code generation pseduo functions

- -

...

- -

Function Index

- -
parse_transform/2 - 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.
- -

Function Details

- -

parse_transform/2

-
-

parse_transform(Forms, Options) -> NewForms

-

- 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 Fntun.

- -

Fun can either be a anonymous fun, which is then converted to - a named function. It can also be an implicit fun, e.g. - fun is_member/2. In this 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.

- -

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 -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.

- -

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: -
-  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).
-  

-
- - -

Generated by EDoc, Sep 5 2010, 14:28:44.

- - diff --git a/doc/parse_trans_codegen.md b/doc/parse_trans_codegen.md new file mode 100644 index 0000000..738dfc3 --- /dev/null +++ b/doc/parse_trans_codegen.md @@ -0,0 +1,125 @@ +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.wiger@erlang-solutions.com`](mailto:ulf.wiger@erlang-solutions.com)). + +##Description## + +Parse transform for code generation pseduo functions + + +... + + +##Function Index## + +
parse_transform/2 + 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.
+ + + + +##Function Details## + + + + +###parse_transform/2## + + +`parse_transform(Forms, Options) -> NewForms` + + + + 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 `Fntun`. + + +`Fun` can either be a anonymous `fun`, which is then converted to + a named function. It can also be an `implicit fun`, e.g. + `fun is_member/2`. In this 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`. + + + +##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 +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. + + + +##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: + +
+  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).
+  
+ +_Generated by EDoc, Oct 23 2010, 21:00:44._ \ No newline at end of file diff --git a/doc/parse_trans_pp.html b/doc/parse_trans_pp.html deleted file mode 100644 index ee3484a..0000000 --- a/doc/parse_trans_pp.html +++ /dev/null @@ -1,72 +0,0 @@ - - - -Module parse_trans_pp - - - - -
- -

Module parse_trans_pp

-Generic parse transform library for Erlang. - -

Authors: : Ulf Wiger (ulf.wiger@erlang-solutions.com).

- -

Description

Generic parse transform library for Erlang.

- -

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: -
-   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 -

Function Index

- - - - -
main/1
pp_beam/1 - Reads debug_info from the beam file Beam and returns a string containing - the pretty-printed corresponding erlang source code.
pp_beam/2 - Reads debug_info from the beam file Beam and pretty-prints it as - Erlang source code, storing it in the file Out.
pp_src/2Pretty-prints the erlang source code corresponding to Forms into Out.
- -

Function Details

- -

main/1

-
-

main(X1) -> any()

-
- -

pp_beam/1

-
-

pp_beam(Beam::filename()) -> string() | {error, Reason}

-

- Reads debug_info from the beam file Beam and returns a string containing - the pretty-printed corresponding erlang source code.

- -

pp_beam/2

-
-

pp_beam(Beam::filename(), Out::filename()) -> ok | {error, Reason}

-

- Reads debug_info from the beam file Beam and pretty-prints it as - Erlang source code, storing it in the file Out.

- -

pp_src/2

-
-

pp_src(Res::Forms, Out::filename()) -> ok

-

Pretty-prints the erlang source code corresponding to Forms into Out -

-
- - -

Generated by EDoc, Sep 5 2010, 14:28:44.

- - diff --git a/doc/parse_trans_pp.md b/doc/parse_trans_pp.md new file mode 100644 index 0000000..0ca7e46 --- /dev/null +++ b/doc/parse_trans_pp.md @@ -0,0 +1,86 @@ +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.wiger@erlang-solutions.com`](mailto:ulf.wiger@erlang-solutions.com)). + +##Description## + +Generic parse transform library for Erlang. + + +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: + +
+   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` + +##Function Index## + +
main/1
pp_beam/1 + Reads debug_info from the beam file Beam and returns a string containing + the pretty-printed corresponding erlang source code.
pp_beam/2 + Reads debug_info from the beam file Beam and pretty-prints it as + Erlang source code, storing it in the file Out.
pp_src/2Pretty-prints the erlang source code corresponding to Forms into Out.
+ + + + +##Function Details## + + + + +###main/1## + + +`main(X1) -> any()` + + + + +###pp_beam/1## + + +`pp_beam(Beam::[filename()](#type-filename)) -> string() | {error, Reason}` + + + Reads debug_info from the beam file Beam and returns a string containing + the pretty-printed corresponding erlang source code. + + + +###pp_beam/2## + + +`pp_beam(Beam::[filename()](#type-filename), Out::[filename()](#type-filename)) -> ok | {error, Reason}` + + + Reads debug_info from the beam file Beam and pretty-prints it as + Erlang source code, storing it in the file Out. + + + +###pp_src/2## + + +`pp_src(Res::Forms, Out::[filename()](#type-filename)) -> ok` + +Pretty-prints the erlang source code corresponding to Forms into Out + +_Generated by EDoc, Oct 23 2010, 21:00:44._ \ No newline at end of file diff --git a/rebar.config b/rebar.config index c2d51b0..30a2607 100644 --- a/rebar.config +++ b/rebar.config @@ -5,3 +5,5 @@ {erl_opts, [debug_info]}. {xref_checks, [undefined_function_calls]}. +{deps, [{edown, ".*", {git, "git://github.com/esl/edown.git", "HEAD"}}]}. +{edoc_opts, [{doclet, edown_doclet}]}.