The sym_node
class defines several fields that are used by all
kinds of symbols. The most obvious of these is the symbol name. Each
symbol has a name that should be unique within the symbol table where it
is defined. The name
and set_name
methods access this
field. The names are automatically entered in the lexicon
(see section Lexicon) by set_name
. Because the name of a symbol
alone is generally insufficient to uniquely identify it, the symbols are
also given ID numbers. See section Numbering Types and Symbols.
When a symbol is entered in a symbol table, it automatically records a
pointer to that parent table. Similarly, when the symbol is removed
from the symbol table, its parent pointer is cleared. The parent
method retrieves this parent pointer.
All symbols contain flags to specify various attributes. The
sym_node
class provides methods to access these flags. The
is_userdef
method tests a flag to see if it is a user-defined
symbol (from the source code) or a new symbol introduced by the
compiler. The set_userdef
and reset_userdef
methods
change the value of this flag.
Another flag is used to mark symbols that are only declarations of
external symbols, rather than actual definitions. This flag is set
automatically. The is_extern
method retrieves its value. Label
symbols are never extern
. A procedure symbol is extern
unless the procedure body is defined in the input file(s). A global
variable symbol is extern
unless it has a separate definition
(see section Variable Definitions); no other variables are extern
.
Since symbols may be treated differently depending on their scopes, the
sym_node
class includes methods to determine which kind of symbol
table contains a symbol. The is_global
method checks if the
parent table is a global or file symbol table. This is really only
useful for variable symbols, because procedures are always global and
labels are never global. The is_private
method checks if a
symbol is global but private to one source file by checking if the
parent symbol table is a file symbol table. This is obviously
irrelevant for label symbols.
The add_to_table
and remove_from_table
methods are
provided for convenience when adding or removing symbols from symbol
tables. In the case of variable symbols, the entire hierarchy of
sub-variables (see section Sub-Variables) is added or removed at one time
by this method.
The copy
method makes a copy of a symbol. This is a virtual
function so it copies the fields that are specific to each kind of
symbol. However, it only copies the symbol itself: copying a procedure
symbol will not copy the procedure body and copying a variable symbol
will not copy the variable definition. The copy
method does not
copy annotations on the symbol, either. Since the copy will have the
same name as the original symbol, it should generally be renamed or used
in a different symbol table.
Two different methods are available for printing symbols. The
print
method just prints the name of the symbol. Label symbols
are prefixed by `L:' and procedure symbols by `P:' to
distinguish them from variable symbols. The print_full
method is
used by the library when listing the contents of symbol tables. It
includes all the fields from the sym_node
.