Many SUIF programs contain code that visits all of the nodes in an AST
to perform various operations. Rather than having every programmer
duplicate the code for this traversal, the SUIF library includes methods
to map functions over ASTs. The tree_node
and
tree_node_list
classes both provide these map
methods.
The function to be mapped must be of type tree_map_f
. For a tree
node, the map
method applies the function to the tree node and
all of its children. The preorder
parameter is used to select
either preorder or postorder traversals; the default is preorder. For
preorder traversals, the function is applied to the tree node before it
is applied to the children. For postorder, the function is first
applied to the tree_node's children and descendants and then last
applied to the tree node itself.
The map
method for a tree node list calls map
for each
node in the list. The nodes are visited in order from first to last
regardless of the preorder
parameter. The tree_node_list
version of the map
method has an extra optional parameter that
allows you to only map the function over the entries in the list without
recursively visiting their children.
The tree_map_f
functions have two parameters: a pointer to the
tree node and a void*
value passed on from the map
method.
Additional parameters can be passed by making the void*
value a
pointer to a structure containing the parameters. For example, the
following code counts the number of tree_for
and tree_loop
nodes in a procedure:
struct count_result { int num_fors; int num_loops; }; void count_loops (tree_node *t, void *x) { count_result *results = (count_result *)x; if (t->kind() == TREE_FOR) results->num_fors++; else if (t->kind() == TREE_LOOP) results->num_loops++; } /* * Return the number of tree_fors and tree_loops in the procedure. */ void counter (tree_proc *p, int *for_count, int *loop_count) { count_result results; results.num_fors = 0; results.num_loops = 0; p->map(count_loops, (void *)&results); *for_count = results.num_fors; *loop_count = results.num_loops; }