7. Types
The structure of a type in mjava is represented by a type expression defined as: ˇ a basic type ( integer, floating, character, boolean, void, error ) ˇ the expression formed by applying a type constructor (name, array, product, method, constructor, reference ) to a type expression. Types are implemented by the class hierarchy in package type : the superclass Type in Typejava, declares a field (tag) corresponding to either a basic type or a type constructor, and a field (width) containing the number of bytes required to store variables of that type. Each type constructor is implemented by a corresponding subclass of Type defined, respectively, in Name.java, Array.java, Product.java, Method.java, Constructor.java, and Reference. java. Type expressions are strings formed by: ˇ just a tag (for basic types) ˇ the tag of a type constructor followed by the type expression to which it applies (for constructed types). In order to efficiently check type equivalence, we maintain a dictionary of the types declared in a source program by means of the HashMap table in class Type : entries in the dictionary are key-value pairs where the key is a type expression and the value is the corresponding Type object. When a type is encountered in the source program, its type expression is searched for in the dictionary: if present, the corresponding Type object is retrieved and used, otherwise a new Type object is created and a new entry is added to the dictionary. In this way two types are equivalent if and only if they are represented by the same Type object.
To complete the construction of symbol tables, we have to specify the information we want to collect about identifiers in the class Symb. In Symb.java we have declared the following fields: ˇ a reference (type) to a Type object ˇ a reference (ownerClass) to the Name object of the class where the identifier is declared ˇ a boolean value (pub), indicating whether the identifier is public or private.
In order to admit forward references, it is necessary to postpone type checking until all the identifiers have been inserted into the symbol table, and therefore to organize the front end in two passes: the first one to create the symbol table, the second one to perform type checking and intermediate code generation. The front end for mjava specified in mjava.cup implements two passes by reading and processing the source file two times . The static variables parser.first and parser.second indicate the current pass. In the second pass the parser moves through the chains of symbol tables, following the same path followed in the first pass. This behavior is obtained by saving, in the first pass, the current (top) environment into the ArrayList newEnvs (in class Env ) anytime it is going to be changed by push and pop operations. In the second pass the sequence of environments saved in newEnvs is restored by invoking method next of class Env in Env.java, in place of push and pop.
You can generate the parser and run it on the input program SampleProgram.mjava by means of mjava.bat or mjava.spt (the type package should be stored in a subdirectory named type). The output reported in TypesResult.txt will be printed on the Java console.
|