1
2
3# Module parse_trans_codegen #
4* [Description](#description)
5* [Function Index](#index)
6* [Function Details](#functions)
7
8Parse transform for code generation pseduo functions.
9
10__Authors:__ : Ulf Wiger ([`ulf@wiger.net`](mailto:ulf@wiger.net)).
11
12<a name="description"></a>
13
14## Description ##
15
16...
17
18<a name="index"></a>
19
20## Function Index ##
21
22
23<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>
24Searches for calls to pseudo functions in the module <code>codegen</code>,
25and converts the corresponding erlang code to a data structure
26representing the abstract form of that code.</td></tr></table>
27
28
29<a name="functions"></a>
30
31## Function Details ##
32
33<a name="format_error-1"></a>
34
35### format_error/1 ###
36
37`format_error(E) -> any()`
38
39<a name="parse_transform-2"></a>
40
41### parse_transform/2 ###
42
43<pre><code>
44parse_transform(Forms, Options) -&gt; NewForms
45</code></pre>
46<br />
47
48Searches for calls to pseudo functions in the module `codegen`,
49and converts the corresponding erlang code to a data structure
50representing the abstract form of that code.
51
52The purpose of these functions is to let the programmer write
53the actual code that is to be generated, rather than manually
54writing abstract forms, which is more error prone and cannot be
55checked by the compiler until the generated module is compiled.
56
57Supported functions:
58
59
60## gen_function/2 ##
61
62Usage: `codegen:gen_function(Name, Fun)`
63
64Substitutes the abstract code for a function with name `Name`
65and the same behaviour as `Fun`.
66
67`Fun` can either be a anonymous `fun`, which is then converted to
68a named function, or it can be an `implicit fun`, e.g.
69`fun is_member/2`. In the latter case, the referenced function is fetched
70and converted to an abstract form representation. It is also renamed
71so that the generated function has the name `Name`.
72
73Another alternative is to wrap a fun inside a list comprehension, e.g.
74
75```
76
77  f(Name, L) ->
78      codegen:gen_function(
79          Name,
80          [ fun({'$var',X}) ->
81               {'$var', Y}
82            end || {X, Y} &lt;- L ]).
83```
84
85
86Calling the above with `f(foo, [{1,a},{2,b},{3,c}])` will result in
87generated code corresponding to:
88
89```
90
91  foo(1) -> a;
92  foo(2) -> b;
93  foo(3) -> c.
94```
95
96
97## gen_functions/1 ##
98
99Takes a list of `{Name, Fun}` tuples and produces a list of abstract
100data objects, just as if one had written
101`[codegen:gen_function(N1,F1),codegen:gen_function(N2,F2),...]`.
102
103
104## exprs/1 ##
105
106Usage: `codegen:exprs(Fun)`
107
108`Fun` is either an anonymous function, or an implicit fun with only one
109function clause. This "function" takes the body of the fun and produces
110a data type representing the abstract form of the list of expressions in
111the body. The arguments of the function clause are ignored, but can be
112used to ensure that all necessary variables are known to the compiler.
113
114
115## gen_module/3 ##
116
117Generates abstract forms for a complete module definition.
118
119Usage: `codegen:gen_module(ModuleName, Exports, Functions)`
120
121`ModuleName` is either an atom or a `{'$var', V}` reference.
122
123`Exports` is a list of `{Function, Arity}` tuples.
124
125`Functions` is a list of `{Name, Fun}` tuples analogous to that for
126`gen_functions/1`.
127
128
129## Variable substitution ##
130
131It is possible to do some limited expansion (importing a value
132bound at compile-time), using the construct `{'$var', V}`, where
133`V` is a bound variable in the scope of the call to `gen_function/2`.
134
135Example:
136
137```
138
139  gen(Name, X) ->
140     codegen:gen_function(Name, fun(L) -> lists:member({'$var',X}, L) end).
141```
142
143After transformation, calling `gen(contains_17, 17)` will yield the
144abstract form corresponding to:
145
146```
147
148  contains_17(L) ->
149     lists:member(17, L).
150```
151
152
153## Form substitution ##
154
155It is possible to inject abstract forms, using the construct
156`{'$form', F}`, where `F` is bound to a parsed form in
157the scope of the call to `gen_function/2`.
158
159Example:
160
161```
162
163  gen(Name, F) ->
164     codegen:gen_function(Name, fun(X) -> X =:= {'$form',F} end).
165```
166
167After transformation, calling `gen(is_foo, {atom,0,foo})` will yield the
168abstract form corresponding to:
169
170```
171
172  is_foo(X) ->
173     X =:= foo.
174```
175
176