<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>