mirror of
https://github.com/valitydev/parse_trans.git
synced 2024-11-06 00:25:16 +00:00
codegen:gen_module/3 support
This commit is contained in:
parent
c55c8861cd
commit
f83f77c2cc
12
README.md
12
README.md
@ -64,10 +64,10 @@ Forms = [{attribute,1,file,{"./ex1.erl",1}},
|
||||
|
||||
|
||||
<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/esl/parse_trans/blob/2.5.4/doc/ct_expand.md" class="module">ct_expand</a></td></tr>
|
||||
<tr><td><a href="http://github.com/esl/parse_trans/blob/2.5.4/doc/exprecs.md" class="module">exprecs</a></td></tr>
|
||||
<tr><td><a href="http://github.com/esl/parse_trans/blob/2.5.4/doc/parse_trans.md" class="module">parse_trans</a></td></tr>
|
||||
<tr><td><a href="http://github.com/esl/parse_trans/blob/2.5.4/doc/parse_trans_codegen.md" class="module">parse_trans_codegen</a></td></tr>
|
||||
<tr><td><a href="http://github.com/esl/parse_trans/blob/2.5.4/doc/parse_trans_mod.md" class="module">parse_trans_mod</a></td></tr>
|
||||
<tr><td><a href="http://github.com/esl/parse_trans/blob/2.5.4/doc/parse_trans_pp.md" class="module">parse_trans_pp</a></td></tr></table>
|
||||
|
||||
|
@ -117,6 +117,20 @@ 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##
|
||||
|
||||
|
||||
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##
|
||||
|
||||
|
||||
|
@ -95,6 +95,19 @@
|
||||
%% 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.
|
||||
%%
|
||||
%% <h2>gen_module/3</h2>
|
||||
%%
|
||||
%% Generates abstract forms for a complete module definition.
|
||||
%%
|
||||
%% Usage: `codegen:gen_module(ModuleName, Exports, Functions)'
|
||||
%%
|
||||
%% `ModuleName' is either an atom or a <code>{'$var', V}</code> reference.
|
||||
%%
|
||||
%% `Exports' is a list of `{Function, Arity}' tuples.
|
||||
%%
|
||||
%% `Functions' is a list of `{Name, Fun}' tuples analogous to that for
|
||||
%% `gen_functions/1'.
|
||||
%%
|
||||
%% <h2>Variable substitution</h2>
|
||||
%%
|
||||
%% It is possible to do some limited expansion (importing a value
|
||||
@ -145,6 +158,11 @@ xform_fun(application, Form, _Ctxt, Acc) ->
|
||||
MFA = erl_syntax_lib:analyze_application(Form),
|
||||
L = erl_syntax:get_pos(Form),
|
||||
case MFA of
|
||||
{codegen, {gen_module, 3}} ->
|
||||
[NameF, ExportsF, FunsF] =
|
||||
erl_syntax:application_arguments(Form),
|
||||
NewForms = gen_module(NameF, ExportsF, FunsF, L, Acc),
|
||||
{NewForms, Acc};
|
||||
{codegen, {gen_function, 2}} ->
|
||||
[NameF, FunF] =
|
||||
erl_syntax:application_arguments(Form),
|
||||
@ -177,6 +195,54 @@ xform_fun(application, Form, _Ctxt, Acc) ->
|
||||
xform_fun(_, Form, _Ctxt, Acc) ->
|
||||
{Form, Acc}.
|
||||
|
||||
gen_module(NameF, ExportsF, FunsF, L, Acc) ->
|
||||
try gen_module_(NameF, ExportsF, FunsF, L, Acc)
|
||||
catch
|
||||
error:E ->
|
||||
ErrStr = parse_trans:format_exception(error, E),
|
||||
{error, {L, ?MODULE, ErrStr}}
|
||||
end.
|
||||
|
||||
gen_module_(NameF, ExportsF, FunsF, L0, Acc) ->
|
||||
P = erl_syntax:get_pos(NameF),
|
||||
ModF = case parse_trans:revert_form(NameF) of
|
||||
{atom,_,_} = Am -> Am;
|
||||
{tuple,_,[{atom,_,'$var'},
|
||||
{var,_,V}]} ->
|
||||
{var,P,V}
|
||||
end,
|
||||
cons(
|
||||
{cons,P,
|
||||
{tuple,P,
|
||||
[{atom,P,attribute},
|
||||
{integer,P,1},
|
||||
{atom,P,module},
|
||||
ModF]},
|
||||
substitute(
|
||||
abstract(
|
||||
[{attribute,P,export,
|
||||
lists:map(
|
||||
fun(TupleF) ->
|
||||
[F,A] = erl_syntax:tuple_elements(TupleF),
|
||||
{erl_syntax:atom_value(F), erl_syntax:integer_value(A)}
|
||||
end, erl_syntax:list_elements(ExportsF))}]))},
|
||||
lists:map(
|
||||
fun(FTupleF) ->
|
||||
Pos = erl_syntax:get_pos(FTupleF),
|
||||
[FName, FFunF] = erl_syntax:tuple_elements(FTupleF),
|
||||
gen_function(FName, FFunF, L0, Pos, Acc)
|
||||
end, erl_syntax:list_elements(FunsF))).
|
||||
|
||||
cons({cons,L,H,T}, L2) ->
|
||||
{cons,L,H,cons(T, L2)};
|
||||
cons({nil,L}, [H|T]) ->
|
||||
Pos = erl_syntax:get_pos(H),
|
||||
{cons,L,H,cons({nil,Pos}, T)};
|
||||
cons({nil,L}, []) ->
|
||||
{nil,L}.
|
||||
|
||||
|
||||
|
||||
gen_function(NameF, FunF, L0, L, Acc) ->
|
||||
try gen_function_(NameF, FunF, L, Acc)
|
||||
catch
|
||||
|
Loading…
Reference in New Issue
Block a user