Java Reference
In-Depth Information
are more likely to be adding new syntax to j--, together with its functionality. Making
extensions to j-- would require our modifying each of the phases.
Moreover, often the traversal order for one node type differs from that of another. And
sometimes we want to perform actions at a node before, after, and even in between the
traversal of the sub-trees. For example, take a look at codegen() for the JIfStatement :
publicvoidcodegen(CLEmitteroutput){
StringelseLabel=output.createLabel();
StringendLabel=output.createLabel();
condition.codegen(output,elseLabel,false);
thenPart.codegen(output);
if(elsePart!=null){
output.addBranchInstruction(GOTO,endLabel);
}
output.addLabel(elseLabel);
if(elsePart!=null){
elsePart.codegen(output);
output.addLabel(endLabel);
}
}
Mixing the traversal code along with the actions is just so much more flexible. For this
reason, the j-- compiler eschews the visitor pattern.
4.7 Programming Language Design and Symbol Table Structure
Our symbol table for j-- has two parts:
1. A linked list (or stack) of contexts (hash tables) for capturing the nested scope of type
definitions and local variables. Types are maintained in a CompilationUnitContext
at the base of this list (or stack). Local variables are looked up beginning at the end
of this linked list (or top of the stack); this reflects the nested scope of local variables.
That names at each level of scope are defined in a hash table speeds up the lookup
operation. Keeping a linked list of these hash tables, one for each lexical level of scope,
speeds up compile-time block entry and block exit.
2. Classes are represented by Type objects, stored in the CompilationUnitContext , and
built upon Java's Class objects|Java's representation for types. This representation
reects the fact that a class' method names and eld names are particular to that
class, and it allows j-- programs to engage with existing classes in the Java API.
Thus, the symbol table structure in our compiler is pretty much dictated by the design of
the j-- programming language.
If we were to implement nested class declarations (an exercise in Chapter 5), some of
the infrastructure is already in our symbol table design|additional classes can be stored in
nested contexts; we may have to modify addType() and lookupType() somewhat. Other
languages that have classes or modules (such as the programming language Modula) will
want a symbol table whose structure is similar to ours.
But other, simpler procedural languages, such as the C language, in which a name is
either external to all functions or local to a function, may have much simpler symbol tables.
For C, one could use a single hash table mapping external names to their definitions, and
a simple stack of hash tables for dealing with nested blocks inside of functions.
 
Search WWH ::




Custom Search