The abstract syntax tree (AST) node representing a compilation unit, and so
the root of the AST.
It keeps track of the name of the source file, its package name, a list of
imported types, a list of type (eg class) declarations, and a flag indicating
if a semantic error has been detected in analysis or code generation. It also
maintains a CompilationUnitContext (built in pre-analysis) for declaring both
imported and declared types.
The AST is produced by the Parser. Once the AST has been built, three
successive methods are invoked:
(1) Method preAnalyze() is invoked for making a first pass at type analysis,
recursively reaching down to the member headers for declaring types and
member interfaces in the environment (contexts). preAnalyze() also creates a
partial class file (in memory) for recording member header information, using
the partialCodegen() method.
(2) Method analyze() is invoked for type-checking field initializations and
method bodies, and determining the types of all expressions. A certain amount
of tree surgery is also done here. And stack frame offsets are computed for
method parameters and local variables.
(3) Method codegen() is invoked for generating code for the compilation unit
to a class file. For each type declaration, it instantiates a CLEmmiter
object (an abstraction of the class file) and then invokes methods on that
CLEmitter for generating instructions. At the end of each type declaration, a
method is invoked on the CLEmitter which writes the class out to the file
system either as .class file or as a .s (SPIM) file. Of course, codegen()
makes recursive calls down the tree, to the codegen() methods at each node,
for generating the appropriate instructions.