PageRenderTime 80ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/syntax_tools/src/erl_syntax.erl

https://github.com/gebi/jungerl
Erlang | 6765 lines | 2507 code | 852 blank | 3406 comment | 47 complexity | 84f69af772a3237def0c3ccbbad9bdce MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, AGPL-1.0
  1. %% =====================================================================
  2. %% Abstract Erlang syntax trees (`erl_parse'-compatible).
  3. %%
  4. %% Copyright (C) 1997-2004 Richard Carlsson
  5. %%
  6. %% This library is free software; you can redistribute it and/or modify
  7. %% it under the terms of the GNU Lesser General Public License as
  8. %% published by the Free Software Foundation; either version 2 of the
  9. %% License, or (at your option) any later version.
  10. %%
  11. %% This library is distributed in the hope that it will be useful, but
  12. %% WITHOUT ANY WARRANTY; without even the implied warranty of
  13. %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. %% Lesser General Public License for more details.
  15. %%
  16. %% You should have received a copy of the GNU Lesser General Public
  17. %% License along with this library; if not, write to the Free Software
  18. %% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  19. %% USA
  20. %%
  21. %% Author contact: richardc@csd.uu.se
  22. %%
  23. %% $Id$
  24. %%
  25. %% =====================================================================
  26. %%
  27. %% @doc Abstract Erlang syntax trees.
  28. %%
  29. %% <p> This module defines an abstract data type for representing Erlang
  30. %% source code as syntax trees, in a way that is backwards compatible
  31. %% with the data structures created by the Erlang standard library
  32. %% parser module <code>erl_parse</code> (often referred to as "parse
  33. %% trees", which is a bit of a misnomer). This means that all
  34. %% <code>erl_parse</code> trees are valid abstract syntax trees, but the
  35. %% reverse is not true: abstract syntax trees can in general not be used
  36. %% as input to functions expecting an <code>erl_parse</code> tree.
  37. %% However, as long as an abstract syntax tree represents a correct
  38. %% Erlang program, the function <a
  39. %% href="#revert-1"><code>revert/1</code></a> should be able to
  40. %% transform it to the corresponding <code>erl_parse</code>
  41. %% representation.</p>
  42. %%
  43. %% <p>A recommended starting point for the first-time user is the
  44. %% documentation of the <a
  45. %% href="#type-syntaxTree"><code>syntaxTree()</code></a> data type, and
  46. %% the function <a href="#type-1"><code>type/1</code></a>.</p>
  47. %%
  48. %% <h3><b>NOTES:</b></h3>
  49. %%
  50. %% <p>This module deals with the composition and decomposition of
  51. %% <em>syntactic</em> entities (as opposed to semantic ones); its
  52. %% purpose is to hide all direct references to the data structures used
  53. %% to represent these entities. With few exceptions, the functions in
  54. %% this module perform no semantic interpretation of their inputs, and
  55. %% in general, the user is assumed to pass type-correct arguments - if
  56. %% this is not done, the effects are not defined.</p>
  57. %%
  58. %% <p>With the exception of the <code>erl_parse</code> data structures,
  59. %% the internal representations of abstract syntax trees are subject to
  60. %% change without notice, and should not be documented outside this
  61. %% module. Furthermore, we do not give any guarantees on how an abstract
  62. %% syntax tree may or may not be represented, <em>with the following
  63. %% exceptions</em>: no syntax tree is represented by a single atom, such
  64. %% as <code>none</code>, by a list constructor <code>[X | Y]</code>, or
  65. %% by the empty list <code>[]</code>. This can be relied on when writing
  66. %% functions that operate on syntax trees.</p>
  67. %%
  68. %% @type syntaxTree(). An abstract syntax tree. The
  69. %% <code>erl_parse</code> "parse tree" representation is a subset of the
  70. %% <code>syntaxTree()</code> representation.
  71. %%
  72. %% <p>Every abstract syntax tree node has a <em>type</em>, given by the
  73. %% function <a href="#type-1"><code>type/1</code></a>. Each node also
  74. %% has associated <em>attributes</em>; see <a
  75. %% href="#get_attrs-1"><code>get_attrs/1</code></a> for details. The
  76. %% functions <a href="#make_tree-2"><code>make_tree/2</code></a> and <a
  77. %% href="#subtrees-1"><code>subtrees/1</code></a> are generic
  78. %% constructor/decomposition functions for abstract syntax trees. The
  79. %% functions <a href="#abstract-1"><code>abstract/1</code></a> and <a
  80. %% href="#concrete-1"><code>concrete/1</code></a> convert between
  81. %% constant Erlang terms and their syntactic representations. The set of
  82. %% syntax tree nodes is extensible through the <a
  83. %% href="#tree-2"><code>tree/2</code></a> function.</p>
  84. %%
  85. %% <p>A syntax tree can be transformed to the <code>erl_parse</code>
  86. %% representation with the <a href="#revert-1"><code>revert/1</code></a>
  87. %% function.</p>
  88. %%
  89. %% @end
  90. %% =====================================================================
  91. -module(erl_syntax).
  92. -export([type/1,
  93. is_leaf/1,
  94. is_form/1,
  95. is_literal/1,
  96. abstract/1,
  97. concrete/1,
  98. revert/1,
  99. revert_forms/1,
  100. subtrees/1,
  101. make_tree/2,
  102. update_tree/2,
  103. meta/1,
  104. get_pos/1,
  105. set_pos/2,
  106. copy_pos/2,
  107. get_precomments/1,
  108. set_precomments/2,
  109. add_precomments/2,
  110. get_postcomments/1,
  111. set_postcomments/2,
  112. add_postcomments/2,
  113. has_comments/1,
  114. remove_comments/1,
  115. copy_comments/2,
  116. join_comments/2,
  117. get_ann/1,
  118. set_ann/2,
  119. add_ann/2,
  120. copy_ann/2,
  121. get_attrs/1,
  122. set_attrs/2,
  123. copy_attrs/2,
  124. flatten_form_list/1,
  125. cons/2,
  126. list_head/1,
  127. list_tail/1,
  128. is_list_skeleton/1,
  129. is_proper_list/1,
  130. list_elements/1,
  131. list_length/1,
  132. normalize_list/1,
  133. compact_list/1,
  134. application/2,
  135. application/3,
  136. application_arguments/1,
  137. application_operator/1,
  138. arity_qualifier/2,
  139. arity_qualifier_argument/1,
  140. arity_qualifier_body/1,
  141. atom/1,
  142. is_atom/2,
  143. atom_value/1,
  144. atom_literal/1,
  145. atom_name/1,
  146. attribute/1,
  147. attribute/2,
  148. attribute_arguments/1,
  149. attribute_name/1,
  150. binary/1,
  151. binary_field/1,
  152. binary_field/2,
  153. binary_field/3,
  154. binary_field_body/1,
  155. binary_field_types/1,
  156. binary_field_size/1,
  157. binary_fields/1,
  158. block_expr/1,
  159. block_expr_body/1,
  160. case_expr/2,
  161. case_expr_argument/1,
  162. case_expr_clauses/1,
  163. catch_expr/1,
  164. catch_expr_body/1,
  165. char/1,
  166. is_char/2,
  167. char_value/1,
  168. char_literal/1,
  169. clause/2,
  170. clause/3,
  171. clause_body/1,
  172. clause_guard/1,
  173. clause_patterns/1,
  174. comment/1,
  175. comment/2,
  176. comment_padding/1,
  177. comment_text/1,
  178. cond_expr/1,
  179. cond_expr_clauses/1,
  180. conjunction/1,
  181. conjunction_body/1,
  182. disjunction/1,
  183. disjunction_body/1,
  184. eof_marker/0,
  185. error_marker/1,
  186. error_marker_info/1,
  187. float/1,
  188. float_value/1,
  189. float_literal/1,
  190. form_list/1,
  191. form_list_elements/1,
  192. fun_expr/1,
  193. fun_expr_arity/1,
  194. fun_expr_clauses/1,
  195. function/2,
  196. function_arity/1,
  197. function_clauses/1,
  198. function_name/1,
  199. generator/2,
  200. generator_body/1,
  201. generator_pattern/1,
  202. if_expr/1,
  203. if_expr_clauses/1,
  204. implicit_fun/1,
  205. implicit_fun/2,
  206. implicit_fun_name/1,
  207. infix_expr/3,
  208. infix_expr_left/1,
  209. infix_expr_operator/1,
  210. infix_expr_right/1,
  211. integer/1,
  212. is_integer/2,
  213. integer_value/1,
  214. integer_literal/1,
  215. list/1,
  216. list/2,
  217. list_comp/2,
  218. list_comp_body/1,
  219. list_comp_template/1,
  220. list_prefix/1,
  221. list_suffix/1,
  222. macro/1,
  223. macro/2,
  224. macro_arguments/1,
  225. macro_name/1,
  226. match_expr/2,
  227. match_expr_body/1,
  228. match_expr_pattern/1,
  229. module_qualifier/2,
  230. module_qualifier_argument/1,
  231. module_qualifier_body/1,
  232. nil/0,
  233. operator/1,
  234. operator_literal/1,
  235. operator_name/1,
  236. parentheses/1,
  237. parentheses_body/1,
  238. prefix_expr/2,
  239. prefix_expr_argument/1,
  240. prefix_expr_operator/1,
  241. qualified_name/1,
  242. qualified_name_segments/1,
  243. query_expr/1,
  244. query_expr_body/1,
  245. receive_expr/1,
  246. receive_expr/3,
  247. receive_expr_action/1,
  248. receive_expr_clauses/1,
  249. receive_expr_timeout/1,
  250. record_access/2,
  251. record_access/3,
  252. record_access_argument/1,
  253. record_access_field/1,
  254. record_access_type/1,
  255. record_expr/2,
  256. record_expr/3,
  257. record_expr_argument/1,
  258. record_expr_fields/1,
  259. record_expr_type/1,
  260. record_field/1,
  261. record_field/2,
  262. record_field_name/1,
  263. record_field_value/1,
  264. record_index_expr/2,
  265. record_index_expr_field/1,
  266. record_index_expr_type/1,
  267. rule/2,
  268. rule_arity/1,
  269. rule_clauses/1,
  270. rule_name/1,
  271. size_qualifier/2,
  272. size_qualifier_argument/1,
  273. size_qualifier_body/1,
  274. string/1,
  275. is_string/2,
  276. string_value/1,
  277. string_literal/1,
  278. text/1,
  279. text_string/1,
  280. try_expr/2,
  281. try_expr/3,
  282. try_expr/4,
  283. try_after_expr/2,
  284. try_expr_body/1,
  285. try_expr_clauses/1,
  286. try_expr_handlers/1,
  287. try_expr_after/1,
  288. class_qualifier/2,
  289. class_qualifier_argument/1,
  290. class_qualifier_body/1,
  291. tuple/1,
  292. tuple_elements/1,
  293. tuple_size/1,
  294. underscore/0,
  295. variable/1,
  296. variable_name/1,
  297. variable_literal/1,
  298. warning_marker/1,
  299. warning_marker_info/1,
  300. tree/1,
  301. tree/2,
  302. data/1,
  303. is_tree/1]).
  304. %% =====================================================================
  305. %% IMPLEMENTATION NOTES:
  306. %%
  307. %% All nodes are represented by tuples of arity 2 or greater, whose
  308. %% first element is an atom which uniquely identifies the type of the
  309. %% node. (In the backwards-compatible representation, the interpretation
  310. %% is also often dependent on the context; the second element generally
  311. %% holds the position information - with a couple of exceptions; see
  312. %% `get_pos' and `set_pos' for details). In the documentation of this
  313. %% module, `Pos' is the source code position information associated with
  314. %% a node; usually, this is a positive integer indicating the original
  315. %% source code line, but no assumptions are made in this module
  316. %% regarding the format or interpretation of position information. When
  317. %% a syntax tree node is constructed, its associated position is by
  318. %% default set to the integer zero.
  319. %% =====================================================================
  320. -define(NO_UNUSED, true).
  321. %% =====================================================================
  322. %% Declarations of globally used internal data structures
  323. %% =====================================================================
  324. %% `com' records are used to hold comment information attached to a
  325. %% syntax tree node or a wrapper structure.
  326. %%
  327. %% #com{pre :: Pre, post :: Post}
  328. %%
  329. %% Pre = Post = [Com]
  330. %% Com = syntaxTree()
  331. %%
  332. %% type(Com) = comment
  333. -record(com, {pre = [],
  334. post = []}).
  335. %% `attr' records store node attributes as an aggregate.
  336. %%
  337. %% #attr{pos :: Pos, ann :: Ann, com :: Comments}
  338. %%
  339. %% Pos = term()
  340. %% Ann = [term()]
  341. %% Comments = none | #com{}
  342. %%
  343. %% where `Pos' `Ann' and `Comments' are the corresponding values of a
  344. %% `tree' or `wrapper' record.
  345. -record(attr, {pos = 0,
  346. ann = [],
  347. com = none}).
  348. %% `tree' records represent new-form syntax tree nodes.
  349. %%
  350. %% Tree = #tree{type :: Type, attr :: Attr, data :: Data}
  351. %%
  352. %% Type = atom()
  353. %% Attr = #attr{}
  354. %% Data = term()
  355. %%
  356. %% is_tree(Tree) = true
  357. -record(tree, {type,
  358. attr = #attr{},
  359. data}).
  360. %% `wrapper' records are used for attaching new-form node information to
  361. %% `erl_parse' trees.
  362. %%
  363. %% Wrapper = #wrapper{type :: Type, attr :: Attr, tree :: ParseTree}
  364. %%
  365. %% Type = atom()
  366. %% Attr = #attr{}
  367. %% ParseTree = term()
  368. %%
  369. %% is_tree(Wrapper) = false
  370. -record(wrapper, {type,
  371. attr = #attr{},
  372. tree}).
  373. %% =====================================================================
  374. %%
  375. %% Exported functions
  376. %%
  377. %% =====================================================================
  378. %% =====================================================================
  379. %% @spec type(Node::syntaxTree()) -> atom()
  380. %%
  381. %% @doc Returns the type tag of <code>Node</code>. If <code>Node</code>
  382. %% does not represent a syntax tree, evaluation fails with reason
  383. %% <code>badarg</code>. Node types currently defined by this module are:
  384. %% <p><center><table border="1">
  385. %% <tr>
  386. %% <td>application</td>
  387. %% <td>arity_qualifier</td>
  388. %% <td>atom</td>
  389. %% <td>attribute</td>
  390. %% </tr><tr>
  391. %% <td>binary</td>
  392. %% <td>binary_field</td>
  393. %% <td>block_expr</td>
  394. %% <td>case_expr</td>
  395. %% </tr><tr>
  396. %% <td>catch_expr</td>
  397. %% <td>char</td>
  398. %% <td>class_qualifier</td>
  399. %% <td>clause</td>
  400. %% </tr><tr>
  401. %% <td>comment</td>
  402. %% <td>cond_expr</td>
  403. %% <td>conjunction</td>
  404. %% <td>disjunction</td>
  405. %% </tr><tr>
  406. %% <td>eof_marker</td>
  407. %% <td>error_marker</td>
  408. %% <td>float</td>
  409. %% <td>form_list</td>
  410. %% </tr><tr>
  411. %% <td>fun_expr</td>
  412. %% <td>function</td>
  413. %% <td>generator</td>
  414. %% <td>if_expr</td>
  415. %% </tr><tr>
  416. %% <td>implicit_fun</td>
  417. %% <td>infix_expr</td>
  418. %% <td>integer</td>
  419. %% <td>list</td>
  420. %% </tr><tr>
  421. %% <td>list_comp</td>
  422. %% <td>macro</td>
  423. %% <td>match_expr</td>
  424. %% <td>module_qualifier</td>
  425. %% </tr><tr>
  426. %% <td>nil</td>
  427. %% <td>operator</td>
  428. %% <td>parentheses</td>
  429. %% <td>prefix_expr</td>
  430. %% </tr><tr>
  431. %% <td>qualified_name</td>
  432. %% <td>query_expr</td>
  433. %% <td>receive_expr</td>
  434. %% <td>record_access</td>
  435. %% </tr><tr>
  436. %% <td>record_expr</td>
  437. %% <td>record_field</td>
  438. %% <td>record_index_expr</td>
  439. %% <td>rule</td>
  440. %% </tr><tr>
  441. %% <td>size_qualifier</td>
  442. %% <td>string</td>
  443. %% <td>text</td>
  444. %% <td>try_expr</td>
  445. %% </tr><tr>
  446. %% <td>tuple</td>
  447. %% <td>underscore</td>
  448. %% <td>variable</td>
  449. %% <td>warning_marker</td>
  450. %% </tr>
  451. %% </table></center></p>
  452. %% <p>The user may (for special purposes) create additional nodes
  453. %% with other type tags, using the <code>tree/2</code> function.</p>
  454. %%
  455. %% <p>Note: The primary constructor functions for a node type should
  456. %% always have the same name as the node type itself.</p>
  457. %%
  458. %% @see tree/2
  459. %% @see application/3
  460. %% @see arity_qualifier/2
  461. %% @see atom/1
  462. %% @see attribute/2
  463. %% @see binary/1
  464. %% @see binary_field/2
  465. %% @see block_expr/1
  466. %% @see case_expr/2
  467. %% @see catch_expr/1
  468. %% @see char/1
  469. %% @see class_qualifier/2
  470. %% @see clause/3
  471. %% @see comment/2
  472. %% @see cond_expr/1
  473. %% @see conjunction/1
  474. %% @see disjunction/1
  475. %% @see eof_marker/0
  476. %% @see error_marker/1
  477. %% @see float/1
  478. %% @see form_list/1
  479. %% @see fun_expr/1
  480. %% @see function/2
  481. %% @see generator/2
  482. %% @see if_expr/1
  483. %% @see implicit_fun/2
  484. %% @see infix_expr/3
  485. %% @see integer/1
  486. %% @see list/2
  487. %% @see list_comp/2
  488. %% @see macro/2
  489. %% @see match_expr/2
  490. %% @see module_qualifier/2
  491. %% @see nil/0
  492. %% @see operator/1
  493. %% @see parentheses/1
  494. %% @see prefix_expr/2
  495. %% @see qualified_name/1
  496. %% @see query_expr/1
  497. %% @see receive_expr/3
  498. %% @see record_access/3
  499. %% @see record_expr/2
  500. %% @see record_field/2
  501. %% @see record_index_expr/2
  502. %% @see rule/2
  503. %% @see size_qualifier/2
  504. %% @see string/1
  505. %% @see text/1
  506. %% @see try_expr/3
  507. %% @see tuple/1
  508. %% @see underscore/0
  509. %% @see variable/1
  510. %% @see warning_marker/1
  511. type(#tree{type = T}) ->
  512. T;
  513. type(#wrapper{type = T}) ->
  514. T;
  515. type(Node) ->
  516. %% Check for `erl_parse'-compatible nodes, and otherwise fail.
  517. case Node of
  518. %% Leaf types
  519. {atom, _, _} -> atom;
  520. {char, _, _} -> char;
  521. {float, _, _} -> float;
  522. {integer, _, _} -> integer;
  523. {nil, _} -> nil;
  524. {string, _, _} -> string;
  525. {var, _, Name} ->
  526. if Name == '_' -> underscore;
  527. true -> variable
  528. end;
  529. {error, _} -> error_marker;
  530. {warning, _} -> warning_marker;
  531. {eof, _} -> eof_marker;
  532. %% Composite types
  533. {'case', _, _, _} -> case_expr;
  534. {'catch', _, _} -> catch_expr;
  535. {'cond', _, _} -> cond_expr;
  536. {'fun', _, {clauses, _}} -> fun_expr;
  537. {'fun', _, {function, _, _}} -> implicit_fun;
  538. {'if', _, _} -> if_expr;
  539. {'receive', _, _, _, _} -> receive_expr;
  540. {'receive', _, _} -> receive_expr;
  541. {attribute, _, _, _} -> attribute;
  542. {bin, _, _} -> binary;
  543. {bin_element, _, _, _, _} -> binary_field;
  544. {block, _, _} -> block_expr;
  545. {call, _, _, _} -> application;
  546. {clause, _, _, _, _} -> clause;
  547. {cons, _, _, _} -> list;
  548. {function, _, _, _, _} -> function;
  549. {generate, _, _, _} -> generator;
  550. {lc, _, _, _} -> list_comp;
  551. {match, _, _, _} -> match_expr;
  552. {op, _, _, _, _} -> infix_expr;
  553. {op, _, _, _} -> prefix_expr;
  554. {'query', _, _} -> query_expr;
  555. {record, _, _, _, _} -> record_expr;
  556. {record, _, _, _} -> record_expr;
  557. {record_field, _, _, _, _} -> record_access;
  558. {record_field, _, _, _} ->
  559. case is_qualified_name(Node) of
  560. true -> qualified_name;
  561. false -> record_access
  562. end;
  563. {record_index, _, _, _} -> record_index_expr;
  564. {remote, _, _, _} -> module_qualifier;
  565. {rule, _, _, _, _} -> rule;
  566. {'try', _, _, _, _, _} -> try_expr;
  567. {tuple, _, _} -> tuple;
  568. _ ->
  569. erlang:fault({badarg, Node})
  570. end.
  571. %% =====================================================================
  572. %% @spec is_leaf(Node::syntaxTree()) -> bool()
  573. %%
  574. %% @doc Returns <code>true</code> if <code>Node</code> is a leaf node,
  575. %% otherwise <code>false</code>. The currently recognised leaf node
  576. %% types are:
  577. %% <p><center><table border="1">
  578. %% <tr>
  579. %% <td><code>atom</code></td>
  580. %% <td><code>char</code></td>
  581. %% <td><code>comment</code></td>
  582. %% <td><code>eof_marker</code></td>
  583. %% <td><code>error_marker</code></td>
  584. %% </tr><tr>
  585. %% <td><code>float</code></td>
  586. %% <td><code>integer</code></td>
  587. %% <td><code>nil</code></td>
  588. %% <td><code>operator</code></td>
  589. %% <td><code>string</code></td>
  590. %% </tr><tr>
  591. %% <td><code>text</code></td>
  592. %% <td><code>underscore</code></td>
  593. %% <td><code>variable</code></td>
  594. %% <td><code>warning_marker</code></td>
  595. %% </tr>
  596. %% </table></center></p>
  597. %% <p>A node of type <code>tuple</code> is a leaf node if and only if
  598. %% its arity is zero.</p>
  599. %%
  600. %% <p>Note: not all literals are leaf nodes, and vice versa. E.g.,
  601. %% tuples with nonzero arity and nonempty lists may be literals, but are
  602. %% not leaf nodes. Variables, on the other hand, are leaf nodes but not
  603. %% literals.</p>
  604. %%
  605. %% @see type/1
  606. %% @see is_literal/1
  607. is_leaf(Node) ->
  608. case type(Node) of
  609. atom -> true;
  610. char -> true;
  611. comment -> true; % nonstandard type
  612. eof_marker -> true;
  613. error_marker -> true;
  614. float -> true;
  615. integer -> true;
  616. nil -> true;
  617. operator -> true; % nonstandard type
  618. string -> true;
  619. text -> true; % nonstandard type
  620. tuple ->
  621. case tuple_elements(Node) of
  622. [] -> true;
  623. _ -> false
  624. end;
  625. underscore -> true;
  626. variable -> true;
  627. warning_marker -> true;
  628. _ -> false
  629. end.
  630. %% =====================================================================
  631. %% @spec is_form(Node::syntaxTree()) -> bool()
  632. %%
  633. %% @doc Returns <code>true</code> if <code>Node</code> is a syntax tree
  634. %% representing a so-called "source code form", otherwise
  635. %% <code>false</code>. Forms are the Erlang source code units which,
  636. %% placed in sequence, constitute an Erlang program. Current form types
  637. %% are:
  638. %% <p><center><table border="1">
  639. %% <tr>
  640. %% <td><code>attribute</code></td>
  641. %% <td><code>comment</code></td>
  642. %% <td><code>error_marker</code></td>
  643. %% <td><code>eof_marker</code></td>
  644. %% </tr><tr>
  645. %% <td><code>form_list</code></td>
  646. %% <td><code>function</code></td>
  647. %% <td><code>rule</code></td>
  648. %% <td><code>warning_marker</code></td>
  649. %% </tr>
  650. %% </table></center></p>
  651. %% @see type/1
  652. %% @see attribute/2
  653. %% @see comment/2
  654. %% @see eof_marker/1
  655. %% @see error_marker/1
  656. %% @see form_list/1
  657. %% @see function/2
  658. %% @see rule/2
  659. %% @see warning_marker/1
  660. is_form(Node) ->
  661. case type(Node) of
  662. attribute -> true;
  663. comment -> true;
  664. function -> true;
  665. eof_marker -> true;
  666. error_marker -> true;
  667. form_list -> true;
  668. rule -> true;
  669. warning_marker -> true;
  670. _ -> false
  671. end.
  672. %% =====================================================================
  673. %% @spec get_pos(Node::syntaxTree()) -> term()
  674. %%
  675. %% @doc Returns the position information associated with
  676. %% <code>Node</code>. This is usually a nonnegative integer (indicating
  677. %% the source code line number), but may be any term. By default, all
  678. %% new tree nodes have their associated position information set to the
  679. %% integer zero.
  680. %%
  681. %% @see set_pos/2
  682. %% @see get_attrs/1
  683. %% All `erl_parse' tree nodes are represented by tuples whose second
  684. %% field is the position information (usually an integer), *with the
  685. %% exceptions of* `{error, ...}' (type `error_marker') and `{warning,
  686. %% ...}' (type `warning_marker'), which only contain the associated line
  687. %% number *of the error descriptor*; this is all handled transparently
  688. %% by `get_pos' and `set_pos'.
  689. get_pos(#tree{attr = Attr}) ->
  690. Attr#attr.pos;
  691. get_pos(#wrapper{attr = Attr}) ->
  692. Attr#attr.pos;
  693. get_pos({error, {Pos, _, _}}) ->
  694. Pos;
  695. get_pos({warning, {Pos, _, _}}) ->
  696. Pos;
  697. get_pos(Node) ->
  698. %% Here, we assume that we have an `erl_parse' node with position
  699. %% information in element 2.
  700. element(2, Node).
  701. %% =====================================================================
  702. %% @spec set_pos(Node::syntaxTree(), Pos::term()) -> syntaxTree()
  703. %%
  704. %% @doc Sets the position information of <code>Node</code> to
  705. %% <code>Pos</code>.
  706. %%
  707. %% @see get_pos/1
  708. %% @see copy_pos/2
  709. set_pos(Node, Pos) ->
  710. case Node of
  711. #tree{attr = Attr} ->
  712. Node#tree{attr = Attr#attr{pos = Pos}};
  713. #wrapper{attr = Attr} ->
  714. Node#wrapper{attr = Attr#attr{pos = Pos}};
  715. _ ->
  716. %% We then assume we have an `erl_parse' node, and create a
  717. %% wrapper around it to make things more uniform.
  718. set_pos(wrap(Node), Pos)
  719. end.
  720. %% =====================================================================
  721. %% @spec copy_pos(Source::syntaxTree(), Target::syntaxTree()) ->
  722. %% syntaxTree()
  723. %%
  724. %% @doc Copies the position information from <code>Source</code> to
  725. %% <code>Target</code>.
  726. %%
  727. %% <p>This is equivalent to <code>set_pos(Target,
  728. %% get_pos(Source))</code>, but potentially more efficient.</p>
  729. %%
  730. %% @see get_pos/1
  731. %% @see set_pos/2
  732. copy_pos(Source, Target) ->
  733. set_pos(Target, get_pos(Source)).
  734. %% =====================================================================
  735. %% `get_com' and `set_com' are for internal use only.
  736. get_com(#tree{attr = Attr}) -> Attr#attr.com;
  737. get_com(#wrapper{attr = Attr}) -> Attr#attr.com;
  738. get_com(_) -> none.
  739. set_com(Node, Com) ->
  740. case Node of
  741. #tree{attr = Attr} ->
  742. Node#tree{attr = Attr#attr{com = Com}};
  743. #wrapper{attr = Attr} ->
  744. Node#wrapper{attr = Attr#attr{com = Com}};
  745. _ ->
  746. set_com(wrap(Node), Com)
  747. end.
  748. %% =====================================================================
  749. %% @spec get_precomments(syntaxTree()) -> [syntaxTree()]
  750. %%
  751. %% @doc Returns the associated pre-comments of a node. This is a
  752. %% possibly empty list of abstract comments, in top-down textual order.
  753. %% When the code is formatted, pre-comments are typically displayed
  754. %% directly above the node. For example:
  755. %% <pre>
  756. %% % Pre-comment of function
  757. %% foo(X) -> {bar, X}.</pre>
  758. %%
  759. %% <p>If possible, the comment should be moved before any preceding
  760. %% separator characters on the same line. E.g.:
  761. %% <pre>
  762. %% foo([X | Xs]) ->
  763. %% % Pre-comment of 'bar(X)' node
  764. %% [bar(X) | foo(Xs)];
  765. %% ...</pre>
  766. %% (where the comment is moved before the "<code>[</code>").</p>
  767. %%
  768. %% @see comment/2
  769. %% @see set_precomments/2
  770. %% @see get_postcomments/1
  771. %% @see get_attrs/1
  772. get_precomments(#tree{attr = Attr}) -> get_precomments_1(Attr);
  773. get_precomments(#wrapper{attr = Attr}) -> get_precomments_1(Attr);
  774. get_precomments(_) -> [].
  775. get_precomments_1(#attr{com = none}) -> [];
  776. get_precomments_1(#attr{com = #com{pre = Cs}}) -> Cs.
  777. %% =====================================================================
  778. %% @spec set_precomments(Node::syntaxTree(),
  779. %% Comments::[syntaxTree()]) -> syntaxTree()
  780. %%
  781. %% @doc Sets the pre-comments of <code>Node</code> to
  782. %% <code>Comments</code>. <code>Comments</code> should be a possibly
  783. %% empty list of abstract comments, in top-down textual order.
  784. %%
  785. %% @see comment/2
  786. %% @see get_precomments/1
  787. %% @see add_precomments/2
  788. %% @see set_postcomments/2
  789. %% @see copy_comments/2
  790. %% @see remove_comments/1
  791. %% @see join_comments/2
  792. set_precomments(Node, Cs) ->
  793. case Node of
  794. #tree{attr = Attr} ->
  795. Node#tree{attr = set_precomments_1(Attr, Cs)};
  796. #wrapper{attr = Attr} ->
  797. Node#wrapper{attr = set_precomments_1(Attr, Cs)};
  798. _ ->
  799. set_precomments(wrap(Node), Cs)
  800. end.
  801. set_precomments_1(#attr{com = none} = Attr, Cs) ->
  802. Attr#attr{com = #com{pre = Cs}};
  803. set_precomments_1(#attr{com = Com} = Attr, Cs) ->
  804. Attr#attr{com = Com#com{pre = Cs}}.
  805. %% =====================================================================
  806. %% @spec add_precomments(Comments::[syntaxTree()],
  807. %% Node::syntaxTree()) -> syntaxTree()
  808. %%
  809. %% @doc Appends <code>Comments</code> to the pre-comments of
  810. %% <code>Node</code>.
  811. %%
  812. %% <p>Note: This is equivalent to <code>set_precomments(Node,
  813. %% get_precomments(Node) ++ Comments)</code>, but potentially more
  814. %% efficient.</p>
  815. %%
  816. %% @see comment/2
  817. %% @see get_precomments/1
  818. %% @see set_precomments/2
  819. %% @see add_postcomments/2
  820. %% @see join_comments/2
  821. add_precomments(Cs, Node) ->
  822. case Node of
  823. #tree{attr = Attr} ->
  824. Node#tree{attr = add_precomments_1(Cs, Attr)};
  825. #wrapper{attr = Attr} ->
  826. Node#wrapper{attr = add_precomments_1(Cs, Attr)};
  827. _ ->
  828. add_precomments(Cs, wrap(Node))
  829. end.
  830. add_precomments_1(Cs, #attr{com = none} = Attr) ->
  831. Attr#attr{com = #com{pre = Cs}};
  832. add_precomments_1(Cs, #attr{com = Com} = Attr) ->
  833. Attr#attr{com = Com#com{pre = Com#com.pre ++ Cs}}.
  834. %% =====================================================================
  835. %% @spec get_postcomments(syntaxTree()) -> [syntaxTree()]
  836. %%
  837. %% @doc Returns the associated post-comments of a node. This is a
  838. %% possibly empty list of abstract comments, in top-down textual order.
  839. %% When the code is formatted, post-comments are typically displayed to
  840. %% the right of and/or below the node. For example:
  841. %% <pre>
  842. %% {foo, X, Y} % Post-comment of tuple</pre>
  843. %%
  844. %% <p>If possible, the comment should be moved past any following
  845. %% separator characters on the same line, rather than placing the
  846. %% separators on the following line. E.g.:
  847. %% <pre>
  848. %% foo([X | Xs], Y) ->
  849. %% foo(Xs, bar(X)); % Post-comment of 'bar(X)' node
  850. %% ...</pre>
  851. %% (where the comment is moved past the rightmost "<code>)</code>" and
  852. %% the "<code>;</code>").</p>
  853. %%
  854. %% @see comment/2
  855. %% @see set_postcomments/2
  856. %% @see get_precomments/1
  857. %% @see get_attrs/1
  858. get_postcomments(#tree{attr = Attr}) -> get_postcomments_1(Attr);
  859. get_postcomments(#wrapper{attr = Attr}) -> get_postcomments_1(Attr);
  860. get_postcomments(_) -> [].
  861. get_postcomments_1(#attr{com = none}) -> [];
  862. get_postcomments_1(#attr{com = #com{post = Cs}}) -> Cs.
  863. %% =====================================================================
  864. %% @spec set_postcomments(Node::syntaxTree(),
  865. %% Comments::[syntaxTree()]) -> syntaxTree()
  866. %%
  867. %% @doc Sets the post-comments of <code>Node</code> to
  868. %% <code>Comments</code>. <code>Comments</code> should be a possibly
  869. %% empty list of abstract comments, in top-down textual order
  870. %%
  871. %% @see comment/2
  872. %% @see get_postcomments/1
  873. %% @see add_postcomments/2
  874. %% @see set_precomments/2
  875. %% @see copy_comments/2
  876. %% @see remove_comments/1
  877. %% @see join_comments/2
  878. set_postcomments(Node, Cs) ->
  879. case Node of
  880. #tree{attr = Attr} ->
  881. Node#tree{attr = set_postcomments_1(Attr, Cs)};
  882. #wrapper{attr = Attr} ->
  883. Node#wrapper{attr = set_postcomments_1(Attr, Cs)};
  884. _ ->
  885. set_postcomments(wrap(Node), Cs)
  886. end.
  887. set_postcomments_1(#attr{com = none} = Attr, Cs) ->
  888. Attr#attr{com = #com{post = Cs}};
  889. set_postcomments_1(#attr{com = Com} = Attr, Cs) ->
  890. Attr#attr{com = Com#com{post = Cs}}.
  891. %% =====================================================================
  892. %% @spec add_postcomments(Comments::[syntaxTree()],
  893. %% Node::syntaxTree()) -> syntaxTree()
  894. %%
  895. %% @doc Appends <code>Comments</code> to the post-comments of
  896. %% <code>Node</code>.
  897. %%
  898. %% <p>Note: This is equivalent to <code>set_postcomments(Node,
  899. %% get_postcomments(Node) ++ Comments)</code>, but potentially more
  900. %% efficient.</p>
  901. %%
  902. %% @see comment/2
  903. %% @see get_postcomments/1
  904. %% @see set_postcomments/2
  905. %% @see add_precomments/2
  906. %% @see join_comments/2
  907. add_postcomments(Cs, Node) ->
  908. case Node of
  909. #tree{attr = Attr} ->
  910. Node#tree{attr = add_postcomments_1(Cs, Attr)};
  911. #wrapper{attr = Attr} ->
  912. Node#wrapper{attr = add_postcomments_1(Cs, Attr)};
  913. _ ->
  914. add_postcomments(Cs, wrap(Node))
  915. end.
  916. add_postcomments_1(Cs, #attr{com = none} = Attr) ->
  917. Attr#attr{com = #com{post = Cs}};
  918. add_postcomments_1(Cs, #attr{com = Com} = Attr) ->
  919. Attr#attr{com = Com#com{post = Com#com.post ++ Cs}}.
  920. %% =====================================================================
  921. %% @spec has_comments(Node::syntaxTree()) -> bool()
  922. %%
  923. %% @doc Yields <code>false</code> if the node has no associated
  924. %% comments, and <code>true</code> otherwise.
  925. %%
  926. %% <p>Note: This is equivalent to <code>(get_precomments(Node) == [])
  927. %% and (get_postcomments(Node) == [])</code>, but potentially more
  928. %% efficient.</p>
  929. %%
  930. %% @see get_precomments/1
  931. %% @see get_postcomments/1
  932. %% @see remove_comments/1
  933. has_comments(#tree{attr = Attr}) ->
  934. case Attr#attr.com of
  935. none -> false;
  936. #com{pre = [], post = []} -> false;
  937. _ -> true
  938. end;
  939. has_comments(#wrapper{attr = Attr}) ->
  940. case Attr#attr.com of
  941. none -> false;
  942. #com{pre = [], post = []} -> false;
  943. _ -> true
  944. end;
  945. has_comments(_) -> false.
  946. %% =====================================================================
  947. %% @spec remove_comments(Node::syntaxTree()) -> syntaxTree()
  948. %%
  949. %% @doc Clears the associated comments of <code>Node</code>.
  950. %%
  951. %% <p>Note: This is equivalent to
  952. %% <code>set_precomments(set_postcomments(Node, []), [])</code>, but
  953. %% potentially more efficient.</p>
  954. %%
  955. %% @see set_precomments/2
  956. %% @see set_postcomments/2
  957. remove_comments(Node) ->
  958. case Node of
  959. #tree{attr = Attr} ->
  960. Node#tree{attr = Attr#attr{com = none}};
  961. #wrapper{attr = Attr} ->
  962. Node#wrapper{attr = Attr#attr{com = none}};
  963. _ ->
  964. Node
  965. end.
  966. %% =====================================================================
  967. %% @spec copy_comments(Source::syntaxTree(), Target::syntaxTree()) ->
  968. %% syntaxTree()
  969. %%
  970. %% @doc Copies the pre- and postcomments from <code>Source</code> to
  971. %% <code>Target</code>.
  972. %%
  973. %% <p>Note: This is equivalent to
  974. %% <code>set_postcomments(set_precomments(Target,
  975. %% get_precomments(Source)), get_postcomments(Source))</code>, but
  976. %% potentially more efficient.</p>
  977. %%
  978. %% @see comment/2
  979. %% @see get_precomments/1
  980. %% @see get_postcomments/1
  981. %% @see set_precomments/2
  982. %% @see set_postcomments/2
  983. copy_comments(Source, Target) ->
  984. set_com(Target, get_com(Source)).
  985. %% =====================================================================
  986. %% @spec join_comments(Source::syntaxTree(), Target::syntaxTree()) ->
  987. %% syntaxTree()
  988. %%
  989. %% @doc Appends the comments of <code>Source</code> to the current
  990. %% comments of <code>Target</code>.
  991. %%
  992. %% <p>Note: This is equivalent to
  993. %% <code>add_postcomments(get_postcomments(Source),
  994. %% add_precomments(get_precomments(Source), Target))</code>, but
  995. %% potentially more efficient.</p>
  996. %%
  997. %% @see comment/2
  998. %% @see get_precomments/1
  999. %% @see get_postcomments/1
  1000. %% @see add_precomments/2
  1001. %% @see add_postcomments/2
  1002. join_comments(Source, Target) ->
  1003. add_postcomments(
  1004. get_postcomments(Source),
  1005. add_precomments(get_precomments(Source), Target)).
  1006. %% =====================================================================
  1007. %% @spec get_ann(syntaxTree()) -> [term()]
  1008. %%
  1009. %% @doc Returns the list of user annotations associated with a syntax
  1010. %% tree node. For a newly created node, this is the empty list. The
  1011. %% annotations may be any terms.
  1012. %%
  1013. %% @see set_ann/2
  1014. %% @see get_attrs/1
  1015. get_ann(#tree{attr = Attr}) -> Attr#attr.ann;
  1016. get_ann(#wrapper{attr = Attr}) -> Attr#attr.ann;
  1017. get_ann(_) -> [].
  1018. %% =====================================================================
  1019. %% @spec set_ann(Node::syntaxTree(), Annotations::[term()]) ->
  1020. %% syntaxTree()
  1021. %%
  1022. %% @doc Sets the list of user annotations of <code>Node</code> to
  1023. %% <code>Annotations</code>.
  1024. %%
  1025. %% @see get_ann/1
  1026. %% @see add_ann/2
  1027. %% @see copy_ann/2
  1028. set_ann(Node, As) ->
  1029. case Node of
  1030. #tree{attr = Attr} ->
  1031. Node#tree{attr = Attr#attr{ann = As}};
  1032. #wrapper{attr = Attr} ->
  1033. Node#wrapper{attr = Attr#attr{ann = As}};
  1034. _ ->
  1035. %% Assume we have an `erl_parse' node and create a wrapper
  1036. %% structure to carry the annotation.
  1037. set_ann(wrap(Node), As)
  1038. end.
  1039. %% =====================================================================
  1040. %% @spec add_ann(Annotation::term(), Node::syntaxTree()) -> syntaxTree()
  1041. %%
  1042. %% @doc Appends the term <code>Annotation</code> to the list of user
  1043. %% annotations of <code>Node</code>.
  1044. %%
  1045. %% <p>Note: this is equivalent to <code>set_ann(Node, [Annotation |
  1046. %% get_ann(Node)])</code>, but potentially more efficient.</p>
  1047. %%
  1048. %% @see get_ann/1
  1049. %% @see set_ann/2
  1050. add_ann(A, Node) ->
  1051. case Node of
  1052. #tree{attr = Attr} ->
  1053. Node#tree{attr = Attr#attr{ann = [A | Attr#attr.ann]}};
  1054. #wrapper{attr = Attr} ->
  1055. Node#wrapper{attr = Attr#attr{ann = [A | Attr#attr.ann]}};
  1056. _ ->
  1057. %% Assume we have an `erl_parse' node and create a wrapper
  1058. %% structure to carry the annotation.
  1059. add_ann(A, wrap(Node))
  1060. end.
  1061. %% =====================================================================
  1062. %% @spec copy_ann(Source::syntaxTree(), Target::syntaxTree()) ->
  1063. %% syntaxTree()
  1064. %%
  1065. %% @doc Copies the list of user annotations from <code>Source</code> to
  1066. %% <code>Target</code>.
  1067. %%
  1068. %% <p>Note: this is equivalent to <code>set_ann(Target,
  1069. %% get_ann(Source))</code>, but potentially more efficient.</p>
  1070. %%
  1071. %% @see get_ann/1
  1072. %% @see set_ann/2
  1073. copy_ann(Source, Target) ->
  1074. set_ann(Target, get_ann(Source)).
  1075. %% =====================================================================
  1076. %% @spec get_attrs(syntaxTree()) -> syntaxTreeAttributes()
  1077. %%
  1078. %% @doc Returns a representation of the attributes associated with a
  1079. %% syntax tree node. The attributes are all the extra information that
  1080. %% can be attached to a node. Currently, this includes position
  1081. %% information, source code comments, and user annotations. The result
  1082. %% of this function cannot be inspected directly; only attached to
  1083. %% another node (cf. <code>set_attrs/2</code>).
  1084. %%
  1085. %% <p>For accessing individual attributes, see <code>get_pos/1</code>,
  1086. %% <code>get_ann/1</code>, <code>get_precomments/1</code> and
  1087. %% <code>get_postcomments/1</code>.</p>
  1088. %%
  1089. %% @type syntaxTreeAttributes(). This is an abstract representation of
  1090. %% syntax tree node attributes; see the function <a
  1091. %% href="#get_attrs-1"><code>get_attrs/1</code></a>.
  1092. %%
  1093. %% @see set_attrs/2
  1094. %% @see get_pos/1
  1095. %% @see get_ann/1
  1096. %% @see get_precomments/1
  1097. %% @see get_postcomments/1
  1098. get_attrs(#tree{attr = Attr}) -> Attr;
  1099. get_attrs(#wrapper{attr = Attr}) -> Attr;
  1100. get_attrs(Node) -> #attr{pos = get_pos(Node),
  1101. ann = get_ann(Node),
  1102. com = get_com(Node)}.
  1103. %% =====================================================================
  1104. %% @spec set_attrs(Node::syntaxTree(),
  1105. %% Attributes::syntaxTreeAttributes()) -> syntaxTree()
  1106. %%
  1107. %% @doc Sets the attributes of <code>Node</code> to
  1108. %% <code>Attributes</code>.
  1109. %%
  1110. %% @see get_attrs/1
  1111. %% @see copy_attrs/2
  1112. set_attrs(Node, Attr) ->
  1113. case Node of
  1114. #tree{} ->
  1115. Node#tree{attr = Attr};
  1116. #wrapper{} ->
  1117. Node#wrapper{attr = Attr};
  1118. _ ->
  1119. set_attrs(wrap(Node), Attr)
  1120. end.
  1121. %% =====================================================================
  1122. %% @spec copy_attrs(Source::syntaxTree(), Target::syntaxTree()) ->
  1123. %% syntaxTree()
  1124. %%
  1125. %% @doc Copies the attributes from <code>Source</code> to
  1126. %% <code>Target</code>.
  1127. %%
  1128. %% <p>Note: this is equivalent to <code>set_attrs(Target,
  1129. %% get_attrs(Source))</code>, but potentially more efficient.</p>
  1130. %%
  1131. %% @see get_attrs/1
  1132. %% @see set_attrs/2
  1133. copy_attrs(S, T) ->
  1134. set_attrs(T, get_attrs(S)).
  1135. %% =====================================================================
  1136. %% @spec comment(Strings) -> syntaxTree()
  1137. %% @equiv comment(none, Strings)
  1138. comment(Strings) ->
  1139. comment(none, Strings).
  1140. %% =====================================================================
  1141. %% @spec comment(Padding, Strings::[string()]) -> syntaxTree()
  1142. %% Padding = none | integer()
  1143. %%
  1144. %% @doc Creates an abstract comment with the given padding and text. If
  1145. %% <code>Strings</code> is a (possibly empty) list
  1146. %% <code>["<em>Txt1</em>", ..., "<em>TxtN</em>"]</code>, the result
  1147. %% represents the source code text
  1148. %% <pre>
  1149. %% %<em>Txt1</em>
  1150. %% ...
  1151. %% %<em>TxtN</em></pre>
  1152. %% <code>Padding</code> states the number of empty character positions
  1153. %% to the left of the comment separating it horizontally from
  1154. %% source code on the same line (if any). If <code>Padding</code> is
  1155. %% <code>none</code>, a default positive number is used. If
  1156. %% <code>Padding</code> is an integer less than 1, there should be no
  1157. %% separating space. Comments are in themselves regarded as source
  1158. %% program forms.
  1159. %%
  1160. %% @see comment/1
  1161. %% @see is_form/1
  1162. -record(comment, {pad, text}).
  1163. %% type(Node) = comment
  1164. %% data(Node) = #comment{pad :: Padding, text :: Strings}
  1165. %%
  1166. %% Padding = none | integer()
  1167. %% Strings = [string()]
  1168. comment(Pad, Strings) ->
  1169. tree(comment, #comment{pad = Pad, text = Strings}).
  1170. %% =====================================================================
  1171. %% @spec comment_text(Node::syntaxTree()) -> [string()]
  1172. %%
  1173. %% @doc Returns the lines of text of the abstract comment.
  1174. %%
  1175. %% @see comment/2
  1176. comment_text(Node) ->
  1177. (data(Node))#comment.text.
  1178. %% =====================================================================
  1179. %% @spec comment_padding(Node::syntaxTree()) -> none | integer()
  1180. %%
  1181. %% @doc Returns the amount of padding before the comment, or
  1182. %% <code>none</code>. The latter means that a default padding may be
  1183. %% used.
  1184. %%
  1185. %% @see comment/2
  1186. comment_padding(Node) ->
  1187. (data(Node))#comment.pad.
  1188. %% =====================================================================
  1189. %% @spec form_list(Forms::[syntaxTree()]) -> syntaxTree()
  1190. %%
  1191. %% @doc Creates an abstract sequence of "source code forms". If
  1192. %% <code>Forms</code> is <code>[F1, ..., Fn]</code>, where each
  1193. %% <code>Fi</code> is a form (cf. <code>is_form/1</code>, the result
  1194. %% represents
  1195. %% <pre>
  1196. %% <em>F1</em>
  1197. %% ...
  1198. %% <em>Fn</em></pre>
  1199. %% where the <code>Fi</code> are separated by one or more line breaks. A
  1200. %% node of type <code>form_list</code> is itself regarded as a source
  1201. %% code form; cf. <code>flatten_form_list/1</code>.
  1202. %%
  1203. %% <p>Note: this is simply a way of grouping source code forms as a
  1204. %% single syntax tree, usually in order to form an Erlang module
  1205. %% definition.</p>
  1206. %%
  1207. %% @see form_list_elements/1
  1208. %% @see is_form/1
  1209. %% @see flatten_form_list/1
  1210. %% type(Node) = form_list
  1211. %% data(Node) = [Form]
  1212. %%
  1213. %% Form = syntaxTree()
  1214. %% is_form(Form) = true
  1215. form_list(Forms) ->
  1216. tree(form_list, Forms).
  1217. %% =====================================================================
  1218. %% @spec form_list_elements(syntaxTree()) -> [syntaxTree()]
  1219. %%
  1220. %% @doc Returns the list of subnodes of a <code>form_list</code> node.
  1221. %%
  1222. %% @see form_list/1
  1223. form_list_elements(Node) ->
  1224. data(Node).
  1225. %% =====================================================================
  1226. %% @spec flatten_form_list(Node::syntaxTree()) -> syntaxTree()
  1227. %%
  1228. %% @doc Flattens sublists of a <code>form_list</code> node. Returns
  1229. %% <code>Node</code> with all subtrees of type <code>form_list</code>
  1230. %% recursively expanded, yielding a single "flat" abstract form
  1231. %% sequence.
  1232. %%
  1233. %% @see form_list/1
  1234. flatten_form_list(Node) ->
  1235. Fs = form_list_elements(Node),
  1236. Fs1 = lists:reverse(flatten_form_list_1(Fs, [])),
  1237. copy_attrs(Node, form_list(Fs1)).
  1238. flatten_form_list_1([F | Fs], As) ->
  1239. case type(F) of
  1240. form_list ->
  1241. As1 = flatten_form_list_1(form_list_elements(F), As),
  1242. flatten_form_list_1(Fs, As1);
  1243. _ ->
  1244. flatten_form_list_1(Fs, [F | As])
  1245. end;
  1246. flatten_form_list_1([], As) ->
  1247. As.
  1248. %% =====================================================================
  1249. %% @spec text(String::string()) -> syntaxTree()
  1250. %%
  1251. %% @doc Creates an abstract piece of source code text. The result
  1252. %% represents exactly the sequence of characters in <code>String</code>.
  1253. %% This is useful in cases when one wants full control of the resulting
  1254. %% output, e.g., for the appearance of floating-point numbers or macro
  1255. %% definitions.
  1256. %%
  1257. %% @see text_string/1
  1258. %% type(Node) = text
  1259. %% data(Node) = string()
  1260. text(String) ->
  1261. tree(text, String).
  1262. %% =====================================================================
  1263. %% @spec text_string(syntaxTree()) -> string()
  1264. %%
  1265. %% @doc Returns the character sequence represented by a
  1266. %% <code>text</code> node.
  1267. %%
  1268. %% @see text/1
  1269. text_string(Node) ->
  1270. data(Node).
  1271. %% =====================================================================
  1272. %% @spec variable(Name) -> syntaxTree()
  1273. %% Name = atom() | string()
  1274. %%
  1275. %% @doc Creates an abstract variable with the given name.
  1276. %% <code>Name</code> may be any atom or string that represents a
  1277. %% lexically valid variable name, but <em>not</em> a single underscore
  1278. %% character; cf. <code>underscore/0</code>.
  1279. %%
  1280. %% <p>Note: no checking is done whether the character sequence
  1281. %% represents a proper variable name, i.e., whether or not its first
  1282. %% character is an uppercase Erlang character, or whether it does not
  1283. %% contain control characters, whitespace, etc.</p>
  1284. %%
  1285. %% @see variable_name/1
  1286. %% @see variable_literal/1
  1287. %% @see underscore/0
  1288. %% type(Node) = variable
  1289. %% data(Node) = atom()
  1290. %%
  1291. %% `erl_parse' representation:
  1292. %%
  1293. %% {var, Pos, Name}
  1294. %%
  1295. %% Name = atom() \ '_'
  1296. variable(Name) when atom(Name) ->
  1297. tree(variable, Name);
  1298. variable(Name) ->
  1299. tree(variable, list_to_atom(Name)).
  1300. revert_variable(Node) ->
  1301. Pos = get_pos(Node),
  1302. Name = variable_name(Node),
  1303. {var, Pos, Name}.
  1304. %% =====================================================================
  1305. %% @spec variable_name(syntaxTree()) -> atom()
  1306. %%
  1307. %% @doc Returns the name of a <code>variable</code> node as an atom.
  1308. %%
  1309. %% @see variable/1
  1310. variable_name(Node) ->
  1311. case unwrap(Node) of
  1312. {var, _, Name} ->
  1313. Name;
  1314. Node1 ->
  1315. data(Node1)
  1316. end.
  1317. %% =====================================================================
  1318. %% @spec variable_literal(syntaxTree()) -> string()
  1319. %%
  1320. %% @doc Returns the name of a <code>variable</code> node as a string.
  1321. %%
  1322. %% @see variable/1
  1323. variable_literal(Node) ->
  1324. case unwrap(Node) of
  1325. {var, _, Name} ->
  1326. atom_to_list(Name);
  1327. Node1 ->
  1328. atom_to_list(data(Node1))
  1329. end.
  1330. %% =====================================================================
  1331. %% @spec underscore() -> syntaxTree()
  1332. %%
  1333. %% @doc Creates an abstract universal pattern ("<code>_</code>"). The
  1334. %% lexical representation is a single underscore character. Note that
  1335. %% this is <em>not</em> a variable, lexically speaking.
  1336. %%
  1337. %% @see variable/1
  1338. %% type(Node) = underscore
  1339. %% data(Node) = []
  1340. %%
  1341. %% `erl_parse' representation:
  1342. %%
  1343. %% {var, Pos, '_'}
  1344. underscore() ->
  1345. tree(underscore, []).
  1346. revert_underscore(Node) ->
  1347. Pos = get_pos(Node),
  1348. {var, Pos, '_'}.
  1349. %% =====================================================================
  1350. %% @spec integer(Value::integer()) -> syntaxTree()
  1351. %%
  1352. %% @doc Creates an abstract integer literal. The lexical representation
  1353. %% is the canonical decimal numeral of <code>Value</code>.
  1354. %%
  1355. %% @see integer_value/1
  1356. %% @see integer_literal/1
  1357. %% @see is_integer/2
  1358. %% type(Node) = integer
  1359. %% data(Node) = integer()
  1360. %%
  1361. %% `erl_parse' representation:
  1362. %%
  1363. %% {integer, Pos, Value}
  1364. %%
  1365. %% Value = integer()
  1366. integer(Value) ->
  1367. tree(integer, Value).
  1368. revert_integer(Node) ->
  1369. Pos = get_pos(Node),
  1370. {integer, Pos, integer_value(Node)}.
  1371. %% =====================================================================
  1372. %% @spec is_integer(Node::syntaxTree(), Value::integer()) -> bool()
  1373. %%
  1374. %% @doc Returns <code>true</code> if <code>Node</code> has type
  1375. %% <code>integer</code> and represents <code>Value</code>, otherwise
  1376. %% <code>false</code>.
  1377. %%
  1378. %% @see integer/1
  1379. is_integer(Node, Value) ->
  1380. case unwrap(Node) of
  1381. {integer, _, Value} ->
  1382. true;
  1383. #tree{type = integer, data = Value} ->
  1384. true;
  1385. _ ->
  1386. false
  1387. end.
  1388. %% =====================================================================
  1389. %% @spec integer_value(syntaxTree()) -> integer()
  1390. %%
  1391. %% @doc Returns the value represented by an <code>integer</code> node.
  1392. %%
  1393. %% @see integer/1
  1394. integer_value(Node) ->
  1395. case unwrap(Node) of
  1396. {integer, _, Value} ->
  1397. Value;
  1398. Node1 ->
  1399. data(Node1)
  1400. end.
  1401. %% =====================================================================
  1402. %% @spec integer_literal(syntaxTree()) -> string()
  1403. %%
  1404. %% @doc Returns the numeral string represented by an
  1405. %% <code>integer</code> node.
  1406. %%
  1407. %% @see integer/1
  1408. integer_literal(Node) ->
  1409. integer_to_list(integer_value(Node)).
  1410. %% =====================================================================
  1411. %% @spec float(Value::float()) -> syntaxTree()
  1412. %%
  1413. %% @doc Creates an abstract floating-point literal. The lexical
  1414. %% representation is the decimal floating-point numeral of
  1415. %% <code>Value</code>.
  1416. %%
  1417. %% @see float_value/1
  1418. %% @see float_literal/1
  1419. %% type(Node) = float
  1420. %% data(Node) = Value
  1421. %%
  1422. %% Value = float()
  1423. %%
  1424. %% `erl_parse' representation:
  1425. %%
  1426. %% {float, Pos, Value}
  1427. %%
  1428. %% Value = float()
  1429. %% Note that under current versions of Erlang, the name `float/1' cannot
  1430. %% be used for local calls (i.e., within the module) - it will be
  1431. %% overridden by the type conversion BIF of the same name, so always use
  1432. %% `make_float/1' for local calls.
  1433. float(Value) ->
  1434. make_float(Value).
  1435. make_float(Value) ->
  1436. tree(float, Value).
  1437. revert_float(Node) ->
  1438. Pos = get_pos(Node),
  1439. {float, Pos, float_value(Node)}.
  1440. %% =====================================================================
  1441. %% @spec float_value(syntaxTree()) -> float()
  1442. %%
  1443. %% @doc Returns the value represented by a <code>float</code> node. Note
  1444. %% that floating-point values should usually not be compared for
  1445. %% equality.
  1446. %%
  1447. %% @see float/1
  1448. float_value(Node) ->
  1449. case unwrap(Node) of
  1450. {float, _, Value} ->
  1451. Value;
  1452. Node1 ->
  1453. data(Node1)
  1454. end.
  1455. %% =====================================================================
  1456. %% @spec float_literal(syntaxTree()) -> string()
  1457. %%
  1458. %% @doc Returns the numeral string represented by a <code>float</code>
  1459. %% node.
  1460. %%
  1461. %% @see float/1
  1462. float_literal(Node) ->
  1463. float_to_list(float_value(Node)).
  1464. %% =====================================================================
  1465. %% @spec char(Value::char()) -> syntaxTree()
  1466. %%
  1467. %% @doc Creates an abstract character literal. The result represents
  1468. %% "<code>$<em>Name</em></code>", where <code>Name</code> corresponds to
  1469. %% <code>Value</code>.
  1470. %%
  1471. %% <p>Note: the literal corresponding to a particular character value is
  1472. %% not uniquely defined. E.g., the character "<code>a</code>" can be
  1473. %% written both as "<code>$a</code>" and "<code>$\141</code>", and a Tab
  1474. %% character can be written as "<code>$\11</code>", "<code>$\011</code>"
  1475. %% or "<code>$\t</code>".</p>
  1476. %%
  1477. %% @see char_value/1
  1478. %% @see char_literal/1
  1479. %% @see is_char/2
  1480. %% type(Node) = char
  1481. %% data(Node) = char()
  1482. %%
  1483. %% `erl_parse' representation:
  1484. %%
  1485. %% {char, Pos, Code}
  1486. %%
  1487. %% Code = integer()
  1488. char(Char) ->
  1489. tree(char, Char).
  1490. revert_char(Node) ->
  1491. Pos = get_pos(Node),
  1492. {char, Pos, char_value(Node)}.
  1493. %% =====================================================================
  1494. %% @spec is_char(Node::syntaxTree(), Value::char()) -> bool()
  1495. %%
  1496. %% @doc Returns <code>true</code> if <code>Node</code> has type
  1497. %% <code>char</code> and represents <code>Value</code>, otherwise
  1498. %% <code>false</code>.
  1499. %%
  1500. %% @see char/1
  1501. is_char(Node, Value) ->
  1502. case unwrap(Node) of
  1503. {char, _, Value} ->
  1504. true;
  1505. #tree{type = char, data = Value} ->
  1506. true;
  1507. _ ->
  1508. false
  1509. end.
  1510. %% =====================================================================
  1511. %% @spec char_value(syntaxTree()) -> char()
  1512. %%
  1513. %% @doc Returns the value represented by a <code>char</code> node.
  1514. %%
  1515. %% @see char/1
  1516. char_value(Node) ->
  1517. case unwrap(Node) of
  1518. {char, _, Char} ->
  1519. Char;
  1520. Node1 ->
  1521. data(Node1)
  1522. end.
  1523. %% =====================================================================
  1524. %% @spec char_literal(syntaxTree()) -> string()
  1525. %%
  1526. %% @doc Returns the literal string represented by a <code>char</code>
  1527. %% node. This includes the leading "<code>$</code>" character.
  1528. %%
  1529. %% @see char/1
  1530. char_literal(Node) ->
  1531. io_lib:write_char(char_value(Node)).
  1532. %% =====================================================================
  1533. %% @spec string(Value::string()) -> syntaxTree()
  1534. %%
  1535. %% @doc Creates an abstract string literal. The result represents
  1536. %% <code>"<em>Text</em>"</code> (including the surrounding
  1537. %% double-quotes), where <code>Text</code> corresponds to the sequence
  1538. %% of characters in <code>Value</code>, but not representing a
  1539. %% <em>specific</em> string literal. E.g., the result of
  1540. %% <code>string("x\ny")</code> represents any and all of
  1541. %% <code>"x\ny"</code>, <code>"x\12y"</code>, <code>"x\012y"</code> and
  1542. %% <code>"x\^Jy"</code>; cf. <code>char/1</code>.
  1543. %%
  1544. %% @see string_value/1
  1545. %% @see string_literal/1
  1546. %% @see is_string/2
  1547. %% @see char/1
  1548. %% type(Node) = string
  1549. %% data(Node) = string()
  1550. %%
  1551. %% `erl_parse' representation:
  1552. %%
  1553. %% {string, Pos, Chars}
  1554. %%
  1555. %% Chars = string()
  1556. string(String) ->
  1557. tree(string, String).
  1558. revert_string(Node) ->
  1559. Pos = get_pos(Node),
  1560. {string, Pos, string_value(Node)}.
  1561. %% =====================================================================
  1562. %% @spec is_string(Node::syntaxTree(), Value::string()) -> bool()
  1563. %%
  1564. %% @doc Returns <code>true</code> if <code>Node</code> has type
  1565. %% <code>string</code> and represents <code>Value</code>, otherwise
  1566. %% <code>false</code>.
  1567. %%
  1568. %% @see string/1
  1569. is_string(Node, Value) ->
  1570. case unwrap(Node) of
  1571. {string, _, Value} ->
  1572. true;
  1573. #tree{type = string, data = Value} ->
  1574. true;
  1575. _ ->
  1576. false
  1577. end.
  1578. %% =====================================================================
  1579. %% @spec string_value(syntaxTree()) -> string()
  1580. %%
  1581. %% @doc Returns the value represented by a <code>string</code> node.
  1582. %%
  1583. %% @see string/1
  1584. string_value(Node) ->
  1585. case unwrap(Node) of
  1586. {string, _, List} ->
  1587. List;
  1588. Node1 ->
  1589. data(Node1)
  1590. end.
  1591. %% =====================================================================
  1592. %% @spec string_literal(syntaxTree()) -> string()
  1593. %%
  1594. %% @doc Returns the literal string represented by a <code>string</code>
  1595. %% node. This includes surrounding double-quote characters.
  1596. %%
  1597. %% @see string/1
  1598. string_literal(Node) ->
  1599. io_lib:write_string(string_value(Node)).
  1600. %% =====================================================================
  1601. %% @spec atom(Name) -> syntaxTree()
  1602. %% Name = atom() | string()
  1603. %%
  1604. %% @doc Creates an abstract atom literal. The print name of the atom is
  1605. %% the character sequence represented by <code>Name</code>.
  1606. %%
  1607. %% @see atom_value/1
  1608. %% @see atom_name/1
  1609. %% @see atom_literal/1
  1610. %% @see is_atom/2
  1611. %% type(Node) = atom
  1612. %% data(Node) = atom()
  1613. %%
  1614. %% `erl_parse' representation:
  1615. %%
  1616. %% {atom, Pos, Value}
  1617. %%
  1618. %% Value = atom()
  1619. atom(Name) when atom(Name) ->
  1620. tree(atom, Name);
  1621. atom(Name) ->
  1622. tree(atom, list_to_atom(Name)).
  1623. revert_atom(Node) ->
  1624. Pos = get_pos(Node),
  1625. {atom, Pos, atom_value(Node)}.
  1626. %% =====================================================================
  1627. %% @spec is_atom(Node::syntaxTree(), Value::atom()) -> bool()
  1628. %%
  1629. %% @doc Returns <code>true</code> if <code>Node</code> has type
  1630. %% <code>atom</code> and represents <code>Value</code>, otherwise
  1631. %% <code>false</code>.
  1632. %%
  1633. %% @see atom/1
  1634. is_atom(Node, Value) ->
  1635. case unwrap(Node) of
  1636. {atom, _, Value} ->
  1637. true;
  1638. #tree{type = atom, data = Value} ->
  1639. true;
  1640. _ ->
  1641. false
  1642. end.
  1643. %% =====================================================================
  1644. %% @spec atom_value(syntaxTree())-> atom()
  1645. %%
  1646. %% @doc Returns the value represented by an <code>atom</code> node.
  1647. %%
  1648. %% @see atom/1
  1649. atom_value(Node) ->
  1650. case unwrap(Node) of
  1651. {atom, _, Name} ->
  1652. Name;
  1653. Node1 ->
  1654. data(Node1)
  1655. end.
  1656. %% =====================================================================
  1657. %% @spec atom_name(syntaxTree()) -> string()
  1658. %%
  1659. %% @doc Returns the printname of an <code>atom</code> node.
  1660. %%
  1661. %% @see atom/1
  1662. atom_name(Node) ->
  1663. atom_to_list(atom_value(Node)).
  1664. %% =====================================================================
  1665. %% @spec atom_literal(syntaxTree()) -> string()
  1666. %%
  1667. %% @doc Returns the literal string represented by an <code>atom</code>
  1668. %% node. This includes surrounding single-quote characters if necessary.
  1669. %%
  1670. %% <p>Note that e.g. the result of <code>atom("x\ny")</code> represents
  1671. %% any and all of <code>'x\ny'</code>, <code>'x\12y'</code>,
  1672. %% <code>'x\012y'</code> and <code>'x\^Jy\'</code>; cf.
  1673. %% <code>string/1</code>.</p>
  1674. %%
  1675. %% @see atom/1
  1676. %% @see string/1
  1677. atom_literal(Node) ->
  1678. io_lib:write_atom(atom_value(Node)).
  1679. %% =====================================================================
  1680. %% @spec tuple(Elements::[syntaxTree()]) -> syntaxTree()
  1681. %%
  1682. %% @doc Creates an abstract tuple. If <code>Elements</code> is
  1683. %% <code>[X1, ..., Xn]</code>, the result represents
  1684. %% "<code>{<em>X1</em>, ..., <em>Xn</em>}</code>".
  1685. %%
  1686. %% <p>Note: The Erlang language has distinct 1-tuples, i.e.,
  1687. %% <code>{X}</code> is always distinct from <code>X</code> itself.</p>
  1688. %%
  1689. %% @see tuple_elements/1
  1690. %% @see tuple_size/1
  1691. %% type(Node) = tuple
  1692. %% data(Node) = Elements
  1693. %%
  1694. %% Elements = [syntaxTree()]
  1695. %%
  1696. %% `erl_parse' representation:
  1697. %%
  1698. %% {tuple, Pos, Elements}
  1699. %%
  1700. %% Elements = [erl_parse()]
  1701. tuple(List) ->
  1702. tree(tuple, List).
  1703. revert_tuple(Node) ->
  1704. Pos = get_pos(Node),
  1705. {tuple, Pos, tuple_elements(Node)}.
  1706. %% =====================================================================
  1707. %% @spec tuple_elements(syntaxTree()) -> [syntaxTree()]
  1708. %%
  1709. %% @doc Returns the list of element subtrees of a <code>tuple</code>
  1710. %% node.
  1711. %%
  1712. %% @see tuple/1
  1713. tuple_elements(Node) ->
  1714. case unwrap(Node) of
  1715. {tuple, _, List} ->
  1716. List;
  1717. Node1 ->
  1718. data(Node1)
  1719. end.
  1720. %% =====================================================================
  1721. %% @spec tuple_size(syntaxTree()) -> integer()
  1722. %%
  1723. %% @doc Returns the number of elements of a <code>tuple</code> node.
  1724. %%
  1725. %% <p>Note: this is equivalent to
  1726. %% <code>length(tuple_elements(Node))</code>, but potentially more
  1727. %% efficient.</p>
  1728. %%
  1729. %% @see tuple/1
  1730. %% @see tuple_elements/1
  1731. tuple_size(Node) ->
  1732. length(tuple_elements(Node)).
  1733. %% =====================================================================
  1734. %% @spec list(List) -> syntaxTree()
  1735. %% @equiv list(List, none)
  1736. list(List) ->
  1737. list(List, none).
  1738. %% =====================================================================
  1739. %% @spec list(List, Tail) -> syntaxTree()
  1740. %% List = [syntaxTree()]
  1741. %% Tail = none | syntaxTree()
  1742. %%
  1743. %% @doc Constructs an abstract list skeleton. The result has type
  1744. %% <code>list</code> or <code>nil</code>. If <code>List</code> is a
  1745. %% nonempty list <code>[E1, ..., En]</code>, the result has type
  1746. %% <code>list</code> and represents either "<code>[<em>E1</em>, ...,
  1747. %% <em>En</em>]</code>", if <code>Tail</code> is <code>none</code>, or
  1748. %% otherwise "<code>[<em>E1</em>, ..., <em>En</em> |
  1749. %% <em>Tail</em>]</code>". If <code>List</code> is the empty list,
  1750. %% <code>Tail</code> <em>must</em> be <code>none</code>, and in that
  1751. %% case the result has type <code>nil</code> and represents
  1752. %% "<code>[]</code>" (cf. <code>nil/0</code>).
  1753. %%
  1754. %% <p>The difference between lists as semantic objects (built up of
  1755. %% individual "cons" and "nil" terms) and the various syntactic forms
  1756. %% for denoting lists may be bewildering at first. This module provides
  1757. %% functions both for exact control of the syntactic representation as
  1758. %% well as for the simple composition and deconstruction in terms of
  1759. %% cons and head/tail operations.</p>
  1760. %%
  1761. %% <p>Note: in <code>list(Elements, none)</code>, the "nil" list
  1762. %% terminator is implicit and has no associated information (cf.
  1763. %% <code>get_attrs/1</code>), while in the seemingly equivalent
  1764. %% <code>list(Elements, Tail)</code> when <code>Tail</code> has type
  1765. %% <code>nil</code>, the list terminator subtree <code>Tail</code> may
  1766. %% have attached attributes such as position, comments, and annotations,
  1767. %% which will be preserved in the result.</p>
  1768. %%
  1769. %% @see nil/0
  1770. %% @see list/1
  1771. %% @see list_prefix/1
  1772. %% @see list_suffix/1
  1773. %% @see cons/2
  1774. %% @see list_head/1
  1775. %% @see list_tail/1
  1776. %% @see is_list_skeleton/1
  1777. %% @see is_proper_list/1
  1778. %% @see list_elements/1
  1779. %% @see list_length/1
  1780. %% @see normalize_list/1
  1781. %% @see compact_list/1
  1782. %% @see get_attrs/1
  1783. -record(list, {prefix, suffix}).
  1784. %% type(Node) = list
  1785. %% data(Node) = #list{prefix :: Elements, suffix :: Tail}
  1786. %%
  1787. %% Elements = [syntaxTree()]
  1788. %% Tail = none | syntaxTree()
  1789. %%
  1790. %% `erl_parse' representation:
  1791. %%
  1792. %% {cons, Pos, Head, Tail}
  1793. %%
  1794. %% Head = Tail = [erl_parse()]
  1795. %%
  1796. %% This represents `[<Head> | <Tail>]', or more generally `[<Head>
  1797. %% <Suffix>]' where the form of <Suffix> can depend on the
  1798. %% structure of <Tail>; there is no fixed printed form.
  1799. list([], none) ->
  1800. nil();
  1801. list(Elements, Tail) when Elements /= [] ->
  1802. tree(list, #list{prefix = Elements, suffix = Tail}).
  1803. revert_list(Node) ->
  1804. Pos = get_pos(Node),
  1805. P = list_prefix(Node),
  1806. S = case list_suffix(Node) of
  1807. none ->
  1808. revert_nil(set_pos(nil(), Pos));
  1809. S1 ->
  1810. S1
  1811. end,
  1812. lists:foldr(fun (X, A) ->
  1813. {cons, Pos, X, A}
  1814. end,
  1815. S, P).
  1816. %% =====================================================================
  1817. %% @spec nil() -> syntaxTree()
  1818. %%
  1819. %% @doc Creates an abstract empty list. The result represents
  1820. %% "<code>[]</code>". The empty list is traditionally called "nil".
  1821. %%
  1822. %% @see list/2
  1823. %% @see is_list_skeleton/1
  1824. %% type(Node) = nil
  1825. %% data(Node) = term()
  1826. %%
  1827. %% `erl_parse' representation:
  1828. %%
  1829. %% {nil, Pos}
  1830. nil() ->
  1831. tree(nil).
  1832. revert_nil(Node) ->
  1833. Pos = get_pos(Node),
  1834. {nil, Pos}.
  1835. %% =====================================================================
  1836. %% @spec list_prefix(Node::syntaxTree()) -> [syntaxTree()]
  1837. %%
  1838. %% @doc Returns the prefix element subtrees of a <code>list</code> node.
  1839. %% If <code>Node</code> represents "<code>[<em>E1</em>, ...,
  1840. %% <em>En</em>]</code>" or "<code>[<em>E1</em>, ..., <em>En</em> |
  1841. %% <em>Tail</em>]</code>", the returned value is <code>[E1, ...,
  1842. %% En]</code>.
  1843. %%
  1844. %% @see list/2
  1845. list_prefix(Node) ->
  1846. case unwrap(Node) of
  1847. {cons, _, Head, _} ->
  1848. [Head];
  1849. Node1 ->
  1850. (data(Node1))#list.prefix
  1851. end.
  1852. %% =====================================================================
  1853. %% @spec list_suffix(Node::syntaxTree()) -> none | syntaxTree()
  1854. %%
  1855. %% @doc Returns the suffix subtree of a <code>list</code> node, if one
  1856. %% exists. If <code>Node</code> represents "<code>[<em>E1</em>, ...,
  1857. %% <em>En</em> | <em>Tail</em>]</code>", the returned value is
  1858. %% <code>Tail</code>, otherwise, i.e., if <code>Node</code> represents
  1859. %% "<code>[<em>E1</em>, ..., <em>En</em>]</code>", <code>none</code> is
  1860. %% returned.
  1861. %%
  1862. %% <p>Note that even if this function returns some <code>Tail</code>
  1863. %% that is not <code>none</code>, the type of <code>Tail</code> can be
  1864. %% <code>nil</code>, if the tail has been given explicitly, and the list
  1865. %% skeleton has not been compacted (cf.
  1866. %% <code>compact_list/1</code>).</p>
  1867. %%
  1868. %% @see list/2
  1869. %% @see nil/0
  1870. %% @see compact_list/1
  1871. list_suffix(Node) ->
  1872. case unwrap(Node) of
  1873. {cons, _, _, Tail} ->
  1874. %% If there could be comments/annotations on the tail node,
  1875. %% we should not return `none' even if it has type `nil'.
  1876. case Tail of
  1877. {nil, _} ->
  1878. none; % no interesting information is lost
  1879. _ ->
  1880. Tail
  1881. end;
  1882. Node1 ->
  1883. (data(Node1))#list.suffix
  1884. end.
  1885. %% =====================================================================
  1886. %% @spec cons(Head::syntaxTree(), Tail::syntaxTree()) -> syntaxTree()
  1887. %%
  1888. %% @doc "Optimising" list skeleton cons operation. Creates an abstract
  1889. %% list skeleton whose first element is <code>Head</code> and whose tail
  1890. %% corresponds to <code>Tail</code>. This is similar to
  1891. %% <code>list([Head], Tail)</code>, except that <code>Tail</code> may
  1892. %% not be <code>none</code>, and that the result does not necessarily
  1893. %% represent exactly "<code>[<em>Head</em> | <em>Tail</em>]</code>", but
  1894. %% may depend on the <code>Tail</code> subtree. E.g., if
  1895. %% <code>Tail</code> represents <code>[X, Y]</code>, the result may
  1896. %% represent "<code>[<em>Head</em>, X, Y]</code>", rather than
  1897. %% "<code>[<em>Head</em> | [X, Y]]</code>". Annotations on
  1898. %% <code>Tail</code> itself may be lost if <code>Tail</code> represents
  1899. %% a list skeleton, but comments on <code>Tail</code> are propagated to
  1900. %% the result.
  1901. %%
  1902. %% @see list/2
  1903. %% @see list_head/1
  1904. %% @see list_tail/1
  1905. cons(Head, Tail) ->
  1906. case type(Tail) of
  1907. list ->
  1908. copy_comments(Tail, list([Head | list_prefix(Tail)],
  1909. list_suffix(Tail)));
  1910. nil ->
  1911. copy_comments(Tail, list([Head]));
  1912. _ ->
  1913. list([Head], Tail)
  1914. end.
  1915. %% =====================================================================
  1916. %% @spec list_head(Node::syntaxTree()) -> syntaxTree()
  1917. %%
  1918. %% @doc Returns the head element subtree of a <code>list</code> node. If
  1919. %% <code>Node</code> represents "<code>[<em>Head</em> ...]</code>", the
  1920. %% result will represent "<code><em>Head</em></code>".
  1921. %%
  1922. %% @see list/2
  1923. %% @see list_tail/1
  1924. %% @see cons/2
  1925. list_head(Node) ->
  1926. hd(list_prefix(Node)).
  1927. %% =====================================================================
  1928. %% list_tail(Node::syntaxTree()) -> syntaxTree()
  1929. %%
  1930. %% @doc Returns the tail of a <code>list</code> node. If
  1931. %% <code>Node</code> represents a single-element list
  1932. %% "<code>[<em>E</em>]</code>", then the result has type
  1933. %% <code>nil</code>, representing "<code>[]</code>". If
  1934. %% <code>Node</code> represents "<code>[<em>E1</em>, <em>E2</em>
  1935. %% ...]</code>", the result will represent "<code>[<em>E2</em>
  1936. %% ...]</code>", and if <code>Node</code> represents
  1937. %% "<code>[<em>Head</em> | <em>Tail</em>]</code>", the result will
  1938. %% represent "<code><em>Tail</em></code>".
  1939. %%
  1940. %% @see list/2
  1941. %% @see list_head/1
  1942. %% @see cons/2
  1943. list_tail(Node) ->
  1944. Tail = list_suffix(Node),
  1945. case tl(list_prefix(Node)) of
  1946. [] ->
  1947. if Tail == none ->
  1948. nil(); % implicit list terminator.
  1949. true ->
  1950. Tail
  1951. end;
  1952. Es ->
  1953. list(Es, Tail) % `Es' is nonempty.
  1954. end.
  1955. %% =====================================================================
  1956. %% @spec is_list_skeleton(syntaxTree()) -> bool()
  1957. %%
  1958. %% @doc Returns <code>true</code> if <code>Node</code> has type
  1959. %% <code>list</code> or <code>nil</code>, otherwise <code>false</code>.
  1960. %%
  1961. %% @see list/2
  1962. %% @see nil/0
  1963. is_list_skeleton(Node) ->
  1964. case type(Node) of
  1965. list -> true;
  1966. nil -> true;
  1967. _ -> false
  1968. end.
  1969. %% =====================================================================
  1970. %% @spec is_proper_list(Node::syntaxTree()) -> bool()
  1971. %%
  1972. %% @doc Returns <code>true</code> if <code>Node</code> represents a
  1973. %% proper list, and <code>false</code> otherwise. A proper list is a
  1974. %% list skeleton either on the form "<code>[]</code>" or
  1975. %% "<code>[<em>E1</em>, ..., <em>En</em>]</code>", or "<code>[... |
  1976. %% <em>Tail</em>]</code>" where recursively <code>Tail</code> also
  1977. %% represents a proper list.
  1978. %%
  1979. %% <p>Note: Since <code>Node</code> is a syntax tree, the actual
  1980. %% run-time values corresponding to its subtrees may often be partially
  1981. %% or completely unknown. Thus, if <code>Node</code> represents e.g.
  1982. %% "<code>[... | Ns]</code>" (where <code>Ns</code> is a variable), then
  1983. %% the function will return <code>false</code>, because it is not known
  1984. %% whether <code>Ns</code> will be bound to a list at run-time. If
  1985. %% <code>Node</code> instead represents e.g. "<code>[1, 2, 3]</code>" or
  1986. %% "<code>[A | []]</code>", then the function will return
  1987. %% <code>true</code>.</p>
  1988. %%
  1989. %% @see list/2
  1990. is_proper_list(Node) ->
  1991. case type(Node) of
  1992. list ->
  1993. case list_suffix(Node) of
  1994. none ->
  1995. true;
  1996. Tail ->
  1997. is_proper_list(Tail)
  1998. end;
  1999. nil ->
  2000. true;
  2001. _ ->
  2002. false
  2003. end.
  2004. %% =====================================================================
  2005. %% @spec list_elements(Node::syntaxTree()) -> [syntaxTree()]
  2006. %%
  2007. %% @doc Returns the list of element subtrees of a list skeleton.
  2008. %% <code>Node</code> must represent a proper list. E.g., if
  2009. %% <code>Node</code> represents "<code>[<em>X1</em>, <em>X2</em> |
  2010. %% [<em>X3</em>, <em>X4</em> | []]</code>", then
  2011. %% <code>list_elements(Node)</code> yields the list <code>[X1, X2, X3,
  2012. %% X4]</code>.
  2013. %%
  2014. %% @see list/2
  2015. %% @see is_proper_list/1
  2016. list_elements(Node) ->
  2017. lists:reverse(list_elements(Node, [])).
  2018. list_elements(Node, As) ->
  2019. case type(Node) of
  2020. list ->
  2021. As1 = lists:reverse(list_prefix(Node)) ++ As,
  2022. case list_suffix(Node) of
  2023. none ->
  2024. As1;
  2025. Tail ->
  2026. list_elements(Tail, As1)
  2027. end;
  2028. nil ->
  2029. As
  2030. end.
  2031. %% =====================================================================
  2032. %% list_length(Node::syntaxTree()) -> integer()
  2033. %%
  2034. %% @doc Returns the number of element subtrees of a list skeleton.
  2035. %% <code>Node</code> must represent a proper list. E.g., if
  2036. %% <code>Node</code> represents "<code>[X1 | [X2, X3 | [X4, X5,
  2037. %% X6]]]</code>", then <code>list_length(Node)</code> returns the
  2038. %% integer 6.
  2039. %%
  2040. %% <p>Note: this is equivalent to
  2041. %% <code>length(list_elements(Node))</code>, but potentially more
  2042. %% efficient.</p>
  2043. %%
  2044. %% @see list/2
  2045. %% @see is_proper_list/1
  2046. %% @see list_elements/1
  2047. list_length(Node) ->
  2048. list_length(Node, 0).
  2049. list_length(Node, A) ->
  2050. case type(Node) of
  2051. list ->
  2052. A1 = length(list_prefix(Node)) + A,
  2053. case list_suffix(Node) of
  2054. none ->
  2055. A1;
  2056. Tail ->
  2057. list_length(Tail, A1)
  2058. end;
  2059. nil ->
  2060. A
  2061. end.
  2062. %% =====================================================================
  2063. %% @spec normalize_list(Node::syntaxTree()) -> syntaxTree()
  2064. %%
  2065. %% @doc Expands an abstract list skeleton to its most explicit form. If
  2066. %% <code>Node</code> represents "<code>[<em>E1</em>, ..., <em>En</em> |
  2067. %% <em>Tail</em>]</code>", the result represents "<code>[<em>E1</em> |
  2068. %% ... [<em>En</em> | <em>Tail1</em>] ... ]</code>", where
  2069. %% <code>Tail1</code> is the result of
  2070. %% <code>normalize_list(Tail)</code>. If <code>Node</code> represents
  2071. %% "<code>[<em>E1</em>, ..., <em>En</em>]</code>", the result simply
  2072. %% represents "<code>[<em>E1</em> | ... [<em>En</em> | []] ...
  2073. %% ]</code>". If <code>Node</code> does not represent a list skeleton,
  2074. %% <code>Node</code> itself is returned.
  2075. %%
  2076. %% @see list/2
  2077. %% @see compact_list/1
  2078. normalize_list(Node) ->
  2079. case type(Node) of
  2080. list ->
  2081. P = list_prefix(Node),
  2082. case list_suffix(Node) of
  2083. none ->
  2084. copy_attrs(Node, normalize_list_1(P, nil()));
  2085. Tail ->
  2086. Tail1 = normalize_list(Tail),
  2087. copy_attrs(Node, normalize_list_1(P, Tail1))
  2088. end;
  2089. _ ->
  2090. Node
  2091. end.
  2092. normalize_list_1(Es, Tail) ->
  2093. lists:foldr(fun (X, A) ->
  2094. list([X], A) % not `cons'!
  2095. end,
  2096. Tail, Es).
  2097. %% =====================================================================
  2098. %% @spec compact_list(Node::syntaxTree()) -> syntaxTree()
  2099. %%
  2100. %% @doc Yields the most compact form for an abstract list skeleton. The
  2101. %% result either represents "<code>[<em>E1</em>, ..., <em>En</em> |
  2102. %% <em>Tail</em>]</code>", where <code>Tail</code> is not a list
  2103. %% skeleton, or otherwise simply "<code>[<em>E1</em>, ...,
  2104. %% <em>En</em>]</code>". Annotations on subtrees of <code>Node</code>
  2105. %% that represent list skeletons may be lost, but comments will be
  2106. %% propagated to the result. Returns <code>Node</code> itself if
  2107. %% <code>Node</code> does not represent a list skeleton.
  2108. %%
  2109. %% @see list/2
  2110. %% @see normalize_list/1
  2111. compact_list(Node) ->
  2112. case type(Node) of
  2113. list ->
  2114. case list_suffix(Node) of
  2115. none ->
  2116. Node;
  2117. Tail ->
  2118. case type(Tail) of
  2119. list ->
  2120. Tail1 = compact_list(Tail),
  2121. Node1 = list(list_prefix(Node) ++
  2122. list_prefix(Tail1),
  2123. list_suffix(Tail1)),
  2124. join_comments(Tail1,
  2125. copy_attrs(Node,
  2126. Node1));
  2127. nil ->
  2128. Node1 = list(list_prefix(Node)),
  2129. join_comments(Tail,
  2130. copy_attrs(Node,
  2131. Node1));
  2132. _ ->
  2133. Node
  2134. end
  2135. end;
  2136. _ ->
  2137. Node
  2138. end.
  2139. %% =====================================================================
  2140. %% @spec binary(Fields::[syntaxTree()]) -> syntaxTree()
  2141. %%
  2142. %% @doc Creates an abstract binary-object template. If
  2143. %% <code>Fields</code> is <code>[F1, ..., Fn]</code>, the result
  2144. %% represents "<code>&lt;&lt;<em>F1</em>, ...,
  2145. %% <em>Fn</em>&gt;&gt;</code>".
  2146. %%
  2147. %% @see binary_fields/1
  2148. %% @see binary_field/2
  2149. %% type(Node) = binary
  2150. %% data(Node) = Fields
  2151. %%
  2152. %% Fields = [syntaxTree()]
  2153. %%
  2154. %% `erl_parse' representation:
  2155. %%
  2156. %% {bin, Pos, Fields}
  2157. %%
  2158. %% Fields = [Field]
  2159. %% Field = {bin_element, ...}
  2160. %%
  2161. %% See `binary_field' for documentation on `erl_parse' binary
  2162. %% fields (or "elements").
  2163. binary(List) ->
  2164. tree(binary, List).
  2165. revert_binary(Node) ->
  2166. Pos = get_pos(Node),
  2167. {bin, Pos, binary_fields(Node)}.
  2168. %% =====================================================================
  2169. %% @spec binary_fields(syntaxTree()) -> [syntaxTree()]
  2170. %%
  2171. %% @doc Returns the list of field subtrees of a <code>binary</code>
  2172. %% node.
  2173. %%
  2174. %% @see binary/1
  2175. %% @see binary_field/2
  2176. binary_fields(Node) ->
  2177. case unwrap(Node) of
  2178. {bin, _, List} ->
  2179. List;
  2180. Node1 ->
  2181. data(Node1)
  2182. end.
  2183. %% =====================================================================
  2184. %% @spec binary_field(Body) -> syntaxTree()
  2185. %% @equiv binary_field(Body, [])
  2186. binary_field(Body) ->
  2187. binary_field(Body, []).
  2188. %% =====================================================================
  2189. %% @spec binary_field(Body::syntaxTree(), Size,
  2190. %% Types::[syntaxTree()]) -> syntaxTree()
  2191. %% Size = none | syntaxTree()
  2192. %%
  2193. %% @doc Creates an abstract binary template field. (Utility function.)
  2194. %% If <code>Size</code> is <code>none</code>, this is equivalent to
  2195. %% "<code>binary_field(Body, Types)</code>", otherwise it is
  2196. %% equivalent to "<code>binary_field(size_qualifier(Body, Size),
  2197. %% Types)</code>".
  2198. %%
  2199. %% @see binary/1
  2200. %% @see binary_field/2
  2201. %% @see size_qualifier/2
  2202. binary_field(Body, none, Types) ->
  2203. binary_field(Body, Types);
  2204. binary_field(Body, Size, Types) ->
  2205. binary_field(size_qualifier(Body, Size), Types).
  2206. %% =====================================================================
  2207. %% @spec binary_field(Body::syntaxTree(), Types::[syntaxTree()]) ->
  2208. %% syntaxTree()
  2209. %%
  2210. %% @doc Creates an abstract binary template field. If
  2211. %% <code>Types</code> is the empty list, the result simply represents
  2212. %% "<code><em>Body</em></code>", otherwise, if <code>Types</code> is
  2213. %% <code>[T1, ..., Tn]</code>, the result represents
  2214. %% "<code><em>Body</em>/<em>T1</em>-...-<em>Tn</em></code>".
  2215. %%
  2216. %% @see binary/1
  2217. %% @see binary_field/1
  2218. %% @see binary_field/3
  2219. %% @see binary_field_body/1
  2220. %% @see binary_field_types/1
  2221. %% @see binary_field_size/1
  2222. -record(binary_field, {body, types}).
  2223. %% type(Node) = binary_field
  2224. %% data(Node) = #binary_field{body :: Body, types :: Types}
  2225. %%
  2226. %% Body = syntaxTree()
  2227. %% Types = [Type]
  2228. %%
  2229. %% `erl_parse' representation:
  2230. %%
  2231. %% {bin_element, Pos, Expr, Size, TypeList}
  2232. %%
  2233. %% Expr = erl_parse()
  2234. %% Size = default | erl_parse()
  2235. %% TypeList = default | [Type] \ []
  2236. %% Type = atom() | {atom(), integer()}
  2237. binary_field(Body, Types) ->
  2238. tree(binary_field, #binary_field{body = Body, types = Types}).
  2239. revert_binary_field(Node) ->
  2240. Pos = get_pos(Node),
  2241. Body = binary_field_body(Node),
  2242. {Expr, Size} = case type(Body) of
  2243. size_qualifier ->
  2244. %% Note that size qualifiers are not
  2245. %% revertible out of context.
  2246. {size_qualifier_body(Body),
  2247. size_qualifier_argument(Body)};
  2248. _ ->
  2249. {Body, default}
  2250. end,
  2251. Types = case binary_field_types(Node) of
  2252. [] ->
  2253. default;
  2254. Ts ->
  2255. fold_binary_field_types(Ts)
  2256. end,
  2257. {bin_element, Pos, Expr, Size, Types}.
  2258. %% =====================================================================
  2259. %% @spec binary_field_body(syntaxTree()) -> syntaxTree()
  2260. %%
  2261. %% @doc Returns the body subtree of a <code>binary_field</code>.
  2262. %%
  2263. %% @see binary_field/2
  2264. binary_field_body(Node) ->
  2265. case unwrap(Node) of
  2266. {bin_element, _, Body, Size, _} ->
  2267. if Size == default ->
  2268. Body;
  2269. true ->
  2270. size_qualifier(Body, Size)
  2271. end;
  2272. Node1 ->
  2273. (data(Node1))#binary_field.body
  2274. end.
  2275. %% =====================================================================
  2276. %% @spec binary_field_types(Node::syntaxTree()) -> [syntaxTree()]
  2277. %%
  2278. %% @doc Returns the list of type-specifier subtrees of a
  2279. %% <code>binary_field</code> node. If <code>Node</code> represents
  2280. %% "<code>.../<em>T1</em>, ..., <em>Tn</em></code>", the result is
  2281. %% <code>[T1, ..., Tn]</code>, otherwise the result is the empty list.
  2282. %%
  2283. %% @see binary_field/2
  2284. binary_field_types(Node) ->
  2285. case unwrap(Node) of
  2286. {bin_element, Pos, _, _, Types} ->
  2287. if Types == default ->
  2288. [];
  2289. true ->
  2290. unfold_binary_field_types(Types, Pos)
  2291. end;
  2292. Node1 ->
  2293. (data(Node1))#binary_field.types
  2294. end.
  2295. %% =====================================================================
  2296. %% @spec binary_field_size(Node::syntaxTree()) -> none | syntaxTree()
  2297. %%
  2298. %% @doc Returns the size specifier subtree of a
  2299. %% <code>binary_field</code> node, if any. (Utility function.) If
  2300. %% <code>Node</code> represents
  2301. %% "<code><em>Body</em>:<em>Size</em></code>" or
  2302. %% "<code><em>Body</em>:<em>Size</em>/<em>T1</em>, ...,
  2303. %% <em>Tn</em></code>", the result is <code>Size</code>, otherwise
  2304. %% <code>none</code> is returned.
  2305. %%
  2306. %% @see binary_field/2
  2307. %% @see binary_field/3
  2308. binary_field_size(Node) ->
  2309. case unwrap(Node) of
  2310. {bin_element, _, _, Size, _} ->
  2311. if Size == default ->
  2312. none;
  2313. true ->
  2314. Size
  2315. end;
  2316. Node1 ->
  2317. Body = (data(Node1))#binary_field.body,
  2318. case type(Body) of
  2319. size_qualifier ->
  2320. size_qualifier_argument(Body);
  2321. _ ->
  2322. none
  2323. end
  2324. end.
  2325. %% =====================================================================
  2326. %% @spec size_qualifier(Body::syntaxTree(), Size::syntaxTree()) ->
  2327. %% syntaxTree()
  2328. %%
  2329. %% @doc Creates an abstract size qualifier. The result represents
  2330. %% "<code><em>Body</em>:<em>Size</em></code>".
  2331. %%
  2332. %% @see size_qualifier_body/1
  2333. %% @see size_qualifier_argument/1
  2334. -record(size_qualifier, {body, size}).
  2335. %% type(Node) = size_qualifier
  2336. %% data(Node) = #size_qualifier{body :: Body, size :: Size}
  2337. %%
  2338. %% Body = Size = syntaxTree()
  2339. size_qualifier(Body, Size) ->
  2340. tree(size_qualifier,
  2341. #size_qualifier{body = Body, size = Size}).
  2342. %% =====================================================================
  2343. %% @spec size_qualifier_body(syntaxTree()) -> syntaxTree()
  2344. %%
  2345. %% @doc Returns the body subtree of a <code>size_qualifier</code>
  2346. %% node.
  2347. %%
  2348. %% @see size_qualifier/2
  2349. size_qualifier_body(Node) ->
  2350. (data(Node))#size_qualifier.body.
  2351. %% =====================================================================
  2352. %% @spec size_qualifier_argument(syntaxTree()) -> syntaxTree()
  2353. %%
  2354. %% @doc Returns the argument subtree (the size) of a
  2355. %% <code>size_qualifier</code> node.
  2356. %%
  2357. %% @see size_qualifier/2
  2358. size_qualifier_argument(Node) ->
  2359. (data(Node))#size_qualifier.size.
  2360. %% =====================================================================
  2361. %% @spec error_marker(Error::term()) -> syntaxTree()
  2362. %%
  2363. %% @doc Creates an abstract error marker. The result represents an
  2364. %% occurrence of an error in the source code, with an associated Erlang
  2365. %% I/O ErrorInfo structure given by <code>Error</code> (see module
  2366. %% <code>io</code> for details). Error markers are regarded as source
  2367. %% code forms, but have no defined lexical form.
  2368. %%
  2369. %% <p>Note: this is supported only for backwards compatibility with
  2370. %% existing parsers and tools.</p>
  2371. %%
  2372. %% @see error_marker_info/1
  2373. %% @see warning_marker/1
  2374. %% @see eof_marker/0
  2375. %% @see is_form/1
  2376. %% @see io
  2377. %% type(Node) = error_marker
  2378. %% data(Node) = term()
  2379. %%
  2380. %% `erl_parse' representation:
  2381. %%
  2382. %% {error, Error}
  2383. %%
  2384. %% Error = term()
  2385. %%
  2386. %% Note that there is no position information for the node
  2387. %% itself: `get_pos' and `set_pos' handle this as a special case.
  2388. error_marker(Error) ->
  2389. tree(error_marker, Error).
  2390. revert_error_marker(Node) ->
  2391. %% Note that the position information of the node itself is not
  2392. %% preserved.
  2393. {error, error_marker_info(Node)}.
  2394. %% =====================================================================
  2395. %% @spec error_marker_info(syntaxTree()) -> term()
  2396. %%
  2397. %% @doc Returns the ErrorInfo structure of an <code>error_marker</code>
  2398. %% node.
  2399. %%
  2400. %% @see error_marker/1
  2401. error_marker_info(Node) ->
  2402. case unwrap(Node) of
  2403. {error, Error} ->
  2404. Error;
  2405. T ->
  2406. data(T)
  2407. end.
  2408. %% =====================================================================
  2409. %% @spec warning_marker(Error::term()) -> syntaxTree()
  2410. %%
  2411. %% @doc Creates an abstract warning marker. The result represents an
  2412. %% occurrence of a possible problem in the source code, with an
  2413. %% associated Erlang I/O ErrorInfo structure given by <code>Error</code>
  2414. %% (see module <code>io</code> for details). Warning markers are
  2415. %% regarded as source code forms, but have no defined lexical form.
  2416. %%
  2417. %% <p>Note: this is supported only for backwards compatibility with
  2418. %% existing parsers and tools.</p>
  2419. %%
  2420. %% @see warning_marker_info/1
  2421. %% @see error_marker/1
  2422. %% @see eof_marker/0
  2423. %% @see is_form/1
  2424. %% @see io
  2425. %% type(Node) = warning_marker
  2426. %% data(Node) = term()
  2427. %%
  2428. %% `erl_parse' representation:
  2429. %%
  2430. %% {warning, Error}
  2431. %%
  2432. %% Error = term()
  2433. %%
  2434. %% Note that there is no position information for the node
  2435. %% itself: `get_pos' and `set_pos' handle this as a special case.
  2436. warning_marker(Warning) ->
  2437. tree(warning_marker, Warning).
  2438. revert_warning_marker(Node) ->
  2439. %% Note that the position information of the node itself is not
  2440. %% preserved.
  2441. {warning, warning_marker_info(Node)}.
  2442. %% =====================================================================
  2443. %% @spec warning_marker_info(syntaxTree()) -> term()
  2444. %%
  2445. %% @doc Returns the ErrorInfo structure of a <code>warning_marker</code>
  2446. %% node.
  2447. %%
  2448. %% @see warning_marker/1
  2449. warning_marker_info(Node) ->
  2450. case unwrap(Node) of
  2451. {warning, Error} ->
  2452. Error;
  2453. T ->
  2454. data(T)
  2455. end.
  2456. %% =====================================================================
  2457. %% @spec eof_marker() -> syntaxTree()
  2458. %%
  2459. %% @doc Creates an abstract end-of-file marker. This represents the
  2460. %% end of input when reading a sequence of source code forms. An
  2461. %% end-of-file marker is itself regarded as a source code form
  2462. %% (namely, the last in any sequence in which it occurs). It has no
  2463. %% defined lexical form.
  2464. %%
  2465. %% <p>Note: this is retained only for backwards compatibility with
  2466. %% existing parsers and tools.</p>
  2467. %%
  2468. %% @see error_marker/1
  2469. %% @see warning_marker/1
  2470. %% @see is_form/1
  2471. %% type(Node) = eof_marker
  2472. %% data(Node) = term()
  2473. %%
  2474. %% `erl_parse' representation:
  2475. %%
  2476. %% {eof, Pos}
  2477. eof_marker() ->
  2478. tree(eof_marker).
  2479. revert_eof_marker(Node) ->
  2480. Pos = get_pos(Node),
  2481. {eof, Pos}.
  2482. %% =====================================================================
  2483. %% @spec attribute(Name) -> syntaxTree()
  2484. %% @equiv attribute(Name, none)
  2485. attribute(Name) ->
  2486. attribute(Name, none).
  2487. %% =====================================================================
  2488. %% @spec attribute(Name::syntaxTree(), Arguments) -> syntaxTree()
  2489. %% Arguments = none | [syntaxTree()]
  2490. %%
  2491. %% @doc Creates an abstract program attribute. If
  2492. %% <code>Arguments</code> is <code>[A1, ..., An]</code>, the result
  2493. %% represents "<code>-<em>Name</em>(<em>A1</em>, ...,
  2494. %% <em>An</em>).</code>". Otherwise, if <code>Arguments</code> is
  2495. %% <code>none</code>, the result represents
  2496. %% "<code>-<em>Name</em>.</code>". The latter form makes it possible
  2497. %% to represent preprocessor directives such as
  2498. %% "<code>-endif.</code>". Attributes are source code forms.
  2499. %%
  2500. %% <p>Note: The preprocessor macro definition directive
  2501. %% "<code>-define(<em>Name</em>, <em>Body</em>).</code>" has relatively
  2502. %% few requirements on the syntactical form of <code>Body</code> (viewed
  2503. %% as a sequence of tokens). The <code>text</code> node type can be used
  2504. %% for a <code>Body</code> that is not a normal Erlang construct.</p>
  2505. %%
  2506. %% @see attribute/1
  2507. %% @see attribute_name/1
  2508. %% @see attribute_arguments/1
  2509. %% @see text/1
  2510. %% @see is_form/1
  2511. -record(attribute, {name, args}).
  2512. %% type(Node) = attribute
  2513. %% data(Node) = #attribute{name :: Name, args :: Arguments}
  2514. %%
  2515. %% Name = syntaxTree()
  2516. %% Arguments = none | [syntaxTree()]
  2517. %%
  2518. %% `erl_parse' representation:
  2519. %%
  2520. %% {attribute, Pos, module, {Name,Vars}}
  2521. %% {attribute, Pos, module, Name}
  2522. %%
  2523. %% Name = atom() | [atom()]
  2524. %% Vars = [atom()]
  2525. %%
  2526. %% Representing `-module(M).', or `-module(M, Vs).', where M is
  2527. %% `A1.A2.....An' if Name is `[A1, A2, ..., An]', and Vs is `[V1,
  2528. %% ..., Vm]' if Vars is `[V1, ..., Vm]'.
  2529. %%
  2530. %% {attribute, Pos, export, Exports}
  2531. %%
  2532. %% Exports = [{atom(), integer()}]
  2533. %%
  2534. %% Representing `-export([A1/N1, ..., Ak/Nk]).', if `Exports' is
  2535. %% `[{A1, N1}, ..., {Ak, Nk}]'.
  2536. %%
  2537. %% {attribute, Pos, import, Imports}
  2538. %%
  2539. %% Imports = {atom(), Pairs} | [atom()]
  2540. %% Pairs = [{atom(), integer()]
  2541. %%
  2542. %% Representing `-import(Module, [A1/N1, ..., Ak/Nk]).', if
  2543. %% `Imports' is `{Module, [{A1, N1}, ..., {Ak, Nk}]}', or
  2544. %% `-import(A1.....An).', if `Imports' is `[A1, ..., An]'.
  2545. %%
  2546. %% {attribute, Pos, file, Position}
  2547. %%
  2548. %% Position = {filename(), integer()}
  2549. %%
  2550. %% Representing `-file(Name, Line).', if `Position' is `{Name,
  2551. %% Line}'.
  2552. %%
  2553. %% {attribute, Pos, record, Info}
  2554. %%
  2555. %% Info = {Name, [Entries]}
  2556. %% Name = atom()
  2557. %% Entries = {record_field, Pos, atom()}
  2558. %% | {record_field, Pos, atom(), erl_parse()}
  2559. %%
  2560. %% Representing `-record(Name, {<F1>, ..., <Fn>}).', if `Info' is
  2561. %% `{Name, [D1, ..., D1]}', where each `Fi' is either `Ai = <Ei>',
  2562. %% if the corresponding `Di' is `{record_field, Pos, Ai, Ei}', or
  2563. %% otherwise simply `Ai', if `Di' is `{record_field, Pos, Ai}'.
  2564. %%
  2565. %% {attribute, L, Name, Term}
  2566. %%
  2567. %% Name = atom() \ StandardName
  2568. %% StandardName = module | export | import | file | record
  2569. %% Term = term()
  2570. %%
  2571. %% Representing `-Name(Term).'.
  2572. attribute(Name, Args) ->
  2573. tree(attribute, #attribute{name = Name, args = Args}).
  2574. revert_attribute(Node) ->
  2575. Name = attribute_name(Node),
  2576. Args = attribute_arguments(Node),
  2577. Pos = get_pos(Node),
  2578. case type(Name) of
  2579. atom ->
  2580. revert_attribute_1(atom_value(Name), Args, Pos, Node);
  2581. _ ->
  2582. Node
  2583. end.
  2584. %% All the checking makes this part a bit messy:
  2585. revert_attribute_1(module, [M], Pos, Node) ->
  2586. case revert_module_name(M) of
  2587. {ok, A} ->
  2588. {attribute, Pos, module, A};
  2589. error -> Node
  2590. end;
  2591. revert_attribute_1(module, [M, List], Pos, Node) ->
  2592. Vs = case is_list_skeleton(List) of
  2593. true ->
  2594. case is_proper_list(List) of
  2595. true ->
  2596. fold_variable_names(list_elements(List));
  2597. false ->
  2598. Node
  2599. end;
  2600. false ->
  2601. Node
  2602. end,
  2603. case revert_module_name(M) of
  2604. {ok, A} ->
  2605. {attribute, Pos, module, {A, Vs}};
  2606. error -> Node
  2607. end;
  2608. revert_attribute_1(export, [List], Pos, Node) ->
  2609. case is_list_skeleton(List) of
  2610. true ->
  2611. case is_proper_list(List) of
  2612. true ->
  2613. Fs = fold_function_names(list_elements(List)),
  2614. {attribute, Pos, export, Fs};
  2615. false ->
  2616. Node
  2617. end;
  2618. false ->
  2619. Node
  2620. end;
  2621. revert_attribute_1(import, [M], Pos, Node) ->
  2622. case revert_module_name(M) of
  2623. {ok, A} -> {attribute, Pos, import, A};
  2624. error -> Node
  2625. end;
  2626. revert_attribute_1(import, [A, List], Pos, Node) ->
  2627. case type(A) of
  2628. atom ->
  2629. case is_list_skeleton(List) of
  2630. true ->
  2631. case is_proper_list(List) of
  2632. true ->
  2633. Fs = fold_function_names(
  2634. list_elements(List)),
  2635. {attribute, Pos, import,
  2636. {concrete(A), Fs}};
  2637. false ->
  2638. Node
  2639. end;
  2640. false ->
  2641. Node
  2642. end;
  2643. _ ->
  2644. Node
  2645. end;
  2646. revert_attribute_1(file, [A, Line], Pos, Node) ->
  2647. case type(A) of
  2648. string ->
  2649. case type(Line) of
  2650. integer ->
  2651. {attribute, Pos, file,
  2652. {concrete(A), concrete(Line)}};
  2653. _ ->
  2654. Node
  2655. end;
  2656. _ ->
  2657. Node
  2658. end;
  2659. revert_attribute_1(record, [A, Tuple], Pos, Node) ->
  2660. case type(A) of
  2661. atom ->
  2662. case type(Tuple) of
  2663. tuple ->
  2664. Fs = fold_record_fields(
  2665. tuple_elements(Tuple)),
  2666. {attribute, Pos, record, {concrete(A), Fs}};
  2667. _ ->
  2668. Node
  2669. end;
  2670. _ ->
  2671. Node
  2672. end;
  2673. revert_attribute_1(N, [T], Pos, _) ->
  2674. {attribute, Pos, N, concrete(T)};
  2675. revert_attribute_1(_, _, _, Node) ->
  2676. Node.
  2677. revert_module_name(A) ->
  2678. case type(A) of
  2679. atom ->
  2680. {ok, concrete(A)};
  2681. qualified_name ->
  2682. Ss = qualified_name_segments(A),
  2683. {ok, [concrete(S) || S <- Ss]};
  2684. _ ->
  2685. error
  2686. end.
  2687. %% =====================================================================
  2688. %% @spec attribute_name(syntaxTree()) -> syntaxTree()
  2689. %%
  2690. %% @doc Returns the name subtree of an <code>attribute</code> node.
  2691. %%
  2692. %% @see attribute/1
  2693. attribute_name(Node) ->
  2694. case unwrap(Node) of
  2695. {attribute, Pos, Name, _} ->
  2696. set_pos(atom(Name), Pos);
  2697. Node1 ->
  2698. (data(Node1))#attribute.name
  2699. end.
  2700. %% =====================================================================
  2701. %% @spec attribute_arguments(Node::syntaxTree()) ->
  2702. %% none | [syntaxTree()]
  2703. %%
  2704. %% @doc Returns the list of argument subtrees of an
  2705. %% <code>attribute</code> node, if any. If <code>Node</code>
  2706. %% represents "<code>-<em>Name</em>.</code>", the result is
  2707. %% <code>none</code>. Otherwise, if <code>Node</code> represents
  2708. %% "<code>-<em>Name</em>(<em>E1</em>, ..., <em>En</em>).</code>",
  2709. %% <code>[E1, ..., E1]</code> is returned.
  2710. %%
  2711. %% @see attribute/1
  2712. attribute_arguments(Node) ->
  2713. case unwrap(Node) of
  2714. {attribute, Pos, Name, Data} ->
  2715. case Name of
  2716. module ->
  2717. {M1, Vs} =
  2718. case Data of
  2719. {M0, Vs0} ->
  2720. {M0, unfold_variable_names(Vs0, Pos)};
  2721. M0 ->
  2722. {M0, none}
  2723. end,
  2724. M2 = if list(M1) ->
  2725. qualified_name([atom(A) || A <- M1]);
  2726. true ->
  2727. atom(M1)
  2728. end,
  2729. M = set_pos(M2, Pos),
  2730. if Vs == none -> [M];
  2731. true -> [M, set_pos(list(Vs), Pos)]
  2732. end;
  2733. export ->
  2734. [set_pos(
  2735. list(unfold_function_names(Data, Pos)),
  2736. Pos)];
  2737. import ->
  2738. case Data of
  2739. {Module, Imports} ->
  2740. [if list(Module) ->
  2741. qualified_name([atom(A)
  2742. || A <- Module]);
  2743. true ->
  2744. set_pos(atom(Module), Pos)
  2745. end,
  2746. set_pos(
  2747. list(unfold_function_names(Imports, Pos)),
  2748. Pos)];
  2749. _ ->
  2750. [qualified_name([atom(A) || A <- Data])]
  2751. end;
  2752. file ->
  2753. {File, Line} = Data,
  2754. [set_pos(string(File), Pos),
  2755. set_pos(integer(Line), Pos)];
  2756. record ->
  2757. %% Note that we create a tuple as container
  2758. %% for the second argument!
  2759. {Type, Entries} = Data,
  2760. [set_pos(atom(Type), Pos),
  2761. set_pos(tuple(unfold_record_fields(Entries)),
  2762. Pos)];
  2763. _ ->
  2764. %% Standard single-term generic attribute.
  2765. [set_pos(abstract(Data), Pos)]
  2766. end;
  2767. Node1 ->
  2768. (data(Node1))#attribute.args
  2769. end.
  2770. %% =====================================================================
  2771. %% @spec arity_qualifier(Body::syntaxTree(), Arity::syntaxTree()) ->
  2772. %% syntaxTree()
  2773. %%
  2774. %% @doc Creates an abstract arity qualifier. The result represents
  2775. %% "<code><em>Body</em>/<em>Arity</em></code>".
  2776. %%
  2777. %% @see arity_qualifier_body/1
  2778. %% @see arity_qualifier_argument/1
  2779. -record(arity_qualifier, {body, arity}).
  2780. %% type(Node) = arity_qualifier
  2781. %% data(Node) = #arity_qualifier{body :: Body, arity :: Arity}
  2782. %%
  2783. %% Body = Arity = syntaxTree()
  2784. arity_qualifier(Body, Arity) ->
  2785. tree(arity_qualifier,
  2786. #arity_qualifier{body = Body, arity = Arity}).
  2787. %% =====================================================================
  2788. %% @spec arity_qualifier_body(syntaxTree()) -> syntaxTree()
  2789. %%
  2790. %% @doc Returns the body subtree of an <code>arity_qualifier</code>
  2791. %% node.
  2792. %%
  2793. %% @see arity_qualifier/1
  2794. arity_qualifier_body(Node) ->
  2795. (data(Node))#arity_qualifier.body.
  2796. %% =====================================================================
  2797. %% @spec arity_qualifier_argument(syntaxTree()) -> syntaxTree()
  2798. %%
  2799. %% @doc Returns the argument (the arity) subtree of an
  2800. %% <code>arity_qualifier</code> node.
  2801. %%
  2802. %% @see arity_qualifier/1
  2803. arity_qualifier_argument(Node) ->
  2804. (data(Node))#arity_qualifier.arity.
  2805. %% =====================================================================
  2806. %% @spec module_qualifier(Module::syntaxTree(), Body::syntaxTree()) ->
  2807. %% syntaxTree()
  2808. %%
  2809. %% @doc Creates an abstract module qualifier. The result represents
  2810. %% "<code><em>Module</em>:<em>Body</em></code>".
  2811. %%
  2812. %% @see module_qualifier_argument/1
  2813. %% @see module_qualifier_body/1
  2814. -record(module_qualifier, {module, body}).
  2815. %% type(Node) = module_qualifier
  2816. %% data(Node) = #module_qualifier{module :: Module, body :: Body}
  2817. %%
  2818. %% Module = Body = syntaxTree()
  2819. %%
  2820. %% `erl_parse' representation:
  2821. %%
  2822. %% {remote, Pos, Module, Arg}
  2823. %%
  2824. %% Module = Arg = erl_parse()
  2825. module_qualifier(Module, Body) ->
  2826. tree(module_qualifier,
  2827. #module_qualifier{module = Module, body = Body}).
  2828. revert_module_qualifier(Node) ->
  2829. Pos = get_pos(Node),
  2830. Module = module_qualifier_argument(Node),
  2831. Body = module_qualifier_body(Node),
  2832. {remote, Pos, Module, Body}.
  2833. %% =====================================================================
  2834. %% @spec module_qualifier_argument(syntaxTree()) -> syntaxTree()
  2835. %%
  2836. %% @doc Returns the argument (the module) subtree of a
  2837. %% <code>module_qualifier</code> node.
  2838. %%
  2839. %% @see module_qualifier/2
  2840. module_qualifier_argument(Node) ->
  2841. case unwrap(Node) of
  2842. {remote, _, Module, _} ->
  2843. Module;
  2844. Node1 ->
  2845. (data(Node1))#module_qualifier.module
  2846. end.
  2847. %% =====================================================================
  2848. %% @spec module_qualifier_body(syntaxTree()) -> syntaxTree()
  2849. %%
  2850. %% @doc Returns the body subtree of a <code>module_qualifier</code>
  2851. %% node.
  2852. %%
  2853. %% @see module_qualifier/2
  2854. module_qualifier_body(Node) ->
  2855. case unwrap(Node) of
  2856. {remote, _, _, Body} ->
  2857. Body;
  2858. Node1 ->
  2859. (data(Node1))#module_qualifier.body
  2860. end.
  2861. %% =====================================================================
  2862. %% @spec qualified_name(Segments::[syntaxTree()]) -> syntaxTree()
  2863. %%
  2864. %% @doc Creates an abstract qualified name. The result represents
  2865. %% "<code><em>S1</em>.<em>S2</em>. ... .<em>Sn</em></code>", if
  2866. %% <code>Segments</code> is <code>[S1, S2, ..., Sn]</code>.
  2867. %%
  2868. %% @see qualified_name_segments/1
  2869. %% type(Node) = qualified_name
  2870. %% data(Node) = [syntaxTree()]
  2871. %%
  2872. %% `erl_parse' representation:
  2873. %%
  2874. %% {record_field, Pos, Node, Node}
  2875. %%
  2876. %% Node = {atom, Pos, Value} | {record_field, Pos, Node, Node}
  2877. %%
  2878. %% Note that if not all leaf subnodes are (abstract) atoms, then Node
  2879. %% represents a Mnemosyne query record field access ('record_access');
  2880. %% see type/1 for details.
  2881. qualified_name(Segments) ->
  2882. tree(qualified_name, Segments).
  2883. revert_qualified_name(Node) ->
  2884. Pos = get_pos(Node),
  2885. fold_qualified_name(qualified_name_segments(Node), Pos).
  2886. %% =====================================================================
  2887. %% @spec qualified_name_segments(syntaxTree()) -> [syntaxTree()]
  2888. %%
  2889. %% @doc Returns the list of name segments of a
  2890. %% <code>qualified_name</code> node.
  2891. %%
  2892. %% @see qualified_name/1
  2893. qualified_name_segments(Node) ->
  2894. case unwrap(Node) of
  2895. {record_field, _, _, _} = Node1 ->
  2896. unfold_qualified_name(Node1);
  2897. Node1 ->
  2898. data(Node1)
  2899. end.
  2900. %% =====================================================================
  2901. %% @spec function(Name::syntaxTree(), Clauses::[syntaxTree()]) ->
  2902. %% syntaxTree()
  2903. %%
  2904. %% @doc Creates an abstract function definition. If <code>Clauses</code>
  2905. %% is <code>[C1, ..., Cn]</code>, the result represents
  2906. %% "<code><em>Name</em> <em>C1</em>; ...; <em>Name</em>
  2907. %% <em>Cn</em>.</code>". More exactly, if each <code>Ci</code>
  2908. %% represents "<code>(<em>Pi1</em>, ..., <em>Pim</em>) <em>Gi</em> ->
  2909. %% <em>Bi</em></code>", then the result represents
  2910. %% "<code><em>Name</em>(<em>P11</em>, ..., <em>P1m</em>) <em>G1</em> ->
  2911. %% <em>B1</em>; ...; <em>Name</em>(<em>Pn1</em>, ..., <em>Pnm</em>)
  2912. %% <em>Gn</em> -> <em>Bn</em>.</code>". Function definitions are source
  2913. %% code forms.
  2914. %%
  2915. %% @see function_name/1
  2916. %% @see function_clauses/1
  2917. %% @see function_arity/1
  2918. %% @see is_form/1
  2919. %% @see rule/2
  2920. -record(function, {name, clauses}).
  2921. %% type(Node) = function
  2922. %% data(Node) = #function{name :: Name, clauses :: Clauses}
  2923. %%
  2924. %% Name = syntaxTree()
  2925. %% Clauses = [syntaxTree()]
  2926. %%
  2927. %% (There's no real point in precomputing and storing the arity,
  2928. %% and passing it as a constructor argument makes it possible to
  2929. %% end up with an inconsistent value. Besides, some people might
  2930. %% want to check all clauses, and not just the first, so the
  2931. %% computation is not obvious.)
  2932. %%
  2933. %% `erl_parse' representation:
  2934. %%
  2935. %% {function, Pos, Name, Arity, Clauses}
  2936. %%
  2937. %% Name = atom()
  2938. %% Arity = integer()
  2939. %% Clauses = [Clause] \ []
  2940. %% Clause = {clause, ...}
  2941. %%
  2942. %% where the number of patterns in each clause should be equal to
  2943. %% the integer `Arity'; see `clause' for documentation on
  2944. %% `erl_parse' clauses.
  2945. function(Name, Clauses) ->
  2946. tree(function, #function{name = Name, clauses = Clauses}).
  2947. revert_function(Node) ->
  2948. Name = function_name(Node),
  2949. Clauses = [revert_clause(C) || C <- function_clauses(Node)],
  2950. Pos = get_pos(Node),
  2951. case type(Name) of
  2952. atom ->
  2953. A = function_arity(Node),
  2954. {function, Pos, concrete(Name), A, Clauses};
  2955. _ ->
  2956. Node
  2957. end.
  2958. %% =====================================================================
  2959. %% function_name(Node) -> Name
  2960. %%
  2961. %% Node = Name = syntaxTree()
  2962. %% type(Node) = function
  2963. %%
  2964. %% @doc Returns the name subtree of a <code>function</code> node.
  2965. %%
  2966. %% @see function/2
  2967. function_name(Node) ->
  2968. case unwrap(Node) of
  2969. {function, Pos, Name, _, _} ->
  2970. set_pos(atom(Name), Pos);
  2971. Node1 ->
  2972. (data(Node1))#function.name
  2973. end.
  2974. %% =====================================================================
  2975. %% function_clauses(Node) -> Clauses
  2976. %%
  2977. %% Node = syntaxTree()
  2978. %% Clauses = [syntaxTree()]
  2979. %% type(Node) = function
  2980. %%
  2981. %% @doc Returns the list of clause subtrees of a <code>function</code>
  2982. %% node.
  2983. %%
  2984. %% @see function/2
  2985. function_clauses(Node) ->
  2986. case unwrap(Node) of
  2987. {function, _, _, _, Clauses} ->
  2988. Clauses;
  2989. Node1 ->
  2990. (data(Node1))#function.clauses
  2991. end.
  2992. %% =====================================================================
  2993. %% @spec function_arity(Node::syntaxTree()) -> integer()
  2994. %%
  2995. %% @doc Returns the arity of a <code>function</code> node. The result
  2996. %% is the number of parameter patterns in the first clause of the
  2997. %% function; subsequent clauses are ignored.
  2998. %%
  2999. %% <p>An exception is thrown if <code>function_clauses(Node)</code>
  3000. %% returns an empty list, or if the first element of that list is not
  3001. %% a syntax tree <code>C</code> of type <code>clause</code> such that
  3002. %% <code>clause_patterns(C)</code> is a nonempty list.</p>
  3003. %%
  3004. %% @see function/2
  3005. %% @see function_clauses/1
  3006. %% @see clause/3
  3007. %% @see clause_patterns/1
  3008. function_arity(Node) ->
  3009. %% Note that this never accesses the arity field of `erl_parse'
  3010. %% function nodes.
  3011. length(clause_patterns(hd(function_clauses(Node)))).
  3012. %% =====================================================================
  3013. %% @spec clause(Guard, Body) -> syntaxTree()
  3014. %% @equiv clause([], Guard, Body)
  3015. clause(Guard, Body) ->
  3016. clause([], Guard, Body).
  3017. %% =====================================================================
  3018. %% @spec clause(Patterns::[syntaxTree()], Guard,
  3019. %% Body::[syntaxTree()]) -> syntaxTree()
  3020. %% Guard = none | syntaxTree()
  3021. %% | [syntaxTree()] | [[syntaxTree()]]
  3022. %%
  3023. %% @doc Creates an abstract clause. If <code>Patterns</code> is
  3024. %% <code>[P1, ..., Pn]</code> and <code>Body</code> is <code>[B1, ...,
  3025. %% Bm]</code>, then if <code>Guard</code> is <code>none</code>, the
  3026. %% result represents "<code>(<em>P1</em>, ..., <em>Pn</em>) ->
  3027. %% <em>B1</em>, ..., <em>Bm</em></code>", otherwise, unless
  3028. %% <code>Guard</code> is a list, the result represents
  3029. %% "<code>(<em>P1</em>, ..., <em>Pn</em>) when <em>Guard</em> ->
  3030. %% <em>B1</em>, ..., <em>Bm</em></code>".
  3031. %%
  3032. %% <p>For simplicity, the <code>Guard</code> argument may also be any
  3033. %% of the following:
  3034. %% <ul>
  3035. %% <li>An empty list <code>[]</code>. This is equivalent to passing
  3036. %% <code>none</code>.</li>
  3037. %% <li>A nonempty list <code>[E1, ..., Ej]</code> of syntax trees.
  3038. %% This is equivalent to passing <code>conjunction([E1, ...,
  3039. %% Ej])</code>.</li>
  3040. %% <li>A nonempty list of lists of syntax trees <code>[[E1_1, ...,
  3041. %% E1_k1], ..., [Ej_1, ..., Ej_kj]]</code>, which is equivalent
  3042. %% to passing <code>disjunction([conjunction([E1_1, ...,
  3043. %% E1_k1]), ..., conjunction([Ej_1, ..., Ej_kj])])</code>.</li>
  3044. %% </ul>
  3045. %% </p>
  3046. %%
  3047. %% @see clause/2
  3048. %% @see clause_patterns/1
  3049. %% @see clause_guard/1
  3050. %% @see clause_body/1
  3051. -record(clause, {patterns, guard, body}).
  3052. %% type(Node) = clause
  3053. %% data(Node) = #clause{patterns :: Patterns, guard :: Guard,
  3054. %% body :: Body}
  3055. %%
  3056. %% Patterns = [syntaxTree()]
  3057. %% Guard = syntaxTree() | none
  3058. %% Body = [syntaxTree()]
  3059. %%
  3060. %% `erl_parse' representation:
  3061. %%
  3062. %% {clause, Pos, Patterns, Guard, Body}
  3063. %%
  3064. %% Patterns = [erl_parse()]
  3065. %% Guard = [[erl_parse()]] | [erl_parse()]
  3066. %% Body = [erl_parse()] \ []
  3067. %%
  3068. %% Taken out of context, if `Patterns' is `[P1, ..., Pn]' and
  3069. %% `Body' is `[B1, ..., Bm]', this represents `(<P1>, ..., <Pn>) ->
  3070. %% <B1>, ..., <Bm>' if `Guard' is `[]', or otherwise `(<P1>, ...,
  3071. %% <Pn>) when <G> -> <Body>', where `G' is `<E1_1>, ..., <E1_k1>;
  3072. %% ...; <Ej_1>, ..., <Ej_kj>', if `Guard' is a list of lists
  3073. %% `[[E1_1, ..., E1_k1], ..., [Ej_1, ..., Ej_kj]]'. In older
  3074. %% versions, `Guard' was simply a list `[E1, ..., En]' of parse
  3075. %% trees, which is equivalent to the new form `[[E1, ..., En]]'.
  3076. clause(Patterns, Guard, Body) ->
  3077. Guard1 = case Guard of
  3078. [] ->
  3079. none;
  3080. [X | _] when list(X) ->
  3081. disjunction(conjunction_list(Guard));
  3082. [_ | _] ->
  3083. %% Handle older forms also.
  3084. conjunction(Guard);
  3085. _ ->
  3086. %% This should be `none' or a syntax tree.
  3087. Guard
  3088. end,
  3089. tree(clause, #clause{patterns = Patterns, guard = Guard1,
  3090. body = Body}).
  3091. conjunction_list([L | Ls]) ->
  3092. [conjunction(L) | conjunction_list(Ls)];
  3093. conjunction_list([]) ->
  3094. [].
  3095. revert_clause(Node) ->
  3096. Pos = get_pos(Node),
  3097. Guard = case clause_guard(Node) of
  3098. none ->
  3099. [];
  3100. E ->
  3101. case type(E) of
  3102. disjunction ->
  3103. revert_clause_disjunction(E);
  3104. conjunction ->
  3105. %% Only the top level expression is
  3106. %% unfolded here; no recursion.
  3107. [conjunction_body(E)];
  3108. _ ->
  3109. [[E]] % a single expression
  3110. end
  3111. end,
  3112. {clause, Pos, clause_patterns(Node), Guard,
  3113. clause_body(Node)}.
  3114. revert_clause_disjunction(D) ->
  3115. %% We handle conjunctions within a disjunction, but only at
  3116. %% the top level; no recursion.
  3117. [case type(E) of
  3118. conjunction ->
  3119. conjunction_body(E);
  3120. _ ->
  3121. [E]
  3122. end
  3123. || E <- disjunction_body(D)].
  3124. revert_try_clause(Node) ->
  3125. fold_try_clause(revert_clause(Node)).
  3126. fold_try_clause({clause, Pos, [P], Guard, Body}) ->
  3127. P1 = case type(P) of
  3128. class_qualifier ->
  3129. {tuple, Pos, [class_qualifier_argument(P),
  3130. class_qualifier_body(P),
  3131. {var, Pos, '_'}]};
  3132. _ ->
  3133. {tuple, Pos, [{atom, Pos, throw}, P, {var, Pos, '_'}]}
  3134. end,
  3135. {clause, Pos, [P1], Guard, Body}.
  3136. unfold_try_clauses(Cs) ->
  3137. [unfold_try_clause(C) || C <- Cs].
  3138. unfold_try_clause({clause, Pos, [{tuple, _, [{atom,_,throw}, V, _]}],
  3139. Guard, Body}) ->
  3140. {clause, Pos, [V], Guard, Body};
  3141. unfold_try_clause({clause, Pos, [{tuple, _, [C, V, _]}],
  3142. Guard, Body}) ->
  3143. {clause, Pos, [class_qualifier(C, V)], Guard, Body}.
  3144. %% =====================================================================
  3145. %% @spec clause_patterns(syntaxTree()) -> [syntaxTree()]
  3146. %%
  3147. %% @doc Returns the list of pattern subtrees of a <code>clause</code>
  3148. %% node.
  3149. %%
  3150. %% @see clause/3
  3151. clause_patterns(Node) ->
  3152. case unwrap(Node) of
  3153. {clause, _, Patterns, _, _} ->
  3154. Patterns;
  3155. Node1 ->
  3156. (data(Node1))#clause.patterns
  3157. end.
  3158. %% =====================================================================
  3159. %% @spec clause_guard(Node::syntaxTree()) -> none | syntaxTree()
  3160. %%
  3161. %% @doc Returns the guard subtree of a <code>clause</code> node, if
  3162. %% any. If <code>Node</code> represents "<code>(<em>P1</em>, ...,
  3163. %% <em>Pn</em>) when <em>Guard</em> -> <em>B1</em>, ...,
  3164. %% <em>Bm</em></code>", <code>Guard</code> is returned. Otherwise, the
  3165. %% result is <code>none</code>.
  3166. %%
  3167. %% @see clause/3
  3168. clause_guard(Node) ->
  3169. case unwrap(Node) of
  3170. {clause, _, _, Guard, _} ->
  3171. case Guard of
  3172. [] -> none;
  3173. [L | _] when list(L) ->
  3174. disjunction(conjunction_list(Guard));
  3175. [_ | _] ->
  3176. conjunction(Guard)
  3177. end;
  3178. Node1 ->
  3179. (data(Node1))#clause.guard
  3180. end.
  3181. %% =====================================================================
  3182. %% @spec clause_body(syntaxTree()) -> [syntaxTree()]
  3183. %%
  3184. %% @doc Return the list of body subtrees of a <code>clause</code>
  3185. %% node.
  3186. %%
  3187. %% @see clause/3
  3188. clause_body(Node) ->
  3189. case unwrap(Node) of
  3190. {clause, _, _, _, Body} ->
  3191. Body;
  3192. Node1 ->
  3193. (data(Node1))#clause.body
  3194. end.
  3195. %% =====================================================================
  3196. %% @spec disjunction(List::[syntaxTree()]) -> syntaxTree()
  3197. %%
  3198. %% @doc Creates an abstract disjunction. If <code>List</code> is
  3199. %% <code>[E1, ..., En]</code>, the result represents
  3200. %% "<code><em>E1</em>; ...; <em>En</em></code>".
  3201. %%
  3202. %% @see disjunction_body/1
  3203. %% @see conjunction/1
  3204. %% type(Node) = disjunction
  3205. %% data(Node) = [syntaxTree()]
  3206. disjunction(Tests) ->
  3207. tree(disjunction, Tests).
  3208. %% =====================================================================
  3209. %% @spec disjunction_body(syntaxTree()) -> [syntaxTree()]
  3210. %%
  3211. %% @doc Returns the list of body subtrees of a
  3212. %% <code>disjunction</code> node.
  3213. %%
  3214. %% @see disjunction/1
  3215. disjunction_body(Node) ->
  3216. data(Node).
  3217. %% =====================================================================
  3218. %% @spec conjunction(List::[syntaxTree()]) -> syntaxTree()
  3219. %%
  3220. %% @doc Creates an abstract conjunction. If <code>List</code> is
  3221. %% <code>[E1, ..., En]</code>, the result represents
  3222. %% "<code><em>E1</em>, ..., <em>En</em></code>".
  3223. %%
  3224. %% @see conjunction_body/1
  3225. %% @see disjunction/1
  3226. %% type(Node) = conjunction
  3227. %% data(Node) = [syntaxTree()]
  3228. conjunction(Tests) ->
  3229. tree(conjunction, Tests).
  3230. %% =====================================================================
  3231. %% @spec conjunction_body(syntaxTree()) -> [syntaxTree()]
  3232. %%
  3233. %% @doc Returns the list of body subtrees of a
  3234. %% <code>conjunction</code> node.
  3235. %%
  3236. %% @see conjunction/1
  3237. conjunction_body(Node) ->
  3238. data(Node).
  3239. %% =====================================================================
  3240. %% @spec catch_expr(Expr::syntaxTree()) -> syntaxTree()
  3241. %%
  3242. %% @doc Creates an abstract catch-expression. The result represents
  3243. %% "<code>catch <em>Expr</em></code>".
  3244. %%
  3245. %% @see catch_expr_body/1
  3246. %% type(Node) = catch_expr
  3247. %% data(Node) = syntaxTree()
  3248. %%
  3249. %% `erl_parse' representation:
  3250. %%
  3251. %% {'catch', Pos, Expr}
  3252. %%
  3253. %% Expr = erl_parse()
  3254. catch_expr(Expr) ->
  3255. tree(catch_expr, Expr).
  3256. revert_catch_expr(Node) ->
  3257. Pos = get_pos(Node),
  3258. Expr = catch_expr_body(Node),
  3259. {'catch', Pos, Expr}.
  3260. %% =====================================================================
  3261. %% @spec catch_expr_body(syntaxTree()) -> syntaxTree()
  3262. %%
  3263. %% @doc Returns the body subtree of a <code>catch_expr</code> node.
  3264. %%
  3265. %% @see catch_expr/1
  3266. catch_expr_body(Node) ->
  3267. case unwrap(Node) of
  3268. {'catch', _, Expr} ->
  3269. Expr;
  3270. Node1 ->
  3271. data(Node1)
  3272. end.
  3273. %% =====================================================================
  3274. %% @spec match_expr(Pattern::syntaxTree(), Body::syntaxTree()) ->
  3275. %% syntaxTree()
  3276. %%
  3277. %% @doc Creates an abstract match-expression. The result represents
  3278. %% "<code><em>Pattern</em> = <em>Body</em></code>".
  3279. %%
  3280. %% @see match_expr_pattern/1
  3281. %% @see match_expr_body/1
  3282. -record(match_expr, {pattern, body}).
  3283. %% type(Node) = match_expr
  3284. %% data(Node) = #match_expr{pattern :: Pattern, body :: Body}
  3285. %%
  3286. %% Pattern = Body = syntaxTree()
  3287. %%
  3288. %% `erl_parse' representation:
  3289. %%
  3290. %% {match, Pos, Pattern, Body}
  3291. %%
  3292. %% Pattern = Body = erl_parse()
  3293. match_expr(Pattern, Body) ->
  3294. tree(match_expr, #match_expr{pattern = Pattern, body = Body}).
  3295. revert_match_expr(Node) ->
  3296. Pos = get_pos(Node),
  3297. Pattern = match_expr_pattern(Node),
  3298. Body = match_expr_body(Node),
  3299. {match, Pos, Pattern, Body}.
  3300. %% =====================================================================
  3301. %% @spec match_expr_pattern(syntaxTree()) -> syntaxTree()
  3302. %%
  3303. %% @doc Returns the pattern subtree of a <code>match_expr</code> node.
  3304. %%
  3305. %% @see match_expr/2
  3306. match_expr_pattern(Node) ->
  3307. case unwrap(Node) of
  3308. {match, _, Pattern, _} ->
  3309. Pattern;
  3310. Node1 ->
  3311. (data(Node1))#match_expr.pattern
  3312. end.
  3313. %% =====================================================================
  3314. %% @spec match_expr_body(syntaxTree()) -> syntaxTree()
  3315. %%
  3316. %% @doc Returns the body subtree of a <code>match_expr</code> node.
  3317. %%
  3318. %% @see match_expr/2
  3319. match_expr_body(Node) ->
  3320. case unwrap(Node) of
  3321. {match, _, _, Body} ->
  3322. Body;
  3323. Node1 ->
  3324. (data(Node1))#match_expr.body
  3325. end.
  3326. %% =====================================================================
  3327. %% @spec operator(Name) -> syntaxTree()
  3328. %% Name = atom() | string()
  3329. %%
  3330. %% @doc Creates an abstract operator. The name of the operator is the
  3331. %% character sequence represented by <code>Name</code>. This is
  3332. %% analogous to the print name of an atom, but an operator is never
  3333. %% written within single-quotes; e.g., the result of
  3334. %% <code>operator('++')</code> represents "<code>++</code>" rather
  3335. %% than "<code>'++'</code>".
  3336. %%
  3337. %% @see operator_name/1
  3338. %% @see operator_literal/1
  3339. %% @see atom/1
  3340. %% type(Node) = operator
  3341. %% data(Node) = atom()
  3342. operator(Name) when atom(Name) ->
  3343. tree(operator, Name);
  3344. operator(Name) ->
  3345. tree(operator, list_to_atom(Name)).
  3346. %% =====================================================================
  3347. %% @spec operator_name(syntaxTree())-> atom()
  3348. %%
  3349. %% @doc Returns the name of an <code>operator</code> node. Note that
  3350. %% the name is returned as an atom.
  3351. %%
  3352. %% @see operator/1
  3353. operator_name(Node) ->
  3354. data(Node).
  3355. %% =====================================================================
  3356. %% @spec operator_literal(syntaxTree())-> string()
  3357. %%
  3358. %% @doc Returns the literal string represented by an
  3359. %% <code>operator</code> node. This is simply the operator name as a
  3360. %% string.
  3361. %%
  3362. %% @see operator/1
  3363. operator_literal(Node) ->
  3364. atom_to_list(operator_name(Node)).
  3365. %% =====================================================================
  3366. %% @spec infix_expr(Left::syntaxTree(), Operator::syntaxTree(),
  3367. %% Right::syntaxTree()) -> syntaxTree()
  3368. %%
  3369. %% @doc Creates an abstract infix operator expression. The result
  3370. %% represents "<code><em>Left</em> <em>Operator</em>
  3371. %% <em>Right</em></code>".
  3372. %%
  3373. %% @see infix_expr_left/1
  3374. %% @see infix_expr_right/1
  3375. %% @see infix_expr_operator/1
  3376. %% @see prefix_expr/2
  3377. -record(infix_expr, {operator, left, right}).
  3378. %% type(Node) = infix_expr
  3379. %% data(Node) = #infix_expr{left :: Left, operator :: Operator,
  3380. %% right :: Right}
  3381. %%
  3382. %% Left = Operator = Right = syntaxTree()
  3383. %%
  3384. %% `erl_parse' representation:
  3385. %%
  3386. %% {op, Pos, Operator, Left, Right}
  3387. %%
  3388. %% Operator = atom()
  3389. %% Left = Right = erl_parse()
  3390. infix_expr(Left, Operator, Right) ->
  3391. tree(infix_expr, #infix_expr{operator = Operator, left = Left,
  3392. right = Right}).
  3393. revert_infix_expr(Node) ->
  3394. Pos = get_pos(Node),
  3395. Operator = infix_expr_operator(Node),
  3396. Left = infix_expr_left(Node),
  3397. Right = infix_expr_right(Node),
  3398. case type(Operator) of
  3399. operator ->
  3400. %% Note that the operator itself is not revertible out
  3401. %% of context.
  3402. {op, Pos, operator_name(Operator), Left, Right};
  3403. _ ->
  3404. Node
  3405. end.
  3406. %% =====================================================================
  3407. %% @spec infix_expr_left(syntaxTree()) -> syntaxTree()
  3408. %%
  3409. %% @doc Returns the left argument subtree of an
  3410. %% <code>infix_expr</code> node.
  3411. %%
  3412. %% @see infix_expr/3
  3413. infix_expr_left(Node) ->
  3414. case unwrap(Node) of
  3415. {op, _, _, Left, _} ->
  3416. Left;
  3417. Node1 ->
  3418. (data(Node1))#infix_expr.left
  3419. end.
  3420. %% =====================================================================
  3421. %% @spec infix_expr_operator(syntaxTree()) -> syntaxTree()
  3422. %%
  3423. %% @doc Returns the operator subtree of an <code>infix_expr</code>
  3424. %% node.
  3425. %%
  3426. %% @see infix_expr/3
  3427. infix_expr_operator(Node) ->
  3428. case unwrap(Node) of
  3429. {op, Pos, Operator, _, _} ->
  3430. set_pos(operator(Operator), Pos);
  3431. Node1 ->
  3432. (data(Node1))#infix_expr.operator
  3433. end.
  3434. %% =====================================================================
  3435. %% @spec infix_expr_right(syntaxTree()) -> syntaxTree()
  3436. %%
  3437. %% @doc Returns the right argument subtree of an
  3438. %% <code>infix_expr</code> node.
  3439. %%
  3440. %% @see infix_expr/3
  3441. infix_expr_right(Node) ->
  3442. case unwrap(Node) of
  3443. {op, _, _, _, Right} ->
  3444. Right;
  3445. Node1 ->
  3446. (data(Node1))#infix_expr.right
  3447. end.
  3448. %% =====================================================================
  3449. %% @spec prefix_expr(Operator::syntaxTree(), Argument::syntaxTree()) ->
  3450. %% syntaxTree()
  3451. %%
  3452. %% @doc Creates an abstract prefix operator expression. The result
  3453. %% represents "<code><em>Operator</em> <em>Argument</em></code>".
  3454. %%
  3455. %% @see prefix_expr_argument/1
  3456. %% @see prefix_expr_operator/1
  3457. %% @see infix_expr/3
  3458. -record(prefix_expr, {operator, argument}).
  3459. %% type(Node) = prefix_expr
  3460. %% data(Node) = #prefix_expr{operator :: Operator,
  3461. %% argument :: Argument}
  3462. %%
  3463. %% Operator = Argument = syntaxTree()
  3464. %%
  3465. %% `erl_parse' representation:
  3466. %%
  3467. %% {op, Pos, Operator, Arg}
  3468. %%
  3469. %% Operator = atom()
  3470. %% Argument = erl_parse()
  3471. prefix_expr(Operator, Argument) ->
  3472. tree(prefix_expr, #prefix_expr{operator = Operator,
  3473. argument = Argument}).
  3474. revert_prefix_expr(Node) ->
  3475. Pos = get_pos(Node),
  3476. Operator = prefix_expr_operator(Node),
  3477. Argument = prefix_expr_argument(Node),
  3478. case type(Operator) of
  3479. operator ->
  3480. %% Note that the operator itself is not revertible out
  3481. %% of context.
  3482. {op, Pos, operator_name(Operator), Argument};
  3483. _ ->
  3484. Node
  3485. end.
  3486. %% =====================================================================
  3487. %% @spec prefix_expr_operator(syntaxTree()) -> syntaxTree()
  3488. %%
  3489. %% @doc Returns the operator subtree of a <code>prefix_expr</code>
  3490. %% node.
  3491. %%
  3492. %% @see prefix_expr/2
  3493. prefix_expr_operator(Node) ->
  3494. case unwrap(Node) of
  3495. {op, Pos, Operator, _} ->
  3496. set_pos(operator(Operator), Pos);
  3497. Node1 ->
  3498. (data(Node1))#prefix_expr.operator
  3499. end.
  3500. %% =====================================================================
  3501. %% @spec prefix_expr_argument(syntaxTree()) -> syntaxTree()
  3502. %%
  3503. %% @doc Returns the argument subtree of a <code>prefix_expr</code>
  3504. %% node.
  3505. %%
  3506. %% @see prefix_expr/2
  3507. prefix_expr_argument(Node) ->
  3508. case unwrap(Node) of
  3509. {op, _, _, Argument} ->
  3510. Argument;
  3511. Node1 ->
  3512. (data(Node1))#prefix_expr.argument
  3513. end.
  3514. %% =====================================================================
  3515. %% @spec record_field(Name) -> syntaxTree()
  3516. %% @equiv record_field(Name, none)
  3517. record_field(Name) ->
  3518. record_field(Name, none).
  3519. %% =====================================================================
  3520. %% @spec record_field(Name::syntaxTree(), Value) -> syntaxTree()
  3521. %% Value = none | syntaxTree()
  3522. %%
  3523. %% @doc Creates an abstract record field specification. If
  3524. %% <code>Value</code> is <code>none</code>, the result represents
  3525. %% simply "<code><em>Name</em></code>", otherwise it represents
  3526. %% "<code><em>Name</em> = <em>Value</em></code>".
  3527. %%
  3528. %% @see record_field_name/1
  3529. %% @see record_field_value/1
  3530. %% @see record_expr/3
  3531. -record(record_field, {name, value}).
  3532. %% type(Node) = record_field
  3533. %% data(Node) = #record_field{name :: Name, value :: Value}
  3534. %%
  3535. %% Name = Value = syntaxTree()
  3536. record_field(Name, Value) ->
  3537. tree(record_field, #record_field{name = Name, value = Value}).
  3538. %% =====================================================================
  3539. %% @spec record_field_name(syntaxTree()) -> syntaxTree()
  3540. %%
  3541. %% @doc Returns the name subtree of a <code>record_field</code> node.
  3542. %%
  3543. %% @see record_field/2
  3544. record_field_name(Node) ->
  3545. (data(Node))#record_field.name.
  3546. %% =====================================================================
  3547. %% @spec record_field_value(syntaxTree()) -> none | syntaxTree()
  3548. %%
  3549. %% @doc Returns the value subtree of a <code>record_field</code> node,
  3550. %% if any. If <code>Node</code> represents
  3551. %% "<code><em>Name</em></code>", <code>none</code> is
  3552. %% returned. Otherwise, if <code>Node</code> represents
  3553. %% "<code><em>Name</em> = <em>Value</em></code>", <code>Value</code>
  3554. %% is returned.
  3555. %%
  3556. %% @see record_field/2
  3557. record_field_value(Node) ->
  3558. (data(Node))#record_field.value.
  3559. %% =====================================================================
  3560. %% @spec record_index_expr(Type::syntaxTree(), Field::syntaxTree()) ->
  3561. %% syntaxTree()
  3562. %%
  3563. %% @doc Creates an abstract record field index expression. The result
  3564. %% represents "<code>#<em>Type</em>.<em>Field</em></code>".
  3565. %%
  3566. %% <p>(Note: the function name <code>record_index/2</code> is reserved
  3567. %% by the Erlang compiler, which is why that name could not be used
  3568. %% for this constructor.)</p>
  3569. %%
  3570. %% @see record_index_expr_type/1
  3571. %% @see record_index_expr_field/1
  3572. %% @see record_expr/3
  3573. -record(record_index_expr, {type, field}).
  3574. %% type(Node) = record_index_expr
  3575. %% data(Node) = #record_index_expr{type :: Type, field :: Field}
  3576. %%
  3577. %% Type = Field = syntaxTree()
  3578. %%
  3579. %% `erl_parse' representation:
  3580. %%
  3581. %% {record_index, Pos, Type, Field}
  3582. %%
  3583. %% Type = atom()
  3584. %% Field = erl_parse()
  3585. record_index_expr(Type, Field) ->
  3586. tree(record_index_expr, #record_index_expr{type = Type,
  3587. field = Field}).
  3588. revert_record_index_expr(Node) ->
  3589. Pos = get_pos(Node),
  3590. Type = record_index_expr_type(Node),
  3591. Field = record_index_expr_field(Node),
  3592. case type(Type) of
  3593. atom ->
  3594. {record_index, Pos, concrete(Type), Field};
  3595. _ ->
  3596. Node
  3597. end.
  3598. %% =====================================================================
  3599. %% @spec record_index_expr_type(syntaxTree()) -> syntaxTree()
  3600. %%
  3601. %% @doc Returns the type subtree of a <code>record_index_expr</code>
  3602. %% node.
  3603. %%
  3604. %% @see record_index_expr/2
  3605. record_index_expr_type(Node) ->
  3606. case unwrap(Node) of
  3607. {record_index, Pos, Type, _} ->
  3608. set_pos(atom(Type), Pos);
  3609. Node1 ->
  3610. (data(Node1))#record_index_expr.type
  3611. end.
  3612. %% =====================================================================
  3613. %% @spec record_index_expr_field(syntaxTree()) -> syntaxTree()
  3614. %%
  3615. %% @doc Returns the field subtree of a <code>record_index_expr</code>
  3616. %% node.
  3617. %%
  3618. %% @see record_index_expr/2
  3619. record_index_expr_field(Node) ->
  3620. case unwrap(Node) of
  3621. {record_index, _, _, Field} ->
  3622. Field;
  3623. Node1 ->
  3624. (data(Node1))#record_index_expr.field
  3625. end.
  3626. %% =====================================================================
  3627. %% @spec record_access(Argument, Field) -> syntaxTree()
  3628. %% @equiv record_access(Argument, none, Field)
  3629. record_access(Argument, Field) ->
  3630. record_access(Argument, none, Field).
  3631. %% =====================================================================
  3632. %% @spec record_access(Argument::syntaxTree(), Type,
  3633. %% Field::syntaxTree()) -> syntaxTree()
  3634. %% Type = none | syntaxTree()
  3635. %%
  3636. %% @doc Creates an abstract record field access expression. If
  3637. %% <code>Type</code> is not <code>none</code>, the result represents
  3638. %% "<code><em>Argument</em>#<em>Type</em>.<em>Field</em></code>".
  3639. %%
  3640. %% <p>If <code>Type</code> is <code>none</code>, the result represents
  3641. %% "<code><em>Argument</em>.<em>Field</em></code>". This is a special
  3642. %% form only allowed within Mnemosyne queries.</p>
  3643. %%
  3644. %% @see record_access/2
  3645. %% @see record_access_argument/1
  3646. %% @see record_access_type/1
  3647. %% @see record_access_field/1
  3648. %% @see record_expr/3
  3649. %% @see query_expr/1
  3650. -record(record_access, {argument, type, field}).
  3651. %% type(Node) = record_access
  3652. %% data(Node) = #record_access{argument :: Argument, type :: Type,
  3653. %% field :: Field}
  3654. %%
  3655. %% Argument = Field = syntaxTree()
  3656. %% Type = none | syntaxTree()
  3657. %%
  3658. %% `erl_parse' representation:
  3659. %%
  3660. %% {record_field, Pos, Argument, Type, Field}
  3661. %% {record_field, Pos, Argument, Field}
  3662. %%
  3663. %% Argument = Field = erl_parse()
  3664. %% Type = atom()
  3665. record_access(Argument, Type, Field) ->
  3666. tree(record_access,#record_access{argument = Argument,
  3667. type = Type,
  3668. field = Field}).
  3669. revert_record_access(Node) ->
  3670. Pos = get_pos(Node),
  3671. Argument = record_access_argument(Node),
  3672. Type = record_access_type(Node),
  3673. Field = record_access_field(Node),
  3674. if Type == none ->
  3675. {record_field, Pos, Argument, Field};
  3676. true ->
  3677. case type(Type) of
  3678. atom ->
  3679. {record_field, Pos,
  3680. Argument, concrete(Type), Field};
  3681. _ ->
  3682. Node
  3683. end
  3684. end.
  3685. %% =====================================================================
  3686. %% @spec record_access_argument(syntaxTree()) -> syntaxTree()
  3687. %%
  3688. %% @doc Returns the argument subtree of a <code>record_access</code>
  3689. %% node.
  3690. %%
  3691. %% @see record_access/3
  3692. record_access_argument(Node) ->
  3693. case unwrap(Node) of
  3694. {record_field, _, Argument, _} ->
  3695. Argument;
  3696. {record_field, _, Argument, _, _} ->
  3697. Argument;
  3698. Node1 ->
  3699. (data(Node1))#record_access.argument
  3700. end.
  3701. %% =====================================================================
  3702. %% @spec record_access_type(syntaxTree()) -> none | syntaxTree()
  3703. %%
  3704. %% @doc Returns the type subtree of a <code>record_access</code> node,
  3705. %% if any. If <code>Node</code> represents
  3706. %% "<code><em>Argument</em>.<em>Field</em></code>", <code>none</code>
  3707. %% is returned, otherwise if <code>Node</code> represents
  3708. %% "<code><em>Argument</em>#<em>Type</em>.<em>Field</em></code>",
  3709. %% <code>Type</code> is returned.
  3710. %%
  3711. %% @see record_access/3
  3712. record_access_type(Node) ->
  3713. case unwrap(Node) of
  3714. {record_field, _, _, _} ->
  3715. none;
  3716. {record_field, Pos, _, Type, _} ->
  3717. set_pos(atom(Type), Pos);
  3718. Node1 ->
  3719. (data(Node1))#record_access.type
  3720. end.
  3721. %% =====================================================================
  3722. %% @spec record_access_field(syntaxTree()) -> syntaxTree()
  3723. %%
  3724. %% @doc Returns the field subtree of a <code>record_access</code>
  3725. %% node.
  3726. %%
  3727. %% @see record_access/3
  3728. record_access_field(Node) ->
  3729. case unwrap(Node) of
  3730. {record_field, _, _, Field} ->
  3731. Field;
  3732. {record_field, _, _, _, Field} ->
  3733. Field;
  3734. Node1 ->
  3735. (data(Node1))#record_access.field
  3736. end.
  3737. %% =====================================================================
  3738. %% @spec record_expr(Type, Fields) -> syntaxTree()
  3739. %% @equiv record_expr(none, Type, Fields)
  3740. record_expr(Type, Fields) ->
  3741. record_expr(none, Type, Fields).
  3742. %% =====================================================================
  3743. %% @spec record_expr(Argument, Type::syntaxTree(),
  3744. %% Fields::[syntaxTree()]) -> syntaxTree()
  3745. %% Argument = none | syntaxTree()
  3746. %%
  3747. %% @doc Creates an abstract record expression. If <code>Fields</code> is
  3748. %% <code>[F1, ..., Fn]</code>, then if <code>Argument</code> is
  3749. %% <code>none</code>, the result represents
  3750. %% "<code>#<em>Type</em>{<em>F1</em>, ..., <em>Fn</em>}</code>",
  3751. %% otherwise it represents
  3752. %% "<code><em>Argument</em>#<em>Type</em>{<em>F1</em>, ...,
  3753. %% <em>Fn</em>}</code>".
  3754. %%
  3755. %% @see record_expr/2
  3756. %% @see record_expr_argument/1
  3757. %% @see record_expr_fields/1
  3758. %% @see record_expr_type/1
  3759. %% @see record_field/2
  3760. %% @see record_index_expr/2
  3761. %% @see record_access/3
  3762. -record(record_expr, {argument, type, fields}).
  3763. %% type(Node) = record_expr
  3764. %% data(Node) = #record_expr{argument :: Argument, type :: Type,
  3765. %% fields :: Fields}
  3766. %%
  3767. %% Argument = none | syntaxTree()
  3768. %% Type = syntaxTree
  3769. %% Fields = [syntaxTree()]
  3770. %%
  3771. %% `erl_parse' representation:
  3772. %%
  3773. %% {record, Pos, Type, Fields}
  3774. %% {record, Pos, Argument, Type, Fields}
  3775. %%
  3776. %% Argument = erl_parse()
  3777. %% Type = atom()
  3778. %% Fields = [Entry]
  3779. %% Entry = {record_field, Pos, Field, Value}
  3780. %% | {record_field, Pos, Field}
  3781. %% Field = Value = erl_parse()
  3782. record_expr(Argument, Type, Fields) ->
  3783. tree(record_expr, #record_expr{argument = Argument,
  3784. type = Type, fields = Fields}).
  3785. revert_record_expr(Node) ->
  3786. Pos = get_pos(Node),
  3787. Argument = record_expr_argument(Node),
  3788. Type = record_expr_type(Node),
  3789. Fields = record_expr_fields(Node),
  3790. case type(Type) of
  3791. atom ->
  3792. T = concrete(Type),
  3793. Fs = fold_record_fields(Fields),
  3794. case Argument of
  3795. none ->
  3796. {record, Pos, T, Fs};
  3797. _ ->
  3798. {record, Pos, Argument, T, Fs}
  3799. end;
  3800. _ ->
  3801. Node
  3802. end.
  3803. %% =====================================================================
  3804. %% @spec record_expr_argument(syntaxTree()) -> none | syntaxTree()
  3805. %%
  3806. %% @doc Returns the argument subtree of a <code>record_expr</code> node,
  3807. %% if any. If <code>Node</code> represents
  3808. %% "<code>#<em>Type</em>{...}</code>", <code>none</code> is returned.
  3809. %% Otherwise, if <code>Node</code> represents
  3810. %% "<code><em>Argument</em>#<em>Type</em>{...}</code>",
  3811. %% <code>Argument</code> is returned.
  3812. %%
  3813. %% @see record_expr/3
  3814. record_expr_argument(Node) ->
  3815. case unwrap(Node) of
  3816. {record, _, _, _} ->
  3817. none;
  3818. {record, _, Argument, _, _} ->
  3819. Argument;
  3820. Node1 ->
  3821. (data(Node1))#record_expr.argument
  3822. end.
  3823. %% =====================================================================
  3824. %% record_expr_type(Node) -> Type
  3825. %%
  3826. %% Node = Type = syntaxTree()
  3827. %% type(Node) = record_expr
  3828. %%
  3829. %% @doc Returns the type subtree of a <code>record_expr</code> node.
  3830. %%
  3831. %% @see record_expr/3
  3832. record_expr_type(Node) ->
  3833. case unwrap(Node) of
  3834. {record, Pos, Type, _} ->
  3835. set_pos(atom(Type), Pos);
  3836. {record, Pos, _, Type, _} ->
  3837. set_pos(atom(Type), Pos);
  3838. Node1 ->
  3839. (data(Node1))#record_expr.type
  3840. end.
  3841. %% =====================================================================
  3842. %% record_expr_fields(Node) -> Fields
  3843. %%
  3844. %% Node = syntaxTree()
  3845. %% Fields = [syntaxTree()]
  3846. %% type(Node) = record_expr
  3847. %%
  3848. %% @doc Returns the list of field subtrees of a
  3849. %% <code>record_expr</code> node.
  3850. %%
  3851. %% @see record_expr/3
  3852. record_expr_fields(Node) ->
  3853. case unwrap(Node) of
  3854. {record, _, _, Fields} ->
  3855. unfold_record_fields(Fields);
  3856. {record, _, _, _, Fields} ->
  3857. unfold_record_fields(Fields);
  3858. Node1 ->
  3859. (data(Node1))#record_expr.fields
  3860. end.
  3861. %% =====================================================================
  3862. %% @spec application(Module, Function::syntaxTree(),
  3863. %% Arguments::[syntaxTree()]) -> syntaxTree()
  3864. %% Module = none | syntaxTree()
  3865. %%
  3866. %% @doc Creates an abstract function application expression. (Utility
  3867. %% function.) If <code>Module</code> is <code>none</code>, this is
  3868. %% call is equivalent to <code>application(Function,
  3869. %% Arguments)</code>, otherwise it is equivalent to
  3870. %% <code>application(module_qualifier(Module, Function),
  3871. %% Arguments)</code>.
  3872. %%
  3873. %% @see application/2
  3874. %% @see module_qualifier/2
  3875. application(none, Name, Arguments) ->
  3876. application(Name, Arguments);
  3877. application(Module, Name, Arguments) ->
  3878. application(module_qualifier(Module, Name), Arguments).
  3879. %% =====================================================================
  3880. %% @spec application(Operator::syntaxTree(),
  3881. %% Arguments::[syntaxTree()]) -> syntaxTree()
  3882. %%
  3883. %% @doc Creates an abstract function application expression. If
  3884. %% <code>Arguments</code> is <code>[A1, ..., An]</code>, the result
  3885. %% represents "<code><em>Operator</em>(<em>A1</em>, ...,
  3886. %% <em>An</em>)</code>".
  3887. %%
  3888. %% @see application_operator/1
  3889. %% @see application_arguments/1
  3890. %% @see application/3
  3891. -record(application, {operator, arguments}).
  3892. %% type(Node) = application
  3893. %% data(Node) = #application{operator :: Operator,
  3894. %% arguments :: Arguments}
  3895. %%
  3896. %% Operator = syntaxTree()
  3897. %% Arguments = [syntaxTree()]
  3898. %%
  3899. %% `erl_parse' representation:
  3900. %%
  3901. %% {call, Pos, Fun, Args}
  3902. %%
  3903. %% Operator = erl_parse()
  3904. %% Arguments = [erl_parse()]
  3905. application(Operator, Arguments) ->
  3906. tree(application, #application{operator = Operator,
  3907. arguments = Arguments}).
  3908. revert_application(Node) ->
  3909. Pos = get_pos(Node),
  3910. Operator = application_operator(Node),
  3911. Arguments = application_arguments(Node),
  3912. {call, Pos, Operator, Arguments}.
  3913. %% =====================================================================
  3914. %% @spec application_operator(syntaxTree()) -> syntaxTree()
  3915. %%
  3916. %% @doc Returns the operator subtree of an <code>application</code>
  3917. %% node.
  3918. %%
  3919. %% <p>Note: if <code>Node</code> represents
  3920. %% "<code><em>M</em>:<em>F</em>(...)</code>", then the result is the
  3921. %% subtree representing "<code><em>M</em>:<em>F</em></code>".</p>
  3922. %%
  3923. %% @see application/2
  3924. %% @see module_qualifier/2
  3925. application_operator(Node) ->
  3926. case unwrap(Node) of
  3927. {call, _, Operator, _} ->
  3928. Operator;
  3929. Node1 ->
  3930. (data(Node1))#application.operator
  3931. end.
  3932. %% =====================================================================
  3933. %% @spec application_arguments(syntaxTree()) -> [syntaxTree()]
  3934. %%
  3935. %% @doc Returns the list of argument subtrees of an
  3936. %% <code>application</code> node.
  3937. %%
  3938. %% @see application/2
  3939. application_arguments(Node) ->
  3940. case unwrap(Node) of
  3941. {call, _, _, Arguments} ->
  3942. Arguments;
  3943. Node1 ->
  3944. (data(Node1))#application.arguments
  3945. end.
  3946. %% =====================================================================
  3947. %% @spec list_comp(Template::syntaxTree(), Body::[syntaxTree()]) ->
  3948. %% syntaxTree()
  3949. %%
  3950. %% @doc Creates an abstract list comprehension. If <code>Body</code> is
  3951. %% <code>[E1, ..., En]</code>, the result represents
  3952. %% "<code>[<em>Template</em> || <em>E1</em>, ..., <em>En</em>]</code>".
  3953. %%
  3954. %% @see list_comp_template/1
  3955. %% @see list_comp_body/1
  3956. %% @see generator/2
  3957. -record(list_comp, {template, body}).
  3958. %% type(Node) = list_comp
  3959. %% data(Node) = #list_comp{template :: Template, body :: Body}
  3960. %%
  3961. %% Template = Node = syntaxTree()
  3962. %% Body = [syntaxTree()]
  3963. %%
  3964. %% `erl_parse' representation:
  3965. %%
  3966. %% {lc, Pos, Template, Body}
  3967. %%
  3968. %% Template = erl_parse()
  3969. %% Body = [erl_parse()] \ []
  3970. list_comp(Template, Body) ->
  3971. tree(list_comp, #list_comp{template = Template, body = Body}).
  3972. revert_list_comp(Node) ->
  3973. Pos = get_pos(Node),
  3974. Template = list_comp_template(Node),
  3975. Body = list_comp_body(Node),
  3976. {lc, Pos, Template, Body}.
  3977. %% =====================================================================
  3978. %% @spec list_comp_template(syntaxTree()) -> syntaxTree()
  3979. %%
  3980. %% @doc Returns the template subtree of a <code>list_comp</code> node.
  3981. %%
  3982. %% @see list_comp/2
  3983. list_comp_template(Node) ->
  3984. case unwrap(Node) of
  3985. {lc, _, Template, _} ->
  3986. Template;
  3987. Node1 ->
  3988. (data(Node1))#list_comp.template
  3989. end.
  3990. %% =====================================================================
  3991. %% @spec list_comp_body(syntaxTree()) -> [syntaxTree()]
  3992. %%
  3993. %% @doc Returns the list of body subtrees of a <code>list_comp</code>
  3994. %% node.
  3995. %%
  3996. %% @see list_comp/2
  3997. list_comp_body(Node) ->
  3998. case unwrap(Node) of
  3999. {lc, _, _, Body} ->
  4000. Body;
  4001. Node1 ->
  4002. (data(Node1))#list_comp.body
  4003. end.
  4004. %% =====================================================================
  4005. %% @spec query_expr(Body::syntaxTree()) -> syntaxTree()
  4006. %%
  4007. %% @doc Creates an abstract Mnemosyne query expression. The result
  4008. %% represents "<code>query <em>Body</em> end</code>".
  4009. %%
  4010. %% @see query_expr_body/1
  4011. %% @see record_access/2
  4012. %% @see rule/2
  4013. %% type(Node) = query_expr
  4014. %% data(Node) = syntaxTree()
  4015. %%
  4016. %% `erl_parse' representation:
  4017. %%
  4018. %% {'query', Pos, Body}
  4019. %%
  4020. %% Body = erl_parse()
  4021. query_expr(Body) ->
  4022. tree(query_expr, Body).
  4023. revert_query_expr(Node) ->
  4024. Pos = get_pos(Node),
  4025. Body = list_comp_body(Node),
  4026. {'query', Pos, Body}.
  4027. %% =====================================================================
  4028. %% @spec query_expr_body(syntaxTree()) -> syntaxTree()
  4029. %%
  4030. %% @doc Returns the body subtree of a <code>query_expr</code> node.
  4031. %%
  4032. %% @see query_expr/1
  4033. query_expr_body(Node) ->
  4034. case unwrap(Node) of
  4035. {'query', _, Body} ->
  4036. Body;
  4037. Node1 ->
  4038. data(Node1)
  4039. end.
  4040. %% =====================================================================
  4041. %% @spec rule(Name::syntaxTree(), Clauses::[syntaxTree()]) ->
  4042. %% syntaxTree()
  4043. %%
  4044. %% @doc Creates an abstract Mnemosyne rule. If <code>Clauses</code> is
  4045. %% <code>[C1, ..., Cn]</code>, the results represents
  4046. %% "<code><em>Name</em> <em>C1</em>; ...; <em>Name</em>
  4047. %% <em>Cn</em>.</code>". More exactly, if each <code>Ci</code>
  4048. %% represents "<code>(<em>Pi1</em>, ..., <em>Pim</em>) <em>Gi</em> ->
  4049. %% <em>Bi</em></code>", then the result represents
  4050. %% "<code><em>Name</em>(<em>P11</em>, ..., <em>P1m</em>) <em>G1</em> :-
  4051. %% <em>B1</em>; ...; <em>Name</em>(<em>Pn1</em>, ..., <em>Pnm</em>)
  4052. %% <em>Gn</em> :- <em>Bn</em>.</code>". Rules are source code forms.
  4053. %%
  4054. %% @see rule_name/1
  4055. %% @see rule_clauses/1
  4056. %% @see rule_arity/1
  4057. %% @see is_form/1
  4058. %% @see function/2
  4059. -record(rule, {name, clauses}).
  4060. %% type(Node) = rule
  4061. %% data(Node) = #rule{name :: Name, clauses :: Clauses}
  4062. %%
  4063. %% Name = syntaxTree()
  4064. %% Clauses = [syntaxTree()]
  4065. %%
  4066. %% (See `function' for notes on why the arity is not stored.)
  4067. %%
  4068. %% `erl_parse' representation:
  4069. %%
  4070. %% {rule, Pos, Name, Arity, Clauses}
  4071. %%
  4072. %% Name = atom()
  4073. %% Arity = integer()
  4074. %% Clauses = [Clause] \ []
  4075. %% Clause = {clause, ...}
  4076. %%
  4077. %% where the number of patterns in each clause should be equal to
  4078. %% the integer `Arity'; see `clause' for documentation on
  4079. %% `erl_parse' clauses.
  4080. rule(Name, Clauses) ->
  4081. tree(rule, #rule{name = Name, clauses = Clauses}).
  4082. revert_rule(Node) ->
  4083. Name = rule_name(Node),
  4084. Clauses = [revert_clause(C) || C <- rule_clauses(Node)],
  4085. Pos = get_pos(Node),
  4086. case type(Name) of
  4087. atom ->
  4088. A = rule_arity(Node),
  4089. {rule, Pos, concrete(Name), A, Clauses};
  4090. _ ->
  4091. Node
  4092. end.
  4093. %% =====================================================================
  4094. %% @spec rule_name(syntaxTree()) -> syntaxTree()
  4095. %%
  4096. %% @doc Returns the name subtree of a <code>rule</code> node.
  4097. %%
  4098. %% @see rule/2
  4099. rule_name(Node) ->
  4100. case unwrap(Node) of
  4101. {rule, Pos, Name, _, _} ->
  4102. set_pos(atom(Name), Pos);
  4103. Node1 ->
  4104. (data(Node1))#rule.name
  4105. end.
  4106. %% =====================================================================
  4107. %% @spec rule_clauses(syntaxTree()) -> [syntaxTree()]
  4108. %%
  4109. %% @doc Returns the list of clause subtrees of a <code>rule</code> node.
  4110. %%
  4111. %% @see rule/2
  4112. rule_clauses(Node) ->
  4113. case unwrap(Node) of
  4114. {rule, _, _, _, Clauses} ->
  4115. Clauses;
  4116. Node1 ->
  4117. (data(Node1))#rule.clauses
  4118. end.
  4119. %% =====================================================================
  4120. %% @spec rule_arity(Node::syntaxTree()) -> integer()
  4121. %%
  4122. %% @doc Returns the arity of a <code>rule</code> node. The result is the
  4123. %% number of parameter patterns in the first clause of the rule;
  4124. %% subsequent clauses are ignored.
  4125. %%
  4126. %% <p>An exception is thrown if <code>rule_clauses(Node)</code> returns
  4127. %% an empty list, or if the first element of that list is not a syntax
  4128. %% tree <code>C</code> of type <code>clause</code> such that
  4129. %% <code>clause_patterns(C)</code> is a nonempty list.</p>
  4130. %%
  4131. %% @see rule/2
  4132. %% @see rule_clauses/1
  4133. %% @see clause/3
  4134. %% @see clause_patterns/1
  4135. rule_arity(Node) ->
  4136. %% Note that this never accesses the arity field of
  4137. %% `erl_parse' rule nodes.
  4138. length(clause_patterns(hd(rule_clauses(Node)))).
  4139. %% =====================================================================
  4140. %% @spec generator(Pattern::syntaxTree(), Body::syntaxTree()) ->
  4141. %% syntaxTree()
  4142. %%
  4143. %% @doc Creates an abstract generator. The result represents
  4144. %% "<code><em>Pattern</em> &lt;- <em>Body</em></code>".
  4145. %%
  4146. %% @see generator_pattern/1
  4147. %% @see generator_body/1
  4148. %% @see list_comp/2
  4149. -record(generator, {pattern, body}).
  4150. %% type(Node) = generator
  4151. %% data(Node) = #generator{pattern :: Pattern, body :: Body}
  4152. %%
  4153. %% Pattern = Argument = syntaxTree()
  4154. %%
  4155. %% `erl_parse' representation:
  4156. %%
  4157. %% {generate, Pos, Pattern, Body}
  4158. %%
  4159. %% Pattern = Body = erl_parse()
  4160. generator(Pattern, Body) ->
  4161. tree(generator, #generator{pattern = Pattern, body = Body}).
  4162. revert_generator(Node) ->
  4163. Pos = get_pos(Node),
  4164. Pattern = generator_pattern(Node),
  4165. Body = generator_body(Node),
  4166. {generate, Pos, Pattern, Body}.
  4167. %% =====================================================================
  4168. %% @spec generator_pattern(syntaxTree()) -> syntaxTree()
  4169. %%
  4170. %% @doc Returns the pattern subtree of a <code>generator</code> node.
  4171. %%
  4172. %% @see generator/2
  4173. generator_pattern(Node) ->
  4174. case unwrap(Node) of
  4175. {generate, _, Pattern, _} ->
  4176. Pattern;
  4177. Node1 ->
  4178. (data(Node1))#generator.pattern
  4179. end.
  4180. %% =====================================================================
  4181. %% @spec generator_body(syntaxTree()) -> syntaxTree()
  4182. %%
  4183. %% @doc Returns the body subtree of a <code>generator</code> node.
  4184. %%
  4185. %% @see generator/2
  4186. generator_body(Node) ->
  4187. case unwrap(Node) of
  4188. {generate, _, _, Body} ->
  4189. Body;
  4190. Node1 ->
  4191. (data(Node1))#generator.body
  4192. end.
  4193. %% =====================================================================
  4194. %% @spec block_expr(Body::[syntaxTree()]) -> syntaxTree()
  4195. %%
  4196. %% @doc Creates an abstract block expression. If <code>Body</code> is
  4197. %% <code>[B1, ..., Bn]</code>, the result represents "<code>begin
  4198. %% <em>B1</em>, ..., <em>Bn</em> end</code>".
  4199. %%
  4200. %% @see block_expr_body/1
  4201. %% type(Node) = block_expr
  4202. %% data(Node) = Body
  4203. %%
  4204. %% Body = [syntaxTree()]
  4205. %%
  4206. %% `erl_parse' representation:
  4207. %%
  4208. %% {block, Pos, Body}
  4209. %%
  4210. %% Body = [erl_parse()] \ []
  4211. block_expr(Body) ->
  4212. tree(block_expr, Body).
  4213. revert_block_expr(Node) ->
  4214. Pos = get_pos(Node),
  4215. Body = block_expr_body(Node),
  4216. {block, Pos, Body}.
  4217. %% =====================================================================
  4218. %% @spec block_expr_body(syntaxTree()) -> [syntaxTree()]
  4219. %%
  4220. %% @doc Returns the list of body subtrees of a <code>block_expr</code>
  4221. %% node.
  4222. %%
  4223. %% @see block_expr/1
  4224. block_expr_body(Node) ->
  4225. case unwrap(Node) of
  4226. {block, _, Body} ->
  4227. Body;
  4228. Node1 ->
  4229. data(Node1)
  4230. end.
  4231. %% =====================================================================
  4232. %% @spec if_expr(Clauses::[syntaxTree()]) -> syntaxTree()
  4233. %%
  4234. %% @doc Creates an abstract if-expression. If <code>Clauses</code> is
  4235. %% <code>[C1, ..., Cn]</code>, the result represents "<code>if
  4236. %% <em>C1</em>; ...; <em>Cn</em> end</code>". More exactly, if each
  4237. %% <code>Ci</code> represents "<code>() <em>Gi</em> ->
  4238. %% <em>Bi</em></code>", then the result represents "<code>if
  4239. %% <em>G1</em> -> <em>B1</em>; ...; <em>Gn</em> -> <em>Bn</em>
  4240. %% end</code>".
  4241. %%
  4242. %% @see if_expr_clauses/1
  4243. %% @see clause/3
  4244. %% @see case_expr/2
  4245. %% type(Node) = if_expr
  4246. %% data(Node) = Clauses
  4247. %%
  4248. %% Clauses = [syntaxTree()]
  4249. %%
  4250. %% `erl_parse' representation:
  4251. %%
  4252. %% {'if', Pos, Clauses}
  4253. %%
  4254. %% Clauses = [Clause] \ []
  4255. %% Clause = {clause, ...}
  4256. %%
  4257. %% See `clause' for documentation on `erl_parse' clauses.
  4258. if_expr(Clauses) ->
  4259. tree(if_expr, Clauses).
  4260. revert_if_expr(Node) ->
  4261. Pos = get_pos(Node),
  4262. Clauses = [revert_clause(C) || C <- if_expr_clauses(Node)],
  4263. {'if', Pos, Clauses}.
  4264. %% =====================================================================
  4265. %% if_expr_clauses(Node) -> Clauses
  4266. %%
  4267. %% Node = syntaxTree()
  4268. %% Clauses = [syntaxTree()]
  4269. %% type(Node) = if_expr
  4270. %%
  4271. %% @doc Returns the list of clause subtrees of an <code>if_expr</code>
  4272. %% node.
  4273. %%
  4274. %% @see if_expr/1
  4275. if_expr_clauses(Node) ->
  4276. case unwrap(Node) of
  4277. {'if', _, Clauses} ->
  4278. Clauses;
  4279. Node1 ->
  4280. data(Node1)
  4281. end.
  4282. %% =====================================================================
  4283. %% @spec case_expr(Argument::syntaxTree(), Clauses::[syntaxTree()]) ->
  4284. %% syntaxTree()
  4285. %%
  4286. %% @doc Creates an abstract case-expression. If <code>Clauses</code> is
  4287. %% <code>[C1, ..., Cn]</code>, the result represents "<code>case
  4288. %% <em>Argument</em> of <em>C1</em>; ...; <em>Cn</em> end</code>". More
  4289. %% exactly, if each <code>Ci</code> represents "<code>(<em>Pi</em>)
  4290. %% <em>Gi</em> -> <em>Bi</em></code>", then the result represents
  4291. %% "<code>case <em>Argument</em> of <em>P1</em> <em>G1</em> ->
  4292. %% <em>B1</em>; ...; <em>Pn</em> <em>Gn</em> -> <em>Bn</em> end</code>".
  4293. %%
  4294. %% @see case_expr_clauses/1
  4295. %% @see case_expr_argument/1
  4296. %% @see clause/3
  4297. %% @see if_expr/1
  4298. %% @see cond_expr/1
  4299. -record(case_expr, {argument, clauses}).
  4300. %% type(Node) = case_expr
  4301. %% data(Node) = #case_expr{argument :: Argument,
  4302. %% clauses :: Clauses}
  4303. %%
  4304. %% Argument = syntaxTree()
  4305. %% Clauses = [syntaxTree()]
  4306. %%
  4307. %% `erl_parse' representation:
  4308. %%
  4309. %% {'case', Pos, Argument, Clauses}
  4310. %%
  4311. %% Argument = erl_parse()
  4312. %% Clauses = [Clause] \ []
  4313. %% Clause = {clause, ...}
  4314. %%
  4315. %% See `clause' for documentation on `erl_parse' clauses.
  4316. case_expr(Argument, Clauses) ->
  4317. tree(case_expr, #case_expr{argument = Argument,
  4318. clauses = Clauses}).
  4319. revert_case_expr(Node) ->
  4320. Pos = get_pos(Node),
  4321. Argument = case_expr_argument(Node),
  4322. Clauses = [revert_clause(C) || C <- case_expr_clauses(Node)],
  4323. {'case', Pos, Argument, Clauses}.
  4324. %% =====================================================================
  4325. %% @spec case_expr_argument(syntaxTree()) -> syntaxTree()
  4326. %%
  4327. %% @doc Returns the argument subtree of a <code>case_expr</code> node.
  4328. %%
  4329. %% @see case_expr/2
  4330. case_expr_argument(Node) ->
  4331. case unwrap(Node) of
  4332. {'case', _, Argument, _} ->
  4333. Argument;
  4334. Node1 ->
  4335. (data(Node1))#case_expr.argument
  4336. end.
  4337. %% =====================================================================
  4338. %% @spec case_expr_clauses(syntaxTree()) -> [syntaxTree()]
  4339. %%
  4340. %% @doc Returns the list of clause subtrees of a <code>case_expr</code>
  4341. %% node.
  4342. %%
  4343. %% @see case_expr/2
  4344. case_expr_clauses(Node) ->
  4345. case unwrap(Node) of
  4346. {'case', _, _, Clauses} ->
  4347. Clauses;
  4348. Node1 ->
  4349. (data(Node1))#case_expr.clauses
  4350. end.
  4351. %% =====================================================================
  4352. %% @spec cond_expr(Clauses::[syntaxTree()]) -> syntaxTree()
  4353. %%
  4354. %% @doc Creates an abstract cond-expression. If <code>Clauses</code> is
  4355. %% <code>[C1, ..., Cn]</code>, the result represents "<code>cond
  4356. %% <em>C1</em>; ...; <em>Cn</em> end</code>". More exactly, if each
  4357. %% <code>Ci</code> represents "<code>() <em>Ei</em> ->
  4358. %% <em>Bi</em></code>", then the result represents "<code>cond
  4359. %% <em>E1</em> -> <em>B1</em>; ...; <em>En</em> -> <em>Bn</em>
  4360. %% end</code>".
  4361. %%
  4362. %% @see cond_expr_clauses/1
  4363. %% @see clause/3
  4364. %% @see case_expr/2
  4365. %% type(Node) = cond_expr
  4366. %% data(Node) = Clauses
  4367. %%
  4368. %% Clauses = [syntaxTree()]
  4369. %%
  4370. %% `erl_parse' representation:
  4371. %%
  4372. %% {'cond', Pos, Clauses}
  4373. %%
  4374. %% Clauses = [Clause] \ []
  4375. %% Clause = {clause, ...}
  4376. %%
  4377. %% See `clause' for documentation on `erl_parse' clauses.
  4378. cond_expr(Clauses) ->
  4379. tree(cond_expr, Clauses).
  4380. revert_cond_expr(Node) ->
  4381. Pos = get_pos(Node),
  4382. Clauses = [revert_clause(C) || C <- cond_expr_clauses(Node)],
  4383. {'cond', Pos, Clauses}.
  4384. %% =====================================================================
  4385. %% cond_expr_clauses(Node) -> Clauses
  4386. %%
  4387. %% Node = syntaxTree()
  4388. %% Clauses = [syntaxTree()]
  4389. %% type(Node) = cond_expr
  4390. %%
  4391. %% @doc Returns the list of clause subtrees of a <code>cond_expr</code>
  4392. %% node.
  4393. %%
  4394. %% @see cond_expr/1
  4395. cond_expr_clauses(Node) ->
  4396. case unwrap(Node) of
  4397. {'cond', _, Clauses} ->
  4398. Clauses;
  4399. Node1 ->
  4400. data(Node1)
  4401. end.
  4402. %% =====================================================================
  4403. %% @spec receive_expr(Clauses) -> syntaxTree()
  4404. %% @equiv receive_expr(Clauses, none, [])
  4405. receive_expr(Clauses) ->
  4406. receive_expr(Clauses, none, []).
  4407. %% =====================================================================
  4408. %% @spec receive_expr(Clauses::[syntaxTree()], Timeout,
  4409. %% Action::[syntaxTree()]) -> syntaxTree()
  4410. %% Timeout = none | syntaxTree()
  4411. %%
  4412. %% @doc Creates an abstract receive-expression. If <code>Timeout</code>
  4413. %% is <code>none</code>, the result represents "<code>receive
  4414. %% <em>C1</em>; ...; <em>Cn</em> end</code>" (the <code>Action</code>
  4415. %% argument is ignored). Otherwise, if <code>Clauses</code> is
  4416. %% <code>[C1, ..., Cn]</code> and <code>Action</code> is <code>[A1, ...,
  4417. %% Am]</code>, the result represents "<code>receive <em>C1</em>; ...;
  4418. %% <em>Cn</em> after <em>Timeout</em> -> <em>A1</em>, ..., <em>Am</em>
  4419. %% end</code>". More exactly, if each <code>Ci</code> represents
  4420. %% "<code>(<em>Pi</em>) <em>Gi</em> -> <em>Bi</em></code>", then the
  4421. %% result represents "<code>receive <em>P1</em> <em>G1</em> ->
  4422. %% <em>B1</em>; ...; <em>Pn</em> <em>Gn</em> -> <em>Bn</em> ...
  4423. %% end</code>".
  4424. %%
  4425. %% <p>Note that in Erlang, a receive-expression must have at least one
  4426. %% clause if no timeout part is specified.</p>
  4427. %%
  4428. %% @see receive_expr_clauses/1
  4429. %% @see receive_expr_timeout/1
  4430. %% @see receive_expr_action/1
  4431. %% @see receive_expr/1
  4432. %% @see clause/3
  4433. %% @see case_expr/2
  4434. -record(receive_expr, {clauses, timeout, action}).
  4435. %% type(Node) = receive_expr
  4436. %% data(Node) = #receive_expr{clauses :: Clauses,
  4437. %% timeout :: Timeout,
  4438. %% action :: Action}
  4439. %%
  4440. %% Clauses = [syntaxTree()]
  4441. %% Timeout = none | syntaxTree()
  4442. %% Action = [syntaxTree()]
  4443. %%
  4444. %% `erl_parse' representation:
  4445. %%
  4446. %% {'receive', Pos, Clauses}
  4447. %% {'receive', Pos, Clauses, Timeout, Action}
  4448. %%
  4449. %% Clauses = [Clause] \ []
  4450. %% Clause = {clause, ...}
  4451. %% Timeout = erl_parse()
  4452. %% Action = [erl_parse()] \ []
  4453. %%
  4454. %% See `clause' for documentation on `erl_parse' clauses.
  4455. receive_expr(Clauses, Timeout, Action) ->
  4456. %% If `Timeout' is `none', we always replace the actual
  4457. %% `Action' argument with an empty list, since
  4458. %% `receive_expr_action' should in that case return the empty
  4459. %% list regardless.
  4460. Action1 = case Timeout of
  4461. none -> [];
  4462. _ -> Action
  4463. end,
  4464. tree(receive_expr, #receive_expr{clauses = Clauses,
  4465. timeout = Timeout,
  4466. action = Action1}).
  4467. revert_receive_expr(Node) ->
  4468. Pos = get_pos(Node),
  4469. Clauses = [revert_clause(C) || C <- receive_expr_clauses(Node)],
  4470. Timeout = receive_expr_timeout(Node),
  4471. Action = receive_expr_action(Node),
  4472. case Timeout of
  4473. none ->
  4474. {'receive', Pos, Clauses};
  4475. _ ->
  4476. {'receive', Pos, Clauses, Timeout, Action}
  4477. end.
  4478. %% =====================================================================
  4479. %% @spec receive_expr_clauses(syntaxTree()) -> [syntaxTree()]
  4480. %% type(Node) = receive_expr
  4481. %%
  4482. %% @doc Returns the list of clause subtrees of a
  4483. %% <code>receive_expr</code> node.
  4484. %%
  4485. %% @see receive_expr/3
  4486. receive_expr_clauses(Node) ->
  4487. case unwrap(Node) of
  4488. {'receive', _, Clauses} ->
  4489. Clauses;
  4490. {'receive', _, Clauses, _, _} ->
  4491. Clauses;
  4492. Node1 ->
  4493. (data(Node1))#receive_expr.clauses
  4494. end.
  4495. %% =====================================================================
  4496. %% @spec receive_expr_timeout(Node::syntaxTree()) -> Timeout
  4497. %% Timeout = none | syntaxTree()
  4498. %%
  4499. %% @doc Returns the timeout subtree of a <code>receive_expr</code> node,
  4500. %% if any. If <code>Node</code> represents "<code>receive <em>C1</em>;
  4501. %% ...; <em>Cn</em> end</code>", <code>none</code> is returned.
  4502. %% Otherwise, if <code>Node</code> represents "<code>receive
  4503. %% <em>C1</em>; ...; <em>Cn</em> after <em>Timeout</em> -> <em>A1</em>,
  4504. %% ..., <em>Am</em> end</code>", <code>[A1, ..., Am]</code> is returned.
  4505. %%
  4506. %% @see receive_expr/3
  4507. receive_expr_timeout(Node) ->
  4508. case unwrap(Node) of
  4509. {'receive', _, _} ->
  4510. none;
  4511. {'receive', _, _, Timeout, _} ->
  4512. Timeout;
  4513. Node1 ->
  4514. (data(Node1))#receive_expr.timeout
  4515. end.
  4516. %% =====================================================================
  4517. %% @spec receive_expr_action(Node::syntaxTree()) -> [syntaxTree()]
  4518. %%
  4519. %% @doc Returns the list of action body subtrees of a
  4520. %% <code>receive_expr</code> node. If <code>Node</code> represents
  4521. %% "<code>receive <em>C1</em>; ...; <em>Cn</em> end</code>", this is the
  4522. %% empty list.
  4523. %%
  4524. %% @see receive_expr/3
  4525. receive_expr_action(Node) ->
  4526. case unwrap(Node) of
  4527. {'receive', _, _} ->
  4528. [];
  4529. {'receive', _, _, _, Action} ->
  4530. Action;
  4531. Node1 ->
  4532. (data(Node1))#receive_expr.action
  4533. end.
  4534. %% =====================================================================
  4535. %% @spec try_expr(Body::syntaxTree(), Handlers::[syntaxTree()]) ->
  4536. %% syntaxTree()
  4537. %% @equiv try_expr(Body, [], Handlers)
  4538. try_expr(Body, Handlers) ->
  4539. try_expr(Body, [], Handlers).
  4540. %% =====================================================================
  4541. %% @spec try_expr(Body::syntaxTree(), Clauses::[syntaxTree()],
  4542. %% Handlers::[syntaxTree()]) -> syntaxTree()
  4543. %% @equiv try_expr(Body, Clauses, Handlers, [])
  4544. try_expr(Body, Clauses, Handlers) ->
  4545. try_expr(Body, Clauses, Handlers, []).
  4546. %% =====================================================================
  4547. %% @spec try_after_expr(Body::syntaxTree(), After::[syntaxTree()]) ->
  4548. %% syntaxTree()
  4549. %% @equiv try_expr(Body, [], [], After)
  4550. try_after_expr(Body, After) ->
  4551. try_expr(Body, [], [], After).
  4552. %% =====================================================================
  4553. %% @spec try_expr(Body::[syntaxTree()], Clauses::[syntaxTree()],
  4554. %% Handlers::[syntaxTree()], After::[syntaxTree()]) ->
  4555. %% syntaxTree()
  4556. %%
  4557. %% @doc Creates an abstract try-expression. If <code>Body</code> is
  4558. %% <code>[B1, ..., Bn]</code>, <code>Clauses</code> is <code>[C1, ...,
  4559. %% Cj]</code>, <code>Handlers</code> is <code>[H1, ..., Hk]</code>, and
  4560. %% <code>After</code> is <code>[A1, ..., Am]</code>, the result
  4561. %% represents "<code>try <em>B1</em>, ..., <em>Bn</em> of <em>C1</em>;
  4562. %% ...; <em>Cj</em> catch <em>H1</em>; ...; <em>Hk</em> after
  4563. %% <em>A1</em>, ..., <em>Am</em> end</code>". More exactly, if each
  4564. %% <code>Ci</code> represents "<code>(<em>CPi</em>) <em>CGi</em> ->
  4565. %% <em>CBi</em></code>", and each <code>Hi</code> represents
  4566. %% "<code>(<em>HPi</em>) <em>HGi</em> -> <em>HBi</em></code>", then the
  4567. %% result represents "<code>try <em>B1</em>, ..., <em>Bn</em> of
  4568. %% <em>CP1</em> <em>CG1</em> -> <em>CB1</em>; ...; <em>CPj</em>
  4569. %% <em>CGj</em> -> <em>CBj</em> catch <em>HP1</em> <em>HG1</em> ->
  4570. %% <em>HB1</em>; ...; <em>HPk</em> <em>HGk</em> -> <em>HBk</em> after
  4571. %% <em>A1</em>, ..., <em>Am</em> end</code>"; cf.
  4572. %% <code>case_expr/2</code>. If <code>Clauses</code> is the empty list,
  4573. %% the <code>of ...</code> section is left out. If <code>After</code> is
  4574. %% the empty list, the <code>after ...</code> section is left out. If
  4575. %% <code>Handlers</code> is the empty list, and <code>After</code> is
  4576. %% nonempty, the <code>catch ...</code> section is left out.
  4577. %%
  4578. %% @see try_expr_body/1
  4579. %% @see try_expr_clauses/1
  4580. %% @see try_expr_handlers/1
  4581. %% @see try_expr_after/1
  4582. %% @see try_expr/2
  4583. %% @see try_expr/3
  4584. %% @see try_after_expr/2
  4585. %% @see clause/3
  4586. %% @see class_qualifier/2
  4587. %% @see case_expr/2
  4588. -record(try_expr, {body, clauses, handlers, 'after'}).
  4589. %% type(Node) = try_expr
  4590. %% data(Node) = #try_expr{body :: Body,
  4591. %% clauses :: Clauses,
  4592. %% handlers :: Clauses,
  4593. %% after :: Body}
  4594. %%
  4595. %% Body = syntaxTree()
  4596. %% Clauses = [syntaxTree()]
  4597. %%
  4598. %% `erl_parse' representation:
  4599. %%
  4600. %% {'try', Pos, Body, Clauses, Handlers, After}
  4601. %%
  4602. %% Body = [erl_parse()]
  4603. %% Clauses = [Clause]
  4604. %% Handlers = [Clause] \ []
  4605. %% Clause = {clause, ...}
  4606. %% After = [erl_parse()]
  4607. %%
  4608. %% See `clause' for documentation on `erl_parse' clauses.
  4609. try_expr(Body, Clauses, Handlers, After) ->
  4610. tree(try_expr, #try_expr{body = Body,
  4611. clauses = Clauses,
  4612. handlers = Handlers,
  4613. 'after' = After}).
  4614. revert_try_expr(Node) ->
  4615. Pos = get_pos(Node),
  4616. Body = try_expr_body(Node),
  4617. Clauses = [revert_clause(C) || C <- try_expr_clauses(Node)],
  4618. Handlers = [revert_try_clause(C) || C <- try_expr_handlers(Node)],
  4619. After = try_expr_after(Node),
  4620. {'try', Pos, Body, Clauses, Handlers, After}.
  4621. %% =====================================================================
  4622. %% @spec try_expr_body(syntaxTree()) -> [syntaxTree()]
  4623. %%
  4624. %% @doc Returns the list of body subtrees of a <code>try_expr</code>
  4625. %% node.
  4626. %%
  4627. %% @see try_expr/4
  4628. try_expr_body(Node) ->
  4629. case unwrap(Node) of
  4630. {'try', _, Body, _, _, _} ->
  4631. Body;
  4632. Node1 ->
  4633. (data(Node1))#try_expr.body
  4634. end.
  4635. %% =====================================================================
  4636. %% @spec try_expr_clauses(Node::syntaxTree()) -> [syntaxTree()]
  4637. %%
  4638. %% @doc Returns the list of case-clause subtrees of a
  4639. %% <code>try_expr</code> node. If <code>Node</code> represents
  4640. %% "<code>try <em>Body</em> catch <em>H1</em>; ...; <em>Hn</em>
  4641. %% end</code>", the result is the empty list.
  4642. %%
  4643. %% @see try_expr/4
  4644. try_expr_clauses(Node) ->
  4645. case unwrap(Node) of
  4646. {'try', _, _, Clauses, _, _} ->
  4647. Clauses;
  4648. Node1 ->
  4649. (data(Node1))#try_expr.clauses
  4650. end.
  4651. %% =====================================================================
  4652. %% @spec try_expr_handlers(syntaxTree()) -> [syntaxTree()]
  4653. %%
  4654. %% @doc Returns the list of handler-clause subtrees of a
  4655. %% <code>try_expr</code> node.
  4656. %%
  4657. %% @see try_expr/4
  4658. try_expr_handlers(Node) ->
  4659. case unwrap(Node) of
  4660. {'try', _, _, _, Handlers, _} ->
  4661. unfold_try_clauses(Handlers);
  4662. Node1 ->
  4663. (data(Node1))#try_expr.handlers
  4664. end.
  4665. %% =====================================================================
  4666. %% @spec try_expr_after(syntaxTree()) -> [syntaxTree()]
  4667. %%
  4668. %% @doc Returns the list of "after" subtrees of a <code>try_expr</code>
  4669. %% node.
  4670. %%
  4671. %% @see try_expr/4
  4672. try_expr_after(Node) ->
  4673. case unwrap(Node) of
  4674. {'try', _, _, _, _, After} ->
  4675. After;
  4676. Node1 ->
  4677. (data(Node1))#try_expr.'after'
  4678. end.
  4679. %% =====================================================================
  4680. %% @spec class_qualifier(Class::syntaxTree(), Body::syntaxTree()) ->
  4681. %% syntaxTree()
  4682. %%
  4683. %% @doc Creates an abstract class qualifier. The result represents
  4684. %% "<code><em>Class</em>:<em>Body</em></code>".
  4685. %%
  4686. %% @see class_qualifier_argument/1
  4687. %% @see class_qualifier_body/1
  4688. %% @see try_expr/4
  4689. -record(class_qualifier, {class, body}).
  4690. %% type(Node) = class_qualifier
  4691. %% data(Node) = #class_qualifier{class :: Class, body :: Body}
  4692. %%
  4693. %% Class = Body = syntaxTree()
  4694. class_qualifier(Class, Body) ->
  4695. tree(class_qualifier,
  4696. #class_qualifier{class = Class, body = Body}).
  4697. %% =====================================================================
  4698. %% @spec class_qualifier_argument(syntaxTree()) -> syntaxTree()
  4699. %%
  4700. %% @doc Returns the argument (the class) subtree of a
  4701. %% <code>class_qualifier</code> node.
  4702. %%
  4703. %% @see class_qualifier/1
  4704. class_qualifier_argument(Node) ->
  4705. (data(Node))#class_qualifier.class.
  4706. %% =====================================================================
  4707. %% @spec class_qualifier_body(syntaxTree()) -> syntaxTree()
  4708. %%
  4709. %% @doc Returns the body subtree of a <code>class_qualifier</code> node.
  4710. %%
  4711. %% @see class_qualifier/1
  4712. class_qualifier_body(Node) ->
  4713. (data(Node))#class_qualifier.body.
  4714. %% =====================================================================
  4715. %% @spec implicit_fun(Name::syntaxTree(), Arity::syntaxTree()) ->
  4716. %% syntaxTree()
  4717. %%
  4718. %% @doc Creates an abstract "implicit fun" expression. (Utility
  4719. %% function.) If <code>Arity</code> is <code>none</code>, this is
  4720. %% equivalent to <code>implicit_fun(Name)</code>, otherwise it is
  4721. %% equivalent to <code>implicit_fun(arity_qualifier(Name,
  4722. %% Arity))</code>.
  4723. %%
  4724. %% @see implicit_fun/1
  4725. implicit_fun(Name, none) ->
  4726. implicit_fun(Name);
  4727. implicit_fun(Name, Arity) ->
  4728. implicit_fun(arity_qualifier(Name, Arity)).
  4729. %% =====================================================================
  4730. %% @spec implicit_fun(Name::syntaxTree()) -> syntaxTree()
  4731. %%
  4732. %% @doc Creates an abstract "implicit fun" expression. The result
  4733. %% represents "<code>fun <em>Name</em></code>".
  4734. %%
  4735. %% @see implicit_fun_name/1
  4736. %% @see implicit_fun/2
  4737. %% type(Node) = implicit_fun
  4738. %% data(Node) = syntaxTree()
  4739. %%
  4740. %% `erl_parse' representation:
  4741. %%
  4742. %% {'fun', Pos, {function, Name, Arity}}
  4743. %%
  4744. %% Name = atom()
  4745. %% Arity = integer()
  4746. implicit_fun(Name) ->
  4747. tree(implicit_fun, Name).
  4748. revert_implicit_fun(Node) ->
  4749. Pos = get_pos(Node),
  4750. Name = implicit_fun_name(Node),
  4751. case type(Name) of
  4752. arity_qualifier ->
  4753. F = arity_qualifier_body(Name),
  4754. A = arity_qualifier_argument(Name),
  4755. case {type(F), type(A)} of
  4756. {atom, integer} ->
  4757. {'fun', Pos,
  4758. {function, concrete(F), concrete(A)}};
  4759. _ ->
  4760. Node
  4761. end;
  4762. _ ->
  4763. Node
  4764. end.
  4765. %% =====================================================================
  4766. %% @spec implicit_fun_name(Node::syntaxTree()) -> syntaxTree()
  4767. %%
  4768. %% @doc Returns the name subtree of an <code>implicit_fun</code> node.
  4769. %%
  4770. %% <p>Note: if <code>Node</code> represents "<code>fun
  4771. %% <em>N</em>/<em>A</em></code>", then the result is the subtree
  4772. %% representing "<code><em>N</em>/<em>A</em></code>".</p>
  4773. %%
  4774. %% @see implicit_fun/1
  4775. implicit_fun_name(Node) ->
  4776. case unwrap(Node) of
  4777. {'fun', Pos, {function, Atom, Arity}} ->
  4778. arity_qualifier(set_pos(atom(Atom), Pos),
  4779. set_pos(integer(Arity), Pos));
  4780. Node1 ->
  4781. data(Node1)
  4782. end.
  4783. %% =====================================================================
  4784. %% @spec fun_expr(Clauses::[syntaxTree()]) -> syntaxTree()
  4785. %%
  4786. %% @doc Creates an abstract fun-expression. If <code>Clauses</code> is
  4787. %% <code>[C1, ..., Cn]</code>, the result represents "<code>fun
  4788. %% <em>C1</em>; ...; <em>Cn</em> end</code>". More exactly, if each
  4789. %% <code>Ci</code> represents "<code>(<em>Pi1</em>, ..., <em>Pim</em>)
  4790. %% <em>Gi</em> -> <em>Bi</em></code>", then the result represents
  4791. %% "<code>fun (<em>P11</em>, ..., <em>P1m</em>) <em>G1</em> ->
  4792. %% <em>B1</em>; ...; (<em>Pn1</em>, ..., <em>Pnm</em>) <em>Gn</em> ->
  4793. %% <em>Bn</em> end</code>".
  4794. %%
  4795. %% @see fun_expr_clauses/1
  4796. %% @see fun_expr_arity/1
  4797. %% type(Node) = fun_expr
  4798. %% data(Node) = Clauses
  4799. %%
  4800. %% Clauses = [syntaxTree()]
  4801. %%
  4802. %% (See `function' for notes; e.g. why the arity is not stored.)
  4803. %%
  4804. %% `erl_parse' representation:
  4805. %%
  4806. %% {'fun', Pos, {clauses, Clauses}}
  4807. %%
  4808. %% Clauses = [Clause] \ []
  4809. %% Clause = {clause, ...}
  4810. %%
  4811. %% See `clause' for documentation on `erl_parse' clauses.
  4812. fun_expr(Clauses) ->
  4813. tree(fun_expr, Clauses).
  4814. revert_fun_expr(Node) ->
  4815. Clauses = [revert_clause(C) || C <- fun_expr_clauses(Node)],
  4816. Pos = get_pos(Node),
  4817. {'fun', Pos, {clauses, Clauses}}.
  4818. %% =====================================================================
  4819. %% @spec fun_expr_clauses(syntaxTree()) -> [syntaxTree()]
  4820. %%
  4821. %% @doc Returns the list of clause subtrees of a <code>fun_expr</code>
  4822. %% node.
  4823. %%
  4824. %% @see fun_expr/1
  4825. fun_expr_clauses(Node) ->
  4826. case unwrap(Node) of
  4827. {'fun', _, {clauses, Clauses}} ->
  4828. Clauses;
  4829. Node1 ->
  4830. data(Node1)
  4831. end.
  4832. %% =====================================================================
  4833. %% @spec fun_expr_arity(syntaxTree()) -> integer()
  4834. %%
  4835. %% @doc Returns the arity of a <code>fun_expr</code> node. The result is
  4836. %% the number of parameter patterns in the first clause of the
  4837. %% fun-expression; subsequent clauses are ignored.
  4838. %%
  4839. %% <p>An exception is thrown if <code>fun_expr_clauses(Node)</code>
  4840. %% returns an empty list, or if the first element of that list is not a
  4841. %% syntax tree <code>C</code> of type <code>clause</code> such that
  4842. %% <code>clause_patterns(C)</code> is a nonempty list.</p>
  4843. %%
  4844. %% @see fun_expr/1
  4845. %% @see fun_expr_clauses/1
  4846. %% @see clause/3
  4847. %% @see clause_patterns/1
  4848. fun_expr_arity(Node) ->
  4849. length(clause_patterns(hd(fun_expr_clauses(Node)))).
  4850. %% =====================================================================
  4851. %% @spec parentheses(Body::syntaxTree()) -> syntaxTree()
  4852. %%
  4853. %% @doc Creates an abstract parenthesised expression. The result
  4854. %% represents "<code>(<em>Body</em>)</code>", independently of the
  4855. %% context.
  4856. %%
  4857. %% @see parentheses_body/1
  4858. %% type(Node) = parentheses
  4859. %% data(Node) = syntaxTree()
  4860. parentheses(Expr) ->
  4861. tree(parentheses, Expr).
  4862. revert_parentheses(Node) ->
  4863. parentheses_body(Node).
  4864. %% =====================================================================
  4865. %% @spec parentheses_body(syntaxTree()) -> syntaxTree()
  4866. %%
  4867. %% @doc Returns the body subtree of a <code>parentheses</code> node.
  4868. %%
  4869. %% @see parentheses/1
  4870. parentheses_body(Node) ->
  4871. data(Node).
  4872. %% =====================================================================
  4873. %% @spec macro(Name) -> syntaxTree()
  4874. %% @equiv macro(Name, none)
  4875. macro(Name) ->
  4876. macro(Name, none).
  4877. %% =====================================================================
  4878. %% @spec macro(Name::syntaxTree(), Arguments) -> syntaxTree()
  4879. %% Arguments = none | [syntaxTree()]
  4880. %%
  4881. %% @doc Creates an abstract macro application. If <code>Arguments</code>
  4882. %% is <code>none</code>, the result represents
  4883. %% "<code>?<em>Name</em></code>", otherwise, if <code>Arguments</code>
  4884. %% is <code>[A1, ..., An]</code>, the result represents
  4885. %% "<code>?<em>Name</em>(<em>A1</em>, ..., <em>An</em>)</code>".
  4886. %%
  4887. %% <p>Notes: if <code>Arguments</code> is the empty list, the result
  4888. %% will thus represent "<code>?<em>Name</em>()</code>", including a pair
  4889. %% of matching parentheses.</p>
  4890. %%
  4891. %% <p>The only syntactical limitation imposed by the preprocessor on the
  4892. %% arguments to a macro application (viewed as sequences of tokens) is
  4893. %% that they must be balanced with respect to parentheses, brackets,
  4894. %% <code>begin ... end</code>, <code>case ... end</code>, etc. The
  4895. %% <code>text</code> node type can be used to represent arguments which
  4896. %% are not regular Erlang constructs.</p>
  4897. %%
  4898. %% @see macro_name/1
  4899. %% @see macro_arguments/1
  4900. %% @see macro/1
  4901. %% @see text/1
  4902. -record(macro, {name, arguments}).
  4903. %% type(Node) = macro
  4904. %% data(Node) = #macro{name :: Name, arguments :: Arguments}
  4905. %%
  4906. %% Name = syntaxTree()
  4907. %% Arguments = none | [syntaxTree()]
  4908. macro(Name, Arguments) ->
  4909. tree(macro, #macro{name = Name, arguments = Arguments}).
  4910. %% =====================================================================
  4911. %% @spec macro_name(syntaxTree()) -> syntaxTree()
  4912. %%
  4913. %% @doc Returns the name subtree of a <code>macro</code> node.
  4914. %%
  4915. %% @see macro/2
  4916. macro_name(Node) ->
  4917. (data(Node))#macro.name.
  4918. %% =====================================================================
  4919. %% @spec macro_arguments(Node::syntaxTree()) -> none | [syntaxTree()]
  4920. %%
  4921. %% @doc Returns the list of argument subtrees of a <code>macro</code>
  4922. %% node, if any. If <code>Node</code> represents
  4923. %% "<code>?<em>Name</em></code>", <code>none</code> is returned.
  4924. %% Otherwise, if <code>Node</code> represents
  4925. %% "<code>?<em>Name</em>(<em>A1</em>, ..., <em>An</em>)</code>",
  4926. %% <code>[A1, ..., An]</code> is returned.
  4927. %%
  4928. %% @see macro/2
  4929. macro_arguments(Node) ->
  4930. (data(Node))#macro.arguments.
  4931. %% =====================================================================
  4932. %% @spec abstract(Term::term()) -> syntaxTree()
  4933. %%
  4934. %% @doc Returns the syntax tree corresponding to an Erlang term.
  4935. %% <code>Term</code> must be a literal term, i.e., one that can be
  4936. %% represented as a source code literal. Thus, it may not contain a
  4937. %% process identifier, port, reference, binary or function value as a
  4938. %% subterm. The function recognises printable strings, in order to get a
  4939. %% compact and readable representation. Evaluation fails with reason
  4940. %% <code>badarg</code> if <code>Term</code> is not a literal term.
  4941. %%
  4942. %% @see concrete/1
  4943. %% @see is_literal/1
  4944. abstract([H | T]) when integer(H) ->
  4945. case is_printable([H | T]) of
  4946. true ->
  4947. string([H | T]);
  4948. false ->
  4949. abstract_tail(H, T)
  4950. end;
  4951. abstract([H | T]) ->
  4952. abstract_tail(H, T);
  4953. abstract(T) when atom(T) ->
  4954. atom(T);
  4955. abstract(T) when integer(T) ->
  4956. integer(T);
  4957. abstract(T) when float(T) ->
  4958. make_float(T); % (not `float', which would call the BIF)
  4959. abstract([]) ->
  4960. nil();
  4961. abstract(T) when tuple(T) ->
  4962. tuple(abstract_list(tuple_to_list(T)));
  4963. abstract(T) when binary(T) ->
  4964. binary([binary_field(integer(B)) || B <- binary_to_list(T)]);
  4965. abstract(T) ->
  4966. erlang:fault({badarg, T}).
  4967. abstract_list([T | Ts]) ->
  4968. [abstract(T) | abstract_list(Ts)];
  4969. abstract_list([]) ->
  4970. [].
  4971. %% This is entered when we might have a sequence of conses that might or
  4972. %% might not be a proper list, but which should not be considered as a
  4973. %% potential string, to avoid unnecessary checking. This also avoids
  4974. %% that a list like `[4711, 42, 10]' could be abstracted to represent
  4975. %% `[4711 | "*\n"]'.
  4976. abstract_tail(H1, [H2 | T]) ->
  4977. %% Recall that `cons' does "intelligent" composition
  4978. cons(abstract(H1), abstract_tail(H2, T));
  4979. abstract_tail(H, T) ->
  4980. cons(abstract(H), abstract(T)).
  4981. %% =====================================================================
  4982. %% @spec concrete(Node::syntaxTree()) -> term()
  4983. %%
  4984. %% @doc Returns the Erlang term represented by a syntax tree. Evaluation
  4985. %% fails with reason <code>badarg</code> if <code>Node</code> does not
  4986. %% represent a literal term.
  4987. %%
  4988. %% <p>Note: Currently, the set of syntax trees which have a concrete
  4989. %% representation is larger than the set of trees which can be built
  4990. %% using the function <code>abstract/1</code>. An abstract character
  4991. %% will be concretised as an integer, while <code>abstract/1</code> does
  4992. %% not at present yield an abstract character for any input. (Use the
  4993. %% <code>char/1</code> function to explicitly create an abstract
  4994. %% character.)</p>
  4995. %%
  4996. %% @see abstract/1
  4997. %% @see is_literal/1
  4998. %% @see char/1
  4999. concrete(Node) ->
  5000. case type(Node) of
  5001. atom ->
  5002. atom_value(Node);
  5003. integer ->
  5004. integer_value(Node);
  5005. float ->
  5006. float_value(Node);
  5007. char ->
  5008. char_value(Node);
  5009. string ->
  5010. string_value(Node);
  5011. nil ->
  5012. [];
  5013. list ->
  5014. [concrete(list_head(Node))
  5015. | concrete(list_tail(Node))];
  5016. tuple ->
  5017. list_to_tuple(concrete_list(tuple_elements(Node)));
  5018. binary ->
  5019. Fs = [revert_binary_field(
  5020. binary_field(binary_field_body(F),
  5021. case binary_field_size(F) of
  5022. none -> none;
  5023. S ->
  5024. revert(S)
  5025. end,
  5026. binary_field_types(F)))
  5027. || F <- binary_fields(Node)],
  5028. {value, B, _} =
  5029. eval_bits:expr_grp(Fs, [],
  5030. fun(F, _) ->
  5031. {value, concrete(F), []}
  5032. end, [], true),
  5033. B;
  5034. _ ->
  5035. erlang:fault({badarg, Node})
  5036. end.
  5037. concrete_list([E | Es]) ->
  5038. [concrete(E) | concrete_list(Es)];
  5039. concrete_list([]) ->
  5040. [].
  5041. %% =====================================================================
  5042. %% @spec is_literal(Node::syntaxTree()) -> bool()
  5043. %%
  5044. %% @doc Returns <code>true</code> if <code>Node</code> represents a
  5045. %% literal term, otherwise <code>false</code>. This function returns
  5046. %% <code>true</code> if and only if the value of
  5047. %% <code>concrete(Node)</code> is defined.
  5048. %%
  5049. %% @see abstract/1
  5050. %% @see concrete/1
  5051. is_literal(T) ->
  5052. case type(T) of
  5053. atom ->
  5054. true;
  5055. integer ->
  5056. true;
  5057. float ->
  5058. true;
  5059. char->
  5060. true;
  5061. string ->
  5062. true;
  5063. nil ->
  5064. true;
  5065. list ->
  5066. case is_literal(list_head(T)) of
  5067. true ->
  5068. is_literal(list_tail(T));
  5069. false ->
  5070. false
  5071. end;
  5072. tuple ->
  5073. lists:all(fun is_literal/1, tuple_elements(T));
  5074. _ ->
  5075. false
  5076. end.
  5077. %% =====================================================================
  5078. %% @spec revert(Tree::syntaxTree()) -> syntaxTree()
  5079. %%
  5080. %% @doc Returns an <code>erl_parse</code>-compatible representation of a
  5081. %% syntax tree, if possible. If <code>Tree</code> represents a
  5082. %% well-formed Erlang program or expression, the conversion should work
  5083. %% without problems. Typically, <code>is_tree/1</code> yields
  5084. %% <code>true</code> if conversion failed (i.e., the result is still an
  5085. %% abstract syntax tree), and <code>false</code> otherwise.
  5086. %%
  5087. %% <p>The <code>is_tree/1</code> test is not completely foolproof. For a
  5088. %% few special node types (e.g. <code>arity_qualifier</code>), if such a
  5089. %% node occurs in a context where it is not expected, it will be left
  5090. %% unchanged as a non-reverted subtree of the result. This can only
  5091. %% happen if <code>Tree</code> does not actually represent legal Erlang
  5092. %% code.</p>
  5093. %%
  5094. %% @see revert_forms/1
  5095. %% @see erl_parse
  5096. revert(Node) ->
  5097. case is_tree(Node) of
  5098. false ->
  5099. %% Just remove any wrapper. `erl_parse' nodes never contain
  5100. %% abstract syntax tree nodes as subtrees.
  5101. unwrap(Node);
  5102. true ->
  5103. case is_leaf(Node) of
  5104. true ->
  5105. revert_root(Node);
  5106. false ->
  5107. %% First revert the subtrees, where possible.
  5108. %% (Sometimes, subtrees cannot be reverted out of
  5109. %% context, and the real work will be done when the
  5110. %% parent node is reverted.)
  5111. Gs = [[revert(X) || X <- L] || L <- subtrees(Node)],
  5112. %% Then reconstruct the node from the reverted
  5113. %% parts, and revert the node itself.
  5114. Node1 = update_tree(Node, Gs),
  5115. revert_root(Node1)
  5116. end
  5117. end.
  5118. %% Note: The concept of "compatible root node" is not strictly defined.
  5119. %% At a minimum, if `make_tree' is used to compose a node `T' from
  5120. %% subtrees that are all completely backwards compatible, then the
  5121. %% result of `revert_root(T)' should also be completely backwards
  5122. %% compatible.
  5123. revert_root(Node) ->
  5124. case type(Node) of
  5125. application ->
  5126. revert_application(Node);
  5127. atom ->
  5128. revert_atom(Node);
  5129. attribute ->
  5130. revert_attribute(Node);
  5131. binary ->
  5132. revert_binary(Node);
  5133. binary_field ->
  5134. revert_binary_field(Node);
  5135. block_expr ->
  5136. revert_block_expr(Node);
  5137. case_expr ->
  5138. revert_case_expr(Node);
  5139. catch_expr ->
  5140. revert_catch_expr(Node);
  5141. char ->
  5142. revert_char(Node);
  5143. clause ->
  5144. revert_clause(Node);
  5145. cond_expr ->
  5146. revert_cond_expr(Node);
  5147. eof_marker ->
  5148. revert_eof_marker(Node);
  5149. error_marker ->
  5150. revert_error_marker(Node);
  5151. float ->
  5152. revert_float(Node);
  5153. fun_expr ->
  5154. revert_fun_expr(Node);
  5155. function ->
  5156. revert_function(Node);
  5157. generator ->
  5158. revert_generator(Node);
  5159. if_expr ->
  5160. revert_if_expr(Node);
  5161. implicit_fun ->
  5162. revert_implicit_fun(Node);
  5163. infix_expr ->
  5164. revert_infix_expr(Node);
  5165. integer ->
  5166. revert_integer(Node);
  5167. list ->
  5168. revert_list(Node);
  5169. list_comp ->
  5170. revert_list_comp(Node);
  5171. match_expr ->
  5172. revert_match_expr(Node);
  5173. module_qualifier ->
  5174. revert_module_qualifier(Node);
  5175. nil ->
  5176. revert_nil(Node);
  5177. parentheses ->
  5178. revert_parentheses(Node);
  5179. prefix_expr ->
  5180. revert_prefix_expr(Node);
  5181. qualified_name ->
  5182. revert_qualified_name(Node);
  5183. query_expr ->
  5184. revert_query_expr(Node);
  5185. receive_expr ->
  5186. revert_receive_expr(Node);
  5187. record_access ->
  5188. revert_record_access(Node);
  5189. record_expr ->
  5190. revert_record_expr(Node);
  5191. record_index_expr ->
  5192. revert_record_index_expr(Node);
  5193. rule ->
  5194. revert_rule(Node);
  5195. string ->
  5196. revert_string(Node);
  5197. try_expr ->
  5198. revert_try_expr(Node);
  5199. tuple ->
  5200. revert_tuple(Node);
  5201. underscore ->
  5202. revert_underscore(Node);
  5203. variable ->
  5204. revert_variable(Node);
  5205. warning_marker ->
  5206. revert_warning_marker(Node);
  5207. _ ->
  5208. %% Non-revertible new-form node
  5209. Node
  5210. end.
  5211. %% =====================================================================
  5212. %% @spec revert_forms(Forms) -> [erl_parse()]
  5213. %%
  5214. %% Forms = syntaxTree() | [syntaxTree()]
  5215. %%
  5216. %% @doc Reverts a sequence of Erlang source code forms. The sequence can
  5217. %% be given either as a <code>form_list</code> syntax tree (possibly
  5218. %% nested), or as a list of "program form" syntax trees. If successful,
  5219. %% the corresponding flat list of <code>erl_parse</code>-compatible
  5220. %% syntax trees is returned (cf. <code>revert/1</code>). If some program
  5221. %% form could not be reverted, <code>{error, Form}</code> is thrown.
  5222. %% Standalone comments in the form sequence are discarded.
  5223. %%
  5224. %% @see revert/1
  5225. %% @see form_list/1
  5226. %% @see is_form/1
  5227. revert_forms(L) when list(L) ->
  5228. revert_forms(form_list(L));
  5229. revert_forms(T) ->
  5230. case type(T) of
  5231. form_list ->
  5232. T1 = flatten_form_list(T),
  5233. case catch {ok, revert_forms_1(form_list_elements(T1))} of
  5234. {ok, Fs} ->
  5235. Fs;
  5236. {error, R} ->
  5237. erlang:fault({error, R});
  5238. {'EXIT', R} ->
  5239. exit(R);
  5240. R ->
  5241. throw(R)
  5242. end;
  5243. _ ->
  5244. erlang:fault({badarg, T})
  5245. end.
  5246. revert_forms_1([T | Ts]) ->
  5247. case type(T) of
  5248. comment ->
  5249. revert_forms_1(Ts);
  5250. _ ->
  5251. T1 = revert(T),
  5252. case is_tree(T1) of
  5253. true ->
  5254. throw({error, T1});
  5255. false ->
  5256. [T1 | revert_forms_1(Ts)]
  5257. end
  5258. end;
  5259. revert_forms_1([]) ->
  5260. [].
  5261. %% =====================================================================
  5262. %% @spec subtrees(Node::syntaxTree()) -> [[syntaxTree()]]
  5263. %%
  5264. %% @doc Returns the grouped list of all subtrees of a syntax tree. If
  5265. %% <code>Node</code> is a leaf node (cf. <code>is_leaf/1</code>), this
  5266. %% is the empty list, otherwise the result is always a nonempty list,
  5267. %% containing the lists of subtrees of <code>Node</code>, in
  5268. %% left-to-right order as they occur in the printed program text, and
  5269. %% grouped by category. Often, each group contains only a single
  5270. %% subtree.
  5271. %%
  5272. %% <p>Depending on the type of <code>Node</code>, the size of some
  5273. %% groups may be variable (e.g., the group consisting of all the
  5274. %% elements of a tuple), while others always contain the same number of
  5275. %% elements - usually exactly one (e.g., the group containing the
  5276. %% argument expression of a case-expression). Note, however, that the
  5277. %% exact structure of the returned list (for a given node type) should
  5278. %% in general not be depended upon, since it might be subject to change
  5279. %% without notice.</p>
  5280. %%
  5281. %% <p>The function <code>subtrees/1</code> and the constructor functions
  5282. %% <code>make_tree/2</code> and <code>update_tree/2</code> can be a
  5283. %% great help if one wants to traverse a syntax tree, visiting all its
  5284. %% subtrees, but treat nodes of the tree in a uniform way in most or all
  5285. %% cases. Using these functions makes this simple, and also assures that
  5286. %% your code is not overly sensitive to extensions of the syntax tree
  5287. %% data type, because any node types not explicitly handled by your code
  5288. %% can be left to a default case.</p>
  5289. %%
  5290. %% <p>For example:
  5291. %% <pre>
  5292. %% postorder(F, Tree) ->
  5293. %% F(case subtrees(Tree) of
  5294. %% [] -> Tree;
  5295. %% List -> update_tree(Tree,
  5296. %% [[postorder(F, Subtree)
  5297. %% || Subtree &lt;- Group]
  5298. %% || Group &lt;- List])
  5299. %% end).
  5300. %% </pre>
  5301. %% maps the function <code>F</code> on <code>Tree</code> and all its
  5302. %% subtrees, doing a post-order traversal of the syntax tree. (Note the
  5303. %% use of <code>update_tree/2</code> to preserve node attributes.) For a
  5304. %% simple function like:
  5305. %% <pre>
  5306. %% f(Node) ->
  5307. %% case type(Node) of
  5308. %% atom -> atom("a_" ++ atom_name(Node));
  5309. %% _ -> Node
  5310. %% end.
  5311. %% </pre>
  5312. %% the call <code>postorder(fun f/1, Tree)</code> will yield a new
  5313. %% representation of <code>Tree</code> in which all atom names have been
  5314. %% extended with the prefix "a_", but nothing else (including comments,
  5315. %% annotations and line numbers) has been changed.</p>
  5316. %%
  5317. %% @see make_tree/2
  5318. %% @see type/1
  5319. %% @see is_leaf/1
  5320. %% @see copy_attrs/2
  5321. subtrees(T) ->
  5322. case is_leaf(T) of
  5323. true ->
  5324. [];
  5325. false ->
  5326. case type(T) of
  5327. application ->
  5328. [[application_operator(T)],
  5329. application_arguments(T)];
  5330. arity_qualifier ->
  5331. [[arity_qualifier_body(T)],
  5332. [arity_qualifier_argument(T)]];
  5333. attribute ->
  5334. case attribute_arguments(T) of
  5335. none ->
  5336. [[attribute_name(T)]];
  5337. As ->
  5338. [[attribute_name(T)], As]
  5339. end;
  5340. binary ->
  5341. [binary_fields(T)];
  5342. binary_field ->
  5343. case binary_field_types(T) of
  5344. [] ->
  5345. [[binary_field_body(T)]];
  5346. Ts ->
  5347. [[binary_field_body(T)],
  5348. Ts]
  5349. end;
  5350. block_expr ->
  5351. [block_expr_body(T)];
  5352. case_expr ->
  5353. [[case_expr_argument(T)],
  5354. case_expr_clauses(T)];
  5355. catch_expr ->
  5356. [[catch_expr_body(T)]];
  5357. class_qualifier ->
  5358. [[class_qualifier_argument(T)],
  5359. [class_qualifier_body(T)]];
  5360. clause ->
  5361. case clause_guard(T) of
  5362. none ->
  5363. [clause_patterns(T), clause_body(T)];
  5364. G ->
  5365. [clause_patterns(T), [G],
  5366. clause_body(T)]
  5367. end;
  5368. cond_expr ->
  5369. [cond_expr_clauses(T)];
  5370. conjunction ->
  5371. [conjunction_body(T)];
  5372. disjunction ->
  5373. [disjunction_body(T)];
  5374. form_list ->
  5375. [form_list_elements(T)];
  5376. fun_expr ->
  5377. [fun_expr_clauses(T)];
  5378. function ->
  5379. [[function_name(T)], function_clauses(T)];
  5380. generator ->
  5381. [[generator_pattern(T)], [generator_body(T)]];
  5382. if_expr ->
  5383. [if_expr_clauses(T)];
  5384. implicit_fun ->
  5385. [[implicit_fun_name(T)]];
  5386. infix_expr ->
  5387. [[infix_expr_left(T)],
  5388. [infix_expr_operator(T)],
  5389. [infix_expr_right(T)]];
  5390. list ->
  5391. case list_suffix(T) of
  5392. none ->
  5393. [list_prefix(T)];
  5394. S ->
  5395. [list_prefix(T), [S]]
  5396. end;
  5397. list_comp ->
  5398. [[list_comp_template(T)], list_comp_body(T)];
  5399. macro ->
  5400. case macro_arguments(T) of
  5401. none ->
  5402. [[macro_name(T)]];
  5403. As ->
  5404. [[macro_name(T)], As]
  5405. end;
  5406. match_expr ->
  5407. [[match_expr_pattern(T)],
  5408. [match_expr_body(T)]];
  5409. module_qualifier ->
  5410. [[module_qualifier_argument(T)],
  5411. [module_qualifier_body(T)]];
  5412. parentheses ->
  5413. [[parentheses_body(T)]];
  5414. prefix_expr ->
  5415. [[prefix_expr_operator(T)],
  5416. [prefix_expr_argument(T)]];
  5417. qualified_name ->
  5418. [qualified_name_segments(T)];
  5419. query_expr ->
  5420. [[query_expr_body(T)]];
  5421. receive_expr ->
  5422. case receive_expr_timeout(T) of
  5423. none ->
  5424. [receive_expr_clauses(T)];
  5425. E ->
  5426. [receive_expr_clauses(T),
  5427. [E],
  5428. receive_expr_action(T)]
  5429. end;
  5430. record_access ->
  5431. case record_access_type(T) of
  5432. none ->
  5433. [[record_access_argument(T)],
  5434. [record_access_field(T)]];
  5435. R ->
  5436. [[record_access_argument(T)],
  5437. [R],
  5438. [record_access_field(T)]]
  5439. end;
  5440. record_expr ->
  5441. case record_expr_argument(T) of
  5442. none ->
  5443. [[record_expr_type(T)],
  5444. record_expr_fields(T)];
  5445. V ->
  5446. [[V],
  5447. [record_expr_type(T)],
  5448. record_expr_fields(T)]
  5449. end;
  5450. record_field ->
  5451. case record_field_value(T) of
  5452. none ->
  5453. [[record_field_name(T)]];
  5454. V ->
  5455. [[record_field_name(T)], [V]]
  5456. end;
  5457. record_index_expr ->
  5458. [[record_index_expr_type(T)],
  5459. [record_index_expr_field(T)]];
  5460. rule ->
  5461. [[rule_name(T)], rule_clauses(T)];
  5462. size_qualifier ->
  5463. [[size_qualifier_body(T)],
  5464. [size_qualifier_argument(T)]];
  5465. try_expr ->
  5466. [try_expr_body(T),
  5467. try_expr_clauses(T),
  5468. try_expr_handlers(T),
  5469. try_expr_after(T)];
  5470. tuple ->
  5471. [tuple_elements(T)]
  5472. end
  5473. end.
  5474. %% =====================================================================
  5475. %% @spec update_tree(Node::syntaxTree(), Groups::[[syntaxTree()]]) ->
  5476. %% syntaxTree()
  5477. %%
  5478. %% @doc Creates a syntax tree with the same type and attributes as the
  5479. %% given tree. This is equivalent to <code>copy_attrs(Node,
  5480. %% make_tree(type(Node), Groups))</code>.
  5481. %%
  5482. %% @see make_tree/2
  5483. %% @see copy_attrs/2
  5484. %% @see type/1
  5485. update_tree(Node, Groups) ->
  5486. copy_attrs(Node, make_tree(type(Node), Groups)).
  5487. %% =====================================================================
  5488. %% @spec make_tree(Type::atom(), Groups::[[syntaxTree()]]) ->
  5489. %% syntaxTree()
  5490. %%
  5491. %% @doc Creates a syntax tree with the given type and subtrees.
  5492. %% <code>Type</code> must be a node type name (cf. <code>type/1</code>)
  5493. %% that does not denote a leaf node type (cf. <code>is_leaf/1</code>).
  5494. %% <code>Groups</code> must be a <em>nonempty</em> list of groups of
  5495. %% syntax trees, representing the subtrees of a node of the given type,
  5496. %% in left-to-right order as they would occur in the printed program
  5497. %% text, grouped by category as done by <code>subtrees/1</code>.
  5498. %%
  5499. %% <p>The result of <code>copy_attrs(Node, make_tree(type(Node),
  5500. %% subtrees(Node)))</code> (cf. <code>update_tree/2</code>) represents
  5501. %% the same source code text as the original <code>Node</code>, assuming
  5502. %% that <code>subtrees(Node)</code> yields a nonempty list. However, it
  5503. %% does not necessarily have the same data representation as
  5504. %% <code>Node</code>.</p>
  5505. %%
  5506. %% @see update_tree/1
  5507. %% @see subtrees/1
  5508. %% @see type/1
  5509. %% @see is_leaf/1
  5510. %% @see copy_attrs/2
  5511. make_tree(application, [[F], A]) -> application(F, A);
  5512. make_tree(arity_qualifier, [[N], [A]]) -> arity_qualifier(N, A);
  5513. make_tree(attribute, [[N]]) -> attribute(N);
  5514. make_tree(attribute, [[N], A]) -> attribute(N, A);
  5515. make_tree(binary, [Fs]) -> binary(Fs);
  5516. make_tree(binary_field, [[B]]) -> binary_field(B);
  5517. make_tree(binary_field, [[B], Ts]) -> binary_field(B, Ts);
  5518. make_tree(block_expr, [B]) -> block_expr(B);
  5519. make_tree(case_expr, [[A], C]) -> case_expr(A, C);
  5520. make_tree(catch_expr, [[B]]) -> catch_expr(B);
  5521. make_tree(class_qualifier, [[A], [B]]) -> class_qualifier(A, B);
  5522. make_tree(clause, [P, B]) -> clause(P, none, B);
  5523. make_tree(clause, [P, [G], B]) -> clause(P, G, B);
  5524. make_tree(cond_expr, [C]) -> cond_expr(C);
  5525. make_tree(conjunction, [E]) -> conjunction(E);
  5526. make_tree(disjunction, [E]) -> disjunction(E);
  5527. make_tree(form_list, [E]) -> form_list(E);
  5528. make_tree(fun_expr, [C]) -> fun_expr(C);
  5529. make_tree(function, [[N], C]) -> function(N, C);
  5530. make_tree(generator, [[P], [E]]) -> generator(P, E);
  5531. make_tree(if_expr, [C]) -> if_expr(C);
  5532. make_tree(implicit_fun, [[N]]) -> implicit_fun(N);
  5533. make_tree(infix_expr, [[L], [F], [R]]) -> infix_expr(L, F, R);
  5534. make_tree(list, [P]) -> list(P);
  5535. make_tree(list, [P, [S]]) -> list(P, S);
  5536. make_tree(list_comp, [[T], B]) -> list_comp(T, B);
  5537. make_tree(macro, [[N]]) -> macro(N);
  5538. make_tree(macro, [[N], A]) -> macro(N, A);
  5539. make_tree(match_expr, [[P], [E]]) -> match_expr(P, E);
  5540. make_tree(module_qualifier, [[M], [N]]) -> module_qualifier(M, N);
  5541. make_tree(parentheses, [[E]]) -> parentheses(E);
  5542. make_tree(prefix_expr, [[F], [A]]) -> prefix_expr(F, A);
  5543. make_tree(qualified_name, [S]) -> qualified_name(S);
  5544. make_tree(query_expr, [[B]]) -> query_expr(B);
  5545. make_tree(receive_expr, [C]) -> receive_expr(C);
  5546. make_tree(receive_expr, [C, [E], A]) -> receive_expr(C, E, A);
  5547. make_tree(record_access, [[E], [F]]) ->
  5548. record_access(E, F);
  5549. make_tree(record_access, [[E], [T], [F]]) ->
  5550. record_access(E, T, F);
  5551. make_tree(record_expr, [[T], F]) -> record_expr(T, F);
  5552. make_tree(record_expr, [[E], [T], F]) -> record_expr(E, T, F);
  5553. make_tree(record_field, [[N]]) -> record_field(N);
  5554. make_tree(record_field, [[N], [E]]) -> record_field(N, E);
  5555. make_tree(record_index_expr, [[T], [F]]) ->
  5556. record_index_expr(T, F);
  5557. make_tree(rule, [[N], C]) -> rule(N, C);
  5558. make_tree(size_qualifier, [[N], [A]]) -> size_qualifier(N, A);
  5559. make_tree(try_expr, [B, C, H, A]) -> try_expr(B, C, H, A);
  5560. make_tree(tuple, [E]) -> tuple(E).
  5561. %% =====================================================================
  5562. %% @spec meta(Tree::syntaxTree()) -> syntaxTree()
  5563. %%
  5564. %% @doc Creates a meta-representation of a syntax tree. The result
  5565. %% represents an Erlang expression "<code><em>MetaTree</em></code>"
  5566. %% which, if evaluated, will yield a new syntax tree representing the
  5567. %% same source code text as <code>Tree</code> (although the actual data
  5568. %% representation may be different). The expression represented by
  5569. %% <code>MetaTree</code> is <em>implementation independent</em> with
  5570. %% regard to the data structures used by the abstract syntax tree
  5571. %% implementation. Comments attached to nodes of <code>Tree</code> will
  5572. %% be preserved, but other attributes are lost.
  5573. %%
  5574. %% <p>Any node in <code>Tree</code> whose node type is
  5575. %% <code>variable</code> (cf. <code>type/1</code>), and whose list of
  5576. %% annotations (cf. <code>get_ann/1</code>) contains the atom
  5577. %% <code>meta_var</code>, will remain unchanged in the resulting tree,
  5578. %% except that exactly one occurrence of <code>meta_var</code> is
  5579. %% removed from its annotation list.</p>
  5580. %%
  5581. %% <p>The main use of the function <code>meta/1</code> is to transform a
  5582. %% data structure <code>Tree</code>, which represents a piece of program
  5583. %% code, into a form that is <em>representation independent when
  5584. %% printed</em>. E.g., suppose <code>Tree</code> represents a variable
  5585. %% named "V". Then (assuming a function <code>print/1</code> for
  5586. %% printing syntax trees), evaluating <code>print(abstract(Tree))</code>
  5587. %% - simply using <code>abstract/1</code> to map the actual data
  5588. %% structure onto a syntax tree representation - would output a string
  5589. %% that might look something like "<code>{tree, variable, ..., "V",
  5590. %% ...}</code>", which is obviously dependent on the implementation of
  5591. %% the abstract syntax trees. This could e.g. be useful for caching a
  5592. %% syntax tree in a file. However, in some situations like in a program
  5593. %% generator generator (with two "generator"), it may be unacceptable.
  5594. %% Using <code>print(meta(Tree))</code> instead would output a
  5595. %% <em>representation independent</em> syntax tree generating
  5596. %% expression; in the above case, something like
  5597. %% "<code>erl_syntax:variable("V")</code>".</p>
  5598. %%
  5599. %% @see abstract/1
  5600. %% @see type/1
  5601. %% @see get_ann/1
  5602. meta(T) ->
  5603. %% First of all we check for metavariables:
  5604. case type(T) of
  5605. variable ->
  5606. case lists:member(meta_var, get_ann(T)) of
  5607. false ->
  5608. meta_precomment(T);
  5609. true ->
  5610. %% A meta-variable: remove the first found
  5611. %% `meta_var' annotation, but otherwise leave
  5612. %% the node unchanged.
  5613. set_ann(T, lists:delete(meta_var, get_ann(T)))
  5614. end;
  5615. _ ->
  5616. case has_comments(T) of
  5617. true ->
  5618. meta_precomment(T);
  5619. false ->
  5620. meta_1(T)
  5621. end
  5622. end.
  5623. meta_precomment(T) ->
  5624. case get_precomments(T) of
  5625. [] ->
  5626. meta_postcomment(T);
  5627. Cs ->
  5628. meta_call(set_precomments,
  5629. [meta_postcomment(T), list(meta_list(Cs))])
  5630. end.
  5631. meta_postcomment(T) ->
  5632. case get_postcomments(T) of
  5633. [] ->
  5634. meta_0(T);
  5635. Cs ->
  5636. meta_call(set_postcomments,
  5637. [meta_0(T), list(meta_list(Cs))])
  5638. end.
  5639. meta_0(T) ->
  5640. meta_1(remove_comments(T)).
  5641. meta_1(T) ->
  5642. %% First handle leaf nodes and other common cases, in order to
  5643. %% generate compact code.
  5644. case type(T) of
  5645. atom ->
  5646. meta_call(atom, [T]);
  5647. char ->
  5648. meta_call(char, [T]);
  5649. comment ->
  5650. meta_call(comment, [list([string(S)
  5651. || S <- comment_text(T)])]);
  5652. eof_marker ->
  5653. meta_call(eof_marker, []);
  5654. error_marker ->
  5655. meta_call(error_marker,
  5656. [abstract(error_marker_info(T))]);
  5657. float ->
  5658. meta_call(float, [T]);
  5659. integer ->
  5660. meta_call(integer, [T]);
  5661. nil ->
  5662. meta_call(nil, []);
  5663. operator ->
  5664. meta_call(operator, [atom(operator_name(T))]);
  5665. string ->
  5666. meta_call(string, [T]);
  5667. text ->
  5668. meta_call(text, [string(text_string(T))]);
  5669. underscore ->
  5670. meta_call(underscore, []);
  5671. variable ->
  5672. meta_call(variable, [string(variable_name(T))]);
  5673. warning_marker ->
  5674. meta_call(warning_marker,
  5675. [abstract(warning_marker_info(T))]);
  5676. list ->
  5677. case list_suffix(T) of
  5678. none ->
  5679. meta_call(list,
  5680. [list(meta_list(list_prefix(T)))]);
  5681. S ->
  5682. meta_call(list,
  5683. [list(meta_list(list_prefix(T))),
  5684. meta(S)])
  5685. end;
  5686. tuple ->
  5687. meta_call(tuple,
  5688. [list(meta_list(tuple_elements(T)))]);
  5689. Type ->
  5690. %% All remaining cases are handled using `subtrees'
  5691. %% and `make_tree' to decompose and reassemble the
  5692. %% nodes. More cases could of course be handled
  5693. %% directly to get a more compact output, but I can't
  5694. %% be bothered right now.
  5695. meta_call(make_tree,
  5696. [abstract(Type),
  5697. meta_subtrees(subtrees(T))])
  5698. end.
  5699. meta_list([T | Ts]) ->
  5700. [meta(T) | meta_list(Ts)];
  5701. meta_list([]) ->
  5702. [].
  5703. meta_subtrees(Gs) ->
  5704. list([list([meta(T)
  5705. || T <- G])
  5706. || G <- Gs]).
  5707. meta_call(F, As) ->
  5708. application(atom(?MODULE), atom(F), As).
  5709. %% =====================================================================
  5710. %% Functions for abstraction of the syntax tree representation; may be
  5711. %% used externally, but not intended for the normal user.
  5712. %% =====================================================================
  5713. %% =====================================================================
  5714. %% @spec tree(Type) -> syntaxTree()
  5715. %% @equiv tree(Type, [])
  5716. tree(Type) ->
  5717. tree(Type, []).
  5718. %% =====================================================================
  5719. %% @spec tree(Type::atom(), Data::term()) -> syntaxTree()
  5720. %%
  5721. %% @doc <em>For special purposes only</em>. Creates an abstract syntax
  5722. %% tree node with type tag <code>Type</code> and associated data
  5723. %% <code>Data</code>.
  5724. %%
  5725. %% <p>This function and the related <code>is_tree/1</code> and
  5726. %% <code>data/1</code> provide a uniform way to extend the set of
  5727. %% <code>erl_parse</code> node types. The associated data is any term,
  5728. %% whose format may depend on the type tag.</p>
  5729. %%
  5730. %% <h4>Notes:</h4>
  5731. %% <ul>
  5732. %% <li>Any nodes created outside of this module must have type tags
  5733. %% distinct from those currently defined by this module; see
  5734. %% <code>type/1</code> for a complete list.</li>
  5735. %% <li>The type tag of a syntax tree node may also be used
  5736. %% as a primary tag by the <code>erl_parse</code> representation;
  5737. %% in that case, the selector functions for that node type
  5738. %% <em>must</em> handle both the abstract syntax tree and the
  5739. %% <code>erl_parse</code> form. The function <code>type(T)</code>
  5740. %% should return the correct type tag regardless of the
  5741. %% representation of <code>T</code>, so that the user sees no
  5742. %% difference between <code>erl_syntax</code> and
  5743. %% <code>erl_parse</code> nodes.</li>
  5744. %% </ul>
  5745. %% @see is_tree/1
  5746. %% @see data/1
  5747. %% @see type/1
  5748. tree(Type, Data) ->
  5749. #tree{type = Type, data = Data}.
  5750. %% =====================================================================
  5751. %% @spec is_tree(Tree::syntaxTree()) -> bool()
  5752. %%
  5753. %% @doc <em>For special purposes only</em>. Returns <code>true</code> if
  5754. %% <code>Tree</code> is an abstract syntax tree and <code>false</code>
  5755. %% otherwise.
  5756. %%
  5757. %% <p><em>Note</em>: this function yields <code>false</code> for all
  5758. %% "old-style" <code>erl_parse</code>-compatible "parse trees".</p>
  5759. %%
  5760. %% @see tree/2
  5761. is_tree(#tree{}) ->
  5762. true;
  5763. is_tree(_) ->
  5764. false.
  5765. %% =====================================================================
  5766. %% @spec data(Tree::syntaxTree()) -> term()
  5767. %%
  5768. %% @doc <em>For special purposes only</em>. Returns the associated data
  5769. %% of a syntax tree node. Evaluation fails with reason
  5770. %% <code>badarg</code> if <code>is_tree(Node)</code> does not yield
  5771. %% <code>true</code>.
  5772. %%
  5773. %% @see tree/2
  5774. data(#tree{data = D}) -> D;
  5775. data(T) -> erlang:fault({badarg, T}).
  5776. %% =====================================================================
  5777. %% Primitives for backwards compatibility; for internal use only
  5778. %% =====================================================================
  5779. %% =====================================================================
  5780. %% @spec wrap(Node::erl_parse()) -> syntaxTree()
  5781. %%
  5782. %% @type erl_parse() = erl_parse:parse_tree(). The "parse tree"
  5783. %% representation built by the Erlang standard library parser
  5784. %% <code>erl_parse</code>. This is a subset of the
  5785. %% <a href="#type-syntaxTree"><code>syntaxTree</code></a> type.
  5786. %%
  5787. %% @doc Creates a wrapper structure around an <code>erl_parse</code>
  5788. %% "parse tree".
  5789. %%
  5790. %% <p>This function and the related <code>unwrap/1</code> and
  5791. %% <code>is_wrapper/1</code> provide a uniform way to attach arbitrary
  5792. %% information to an <code>erl_parse</code> tree. Some information about
  5793. %% the encapsuled tree may be cached in the wrapper, such as the node
  5794. %% type. All functions on syntax trees must behave so that the user sees
  5795. %% no difference between wrapped and non-wrapped <code>erl_parse</code>
  5796. %% trees. <em>Attaching a wrapper onto another wrapper structure is an
  5797. %% error</em>.</p>
  5798. wrap(Node) ->
  5799. %% We assume that Node is an old-school `erl_parse' tree.
  5800. #wrapper{type = type(Node), attr = #attr{pos = get_pos(Node)},
  5801. tree = Node}.
  5802. %% =====================================================================
  5803. %% @spec unwrap(Node::syntaxTree()) -> syntaxTree()
  5804. %%
  5805. %% @doc Removes any wrapper structure, if present. If <code>Node</code>
  5806. %% is a wrapper structure, this function returns the wrapped
  5807. %% <code>erl_parse</code> tree; otherwise it returns <code>Node</code>
  5808. %% itself.
  5809. unwrap(#wrapper{tree = Node}) -> Node;
  5810. unwrap(Node) -> Node. % This could also be a new-form node.
  5811. %% =====================================================================
  5812. %% @spec is_wrapper(Term::term()) -> bool()
  5813. %%
  5814. %% @doc Returns <code>true</code> if the argument is a wrapper
  5815. %% structure, otherwise <code>false</code>.
  5816. -ifndef(NO_UNUSED).
  5817. is_wrapper(#wrapper{}) ->
  5818. true;
  5819. is_wrapper(_) ->
  5820. false.
  5821. -endif.
  5822. %% =====================================================================
  5823. %% General utility functions for internal use
  5824. %% =====================================================================
  5825. is_printable(S) ->
  5826. io_lib:printable_list(S).
  5827. %% Support functions for transforming lists of function names
  5828. %% specified as `arity_qualifier' nodes.
  5829. unfold_function_names(Ns, Pos) ->
  5830. F = fun ({Atom, Arity}) ->
  5831. N = arity_qualifier(atom(Atom), integer(Arity)),
  5832. set_pos(N, Pos)
  5833. end,
  5834. [F(N) || N <- Ns].
  5835. fold_function_names(Ns) ->
  5836. [fold_function_name(N) || N <- Ns].
  5837. fold_function_name(N) ->
  5838. Name = arity_qualifier_body(N),
  5839. Arity = arity_qualifier_argument(N),
  5840. case (type(Name) == atom) and (type(Arity) == integer) of
  5841. true ->
  5842. {concrete(Name), concrete(Arity)}
  5843. end.
  5844. fold_variable_names(Vs) ->
  5845. [variable_name(V) || V <- Vs].
  5846. unfold_variable_names(Vs, Pos) ->
  5847. [set_pos(variable(V), Pos) || V <- Vs].
  5848. %% Support functions for qualified names ("foo.bar.baz",
  5849. %% "erl.lang.lists", etc.). The representation overlaps with the weird
  5850. %% "Mnesia query record access" operators. The '.' operator is left
  5851. %% associative, so folding should nest on the left.
  5852. is_qualified_name({record_field, _, L, R}) ->
  5853. case is_qualified_name(L) of
  5854. true -> is_qualified_name(R);
  5855. false -> false
  5856. end;
  5857. is_qualified_name({atom, _, _}) -> true;
  5858. is_qualified_name(_) -> false.
  5859. unfold_qualified_name(Node) ->
  5860. lists:reverse(unfold_qualified_name(Node, [])).
  5861. unfold_qualified_name({record_field, _, L, R}, Ss) ->
  5862. unfold_qualified_name(R, unfold_qualified_name(L, Ss));
  5863. unfold_qualified_name(S, Ss) -> [S | Ss].
  5864. fold_qualified_name([S | Ss], Pos) ->
  5865. fold_qualified_name(Ss, Pos, {atom, Pos, atom_value(S)}).
  5866. fold_qualified_name([S | Ss], Pos, Ack) ->
  5867. fold_qualified_name(Ss, Pos, {record_field, Pos, Ack,
  5868. {atom, Pos, atom_value(S)}});
  5869. fold_qualified_name([], _Pos, Ack) ->
  5870. Ack.
  5871. %% Support functions for transforming lists of record field definitions.
  5872. %%
  5873. %% There is no unique representation for field definitions in the
  5874. %% standard form. There, they may only occur in the "fields" part of a
  5875. %% record expression or declaration, and are represented as
  5876. %% `{record_field, Pos, Name, Value}', or as `{record_field, Pos, Name}'
  5877. %% if the value part is left out. However, these cannot be distinguished
  5878. %% out of context from the representation of record field access
  5879. %% expressions (see `record_access').
  5880. fold_record_fields(Fs) ->
  5881. [fold_record_field(F) || F <- Fs].
  5882. fold_record_field(F) ->
  5883. Pos = get_pos(F),
  5884. Name = record_field_name(F),
  5885. case record_field_value(F) of
  5886. none ->
  5887. {record_field, Pos, Name};
  5888. Value ->
  5889. {record_field, Pos, Name, Value}
  5890. end.
  5891. unfold_record_fields(Fs) ->
  5892. [unfold_record_field(F) || F <- Fs].
  5893. unfold_record_field({record_field, Pos, Name}) ->
  5894. set_pos(record_field(Name), Pos);
  5895. unfold_record_field({record_field, Pos, Name, Value}) ->
  5896. set_pos(record_field(Name, Value), Pos).
  5897. fold_binary_field_types(Ts) ->
  5898. [fold_binary_field_type(T) || T <- Ts].
  5899. fold_binary_field_type(Node) ->
  5900. case type(Node) of
  5901. size_qualifier ->
  5902. {concrete(size_qualifier_body(Node)),
  5903. concrete(size_qualifier_argument(Node))};
  5904. _ ->
  5905. concrete(Node)
  5906. end.
  5907. unfold_binary_field_types(Ts, Pos) ->
  5908. [unfold_binary_field_type(T, Pos) || T <- Ts].
  5909. unfold_binary_field_type({Type, Size}, Pos) ->
  5910. set_pos(size_qualifier(atom(Type), integer(Size)), Pos);
  5911. unfold_binary_field_type(Type, Pos) ->
  5912. set_pos(atom(Type), Pos).
  5913. %% =====================================================================