<div dir="ltr"><div><div><div><div><div><div><div><div><div><div><div><div><div>Hi,<br><br></div>Let's say I have this module:<br><br>-module(hello).<br>-export([send_hello/1, receive_hello/0]).<br><br>send_hello(To) -><br>
 To ! {hello, self()}.<br><br>receive_hello() -><br> receive<br>  {hello, From} -><br>   {ok, From};<br>  Msg -><br>   {unknown_msg, Msg}<br> end. <br><br></div>which  gives the following abstract forms (lets bind to Forms for ease of reference):<br>
<br>[{attribute,1,file,{"../src/eaop_explore/hello.erl",1}},<br> {attribute,1,module,hello},<br> {attribute,2,export,[{send_hello,1},{receive_hello,0}]},<br> {function,4,send_hello,1,<br>     [{clause,4,<br>          [{var,4,'To'}],<br>
          [],<br>          [{op,5,'!',<br>               {var,5,'To'},<br>               {tuple,5,[{atom,5,hello},{call,5,{atom,5,self},[]}]}}]}]},<br> {function,7,receive_hello,0,<br>     [{clause,7,[],[],<br>
          [{'receive',8,<br>               [{clause,9,<br>                    [{tuple,9,[{atom,9,hello},{var,9,'From'}]}],<br>                    [],<br>                    [{tuple,10,[{atom,10,ok},{var,10,'From'}]}]},<br>
                {clause,11,<br>                    [{var,11,'Msg'}],<br>                    [],<br>                    [{tuple,12,[{atom,12,unknown_msg},{var,12,'Msg'}]}]}]}]}]},<br> {eof,13}]<br><br></div>
I would like to use the postorder/2 function in the comments of erl_syntax:<br><br>postorder(F, Tree) -><br>        F(case erl_syntax:subtrees(Tree) of<br>            [] -> Tree;<br>            List -> erl_syntax:update_tree(Tree,<br>
                                [[postorder(F, Subtree)<br>                                  || Subtree <- Group]<br>                                 || Group <- List])<br>          end).<br><br></div>to traverse a syntax tree and do some kind of manipulation.<br>
<br></div>The problems is that, although the documentation (or how I understood the doc anyway) claims that abstract forms are a subset of syntax trees, I cannot do the following:<br><br></div>postorder(getAtomFun(), Forms)<br>
<br></div>where:<br><br>getAtomFun() -><br>    fun(Node) -><br>        case erl_syntax:type(Node) of<br>            atom -><br>                case erl_syntax:atom_name(Node) of<br>                    "module" -> Node;<br>
                    "export" -> Node;<br>                    _ -> erl_syntax:atom("a_" ++ erl_syntax:atom_name(Node))<br>                end;<br>            _ -> <br>                Node<br>        end<br>
    end.<br><br></div>However, if Forms is constructed manually using the erl_syntax module, I can do that. e.g. taking a small part of Forms and constructing using erl_syntax (namely, only the module and export attributes), I can do the following:<br>
<br>get_tree() -><br>    erl_syntax:form_list([<br>        erl_syntax:attribute(erl_syntax:atom(module), [erl_syntax:atom(hello)]),<br>        erl_syntax:attribute(erl_syntax:atom(export), [<br>            erl_syntax:list([<br>
                erl_syntax:arity_qualifier(erl_syntax:atom(send_hello), erl_syntax:integer(1)),<br>                erl_syntax:arity_qualifier(erl_syntax:atom(receive_hello), erl_syntax:integer(0))<br>            ])<br>        ])<br>
    ]).<br><br><br>20> postorder(getAtomFun(), get_tree())<br></div>...<br></div>21> erl_syntax:revert_forms(v(20)).<br>[{attribute,0,module,a_hello},<br> {attribute,0,export,[{a_send_hello,1},{a_receive_hello,0}]}]<br>
<br><br></div>The problem is that I can't seem to be able to do such an operation unless I can somehow get the forms into syntax trees.<br><br></div>Is there a function I'm missing in erl_syntax which transforms from forms to syntax trees? (revert_forms/1 exists to do the transformation in the other way).<br>
<br></div>Regards,<br>Justin<br><div><div><div><div><div><div><br></div></div></div></div></div></div></div>