free_vars/1
Bengt Kleberg
Bengt.Kleberg@REDACTED
Thu Sep 4 14:44:51 CEST 2003
greetings,
i have been using the function free_vars/1 (see end of email) by Richard
Carlsson(?). it is very helpful when refactoring code. unfortunatly it
throws an error when given a macro. erl_parse:parse_exprs/1 returns
{error, {Line, erl_parse, Reason}} when fed a macro.
my solution has been to change macros to atoms, like this:
macros_to_atoms( [] ) ->
[];
macros_to_atoms( [{'?',_Nr}, {_Type, Nr, Macro}|T] ) ->
[{atom, Nr, Macro} | macros_to_atoms( T )];
macros_to_atoms( [H|T] ) ->
[H | macros_to_atoms( T )].
before calling erl_parse:parse_exprs/1.
is there a better way?
bengt
%% @spec free_vars(Text::string()) -> string()
%% @equiv free_vars(Text, 1)
free_vars(Text) ->
free_vars(Text, 1).
%% @spec free_vars(Text::string(), Line::integer()) -> string()
free_vars(Text, StartLine) ->
%% StartLine/EndLine may be useful in error messages.
{ok, Ts, EndLine} = erl_scan:string(Text, StartLine),
Ts1 = lists:reverse([{dot, EndLine} | strip(lists:reverse(Ts))]),
Ts2 = macros_to_atoms( Ts1 ),
case erl_parse:parse_exprs(Ts2) of
{ok, Es} ->
E = erl_syntax:block_expr(Es),
E1 = erl_syntax_lib:annotate_bindings(E, ordsets:new()),
{value, {free, Vs}} = lists:keysearch(free, 1,
erl_syntax:get_ann(E1)),
Vs;
{error, {_Line, erl_parse, Reason}} ->
erlang:throw( {error, io_lib:format("~s", [Reason])} )
end.
strip([{',', _} | Ts]) -> strip(Ts);
strip([{';', _} | Ts]) -> strip(Ts);
strip([{'.', _} | Ts]) -> strip(Ts);
strip([{'|', _} | Ts]) -> strip(Ts);
strip([{'=', _} | Ts]) -> strip(Ts);
strip([{'dot', _} | Ts]) -> strip(Ts);
strip([{'->', _} | Ts]) -> strip(Ts);
strip([{'||', _} | Ts]) -> strip(Ts);
strip([{'of', _} | Ts]) -> strip(Ts);
strip(Ts) -> Ts.
More information about the erlang-questions
mailing list