2

For some Erlang terms for example atom, tuple, list i can get AST using erl_parse:abstract/1. But it does not work for funs.

~ $ erl
Erlang/OTP 19 [erts-8.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V8.0  (abort with ^G)

1> erl_parse:abstract(foo).
{atom,0,foo}

2> erl_parse:abstract([bar]).
{cons,0,{atom,0,bar},{nil,0}}

3> erl_parse:abstract({baz}).
{tuple,0,[{atom,0,baz}]}

4> erlang:fun_info(fun() -> ok end, type).
{type,local} % So this is a local fun

5> erl_parse:abstract(fun() -> ok end).       
** exception error: no function clause matching 
                    erl_parse:abstract(#Fun<erl_eval.20.52032458>,0,
                                       #Fun<erl_parse.3.3133389>) (erl_parse.yrl, line 1330)

I know that some local funs have their AST in their info. But this is not for all local funs.

~ $ erl
Erlang/OTP 19 [erts-8.0] [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V8.0  (abort with ^G)

1> erlang:fun_info(fun() -> ok end, env).
{env,[{[],
       {eval,#Fun<shell.21.31625193>},
       {value,#Fun<shell.5.31625193>},
       [{clause,1,[],[],[{atom,1,ok}]}]}]} %% Here

2> foo:test(). %% Yields a fun
#Fun<foo.0.10202683>

3> erlang:fun_info(foo:test(), type).
{type,local} %% So this is a local fun too

4> erlang:fun_info(foo:test(), env). 
{env,[]} %% : (

Getting AST of an external fun is not hard. my solution is to load its module beam chunks and get AST of that function. If you have better solution, please tell me. The main problem is for getting AST of local funs.

Pouriya
  • 1,626
  • 11
  • 19

2 Answers2

2

Maybe you can try also combine erl_scan:string/1 and erl_parse:parse_exprs/1, eg:

1> Fun = "fun() -> ok end.".
"fun() -> ok end."
2> {ok, Tokens, _EndLocation} = erl_scan:string(Fun).
{ok,[{'fun',1},
     {'(',1},
     {')',1},
     {'->',1},
     {atom,1,ok},
     {'end',1},
     {dot,1}],
    1}
3> {ok, ExprList} = erl_parse:parse_exprs(Tokens).
{ok,[{'fun',1,{clauses,[{clause,1,[],[],[{atom,1,ok}]}]}}]}

Hope, this will be helpful.

vkatsuba
  • 1,411
  • 1
  • 7
  • 19
-2

erl_parse:abstract/1 cannot accept function object as argument. I think you are right in the rest.

Alexei K
  • 142
  • 1
  • 5
  • 1
    This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. – Johan Jan 30 '19 at 20:07