[erlang-questions] [proposal] Declarative syntax for metadata (long!)

Michael Truog mjtruog@REDACTED
Sat Apr 10 20:18:44 CEST 2010


Ulf Wiger wrote:
> Michael Truog wrote:
>> Hi,
>>
>> I was hoping to bring up this thread because it does relate to a task I
>> am trying to do in Erlang.  To avoid re-parsing a compiled module to
>> generate this information I was hoping to use the loaded binary beam
>> data.  My use case is for automatically generating RPC function
>> definitions from an API module, which I think would be neat.
>>
>> One small thing that would make this easier, is if
>> "-compile(debug_info)." worked.  The documentation says it does:
>> "Note that all the options except the include path ({i,Dir}) can also be
>> given in the file" (http://erlang.org/doc/man/compile.html#debug_info)
>
> The following code might serve as a quick-and-dirty workaround,
> and also provide much faster access to the abstract code:
>
> -module(include_forms).
> -export([parse_transform/2]).
>
> parse_transform(Forms, _) ->
>     [EoF|Rev] = lists:reverse(Forms),
>     Forms1 = lists:reverse([EoF,absfun(Forms)|Rev]),
>     {Attrs,Funs} = lists:splitwith(fun(F) ->
>                                            element(1,F) == attribute
>                                    end, Forms1),
>     Attrs ++ [{attribute,1,export,[{'$abstract_code$',0}]} | Funs].
>
> absfun(Forms) ->
>     {function, 1, '$abstract_code$', 0,
>      [{clause,1,[],[],
>        [erl_parse:abstract(Forms)]}]}.
>
>
>
> Eshell V5.7.5  (abort with ^G)
> 1> c(include_forms).
> {ok,include_forms}
> 2> c(include_forms, [{parse_transform,include_forms}]).
> {ok,include_forms}
> 3> include_forms:'$abstract_code$'().
> [{attribute,1,file,{"./include_forms.erl",1}},
>  {attribute,1,module,include_forms},
>  {attribute,2,export,[{parse_transform,2}]},
>  {function,4,parse_transform,2,
>            [{clause,4,
>                     [{var,4,'Forms'},{var,4,'_'}],
>                     [],
>                     [{match,5,
>                             {cons,5,{var,5,'EoF'},{var,5,'Rev'}},
>                             {call,5,
>                                   {remote,5,{atom,5,lists},{atom,5,...}},
>                                   [{var,5,'Forms'}]}},
>
>
> The parse_transform directive can certainly be included in
> a module, as well as buried in a .hrl file.
>
> BR,
> Ulf W
This is a better solution!  If the include_forms is put into an
application dependency so that it is compiled before the module that
needs the abstract code access (and so that it exists as low-level
code), the module can just have "-compile({parse_transform,
include_forms})." in the file to create the '$abstract_code$'/1
function.  This doesn't seem dirty, since you have to opt-in to using
the parse transform within the code, so in a way you are agreeing to the
insertion of a function in the module.

Thanks,
Michael


More information about the erlang-questions mailing list