A tree_block node introduces a new scope. Nested scopes are
useful for retaining scope information from source programs and for
debugging purposes. They are also very useful for implementing code
transformations. For example, name conflicts are easily avoided by
introducing new scopes.
A tree_block node contains a block_symtab symbol table and
a tree node list for the body. The symbol table is accessed with the
symtab and set_symtab methods. The body and
set_body methods are used to get and set the list of tree nodes
inside the block.
There is a one-to-one correspondence between a tree_block and its
symbol table, and the hierarchy of symbol tables within a procedure must
parallel the hierarchy of tree_block nodes. When inserting a
tree_block into an AST, the new block's symbol table must be
inserted in the appropriate place in the symbol table hierarchy. When a
tree_block is destroyed, the associated symbol table is detached
from its parent table and destroyed. However, the converse is not
true--when a block_symtab is deleted, the corresponding
tree_block node is not deleted.
The entries in a block's symbol table may not be referenced from outside
the block. There are no other restrictions on tree_block nodes.
The bodies may be empty or contain any kinds of tree nodes. Blocks are
usually entered from the beginning but that is not required; unlike
other AST nodes, branches into the middle of a block are allowed.
As an example, the following code creates a new tree_block and
its associated symbol table. It then adds the new block to the
body of an existing block node:
block_symtab *new_symtab = new block_symtab("my_symtab");
cur_block->symtab()->add_child(new_symtab);
tree_node_list *tl = new tree_node_list;
tree_block *new_block = new tree_block(tl, new_symtab);
cur_block->body()->append(new_block);