Programming assignments 2 through 5 will direct you to design and build an interpreter for Cool. Each assignment will cover one component of the interpreter: lexical analysis, parsing, semantic analysis, and operational semantics. Each assignment will ultimately result in a working interpreter phase which can interface with the other phases.

We will not be completing P4 this semester. However, the information below about the CL-Type format is important and needed for P5.

The .cl-type File Format

If there are no errors in file.cl-ast your program should create file.cl-type and serialize the class map, implementation map, parent map, and annotated AST to it.

The class and implementation maps are described in the Cool Reference Manual.

A .cl-type file consists of four sections:

  1. The class map.
  2. The implementation map.
  3. The parent map.
  4. The annotated AST.

Simply output the four sections in order, one after the other.

We will now describe exactly what to output for the class and implementation maps. The general idea and notation (one string per line, recursive descent) are the same as in P3.

Example input:

class Main inherits IO {
  my_attribute : Int <- 5 ; 
  main() : Object { 
    out_string("Hello, world.\n") 
  } ;
} ;	
Example .cl-type class map output with comments:
class_map	
6               -- number of classes
Bool            -- note: includes predefined base classes
0   
IO  
0   
Int 
0   
Main    
1               -- our Main has 1 attribute
initializer 
my_attribute    -- named "my_attribute"
Int             -- with type Int

2 -- initializer expression line number Int -- initializer expression type (see above: this is an expression annotated with a type) -- do not emit these expression type annotations for the P4c Checkpoint! integer -- initializer expression kind 5 -- which integer constant is it?

Object 0 String 0
Example .cl-type implementation map output with comments:
implementation_map  
6               -- six classes
Bool            -- first is Bool
3               -- it has three methods
abort           -- first is abort()
0               -- abort has 0 formal arguments
Object          -- name of parent class from which Bool inherits abort()

0 -- abort's body expression starts on line 0 Object -- abort's body expression has type Object internal -- abort's body is an internal kind of expression (i.e., a system call; see above) Object.abort -- extra detail on abort's body expression

copy -- second of Bool's three methods is copy() 0 -- copy has 0 formal arguments Object -- name of parent class from which Bool inherits copy()

0 -- copy's body expression starts on line 0 SELF_TYPE -- copy's body expression has type SELF_TYPE internal -- copy's body is an internal kind of expression (i.e., a system call; see above) Object.copy -- extra detail on copy's body expression

... many lines skipped ...

Main -- another class is Main 8 -- it has 8 methods

... many lines skipped ...

main -- one of Main's methods is main() 0 -- main has 0 formal arguments Main -- the name of the class where Main.main() is defined

4 -- the body expression of Main.main starts on line 4 SELF_TYPE -- the body expression of Main.main has type SELF_TYPE self_dispatch -- the body of Main.main() is a self_dispatch kind of expression

... many lines skipped ...

Example .cl-type parent output with comments:
parent_map  
5               -- there are five classes with parents (Object is the sixth class)
Bool            -- Bool's parent ...
Object          -- ... is Object.
IO              -- IO's parent ...
Object          -- ... is Object.
Int             -- Int's parent ...
Object          -- ... is Object.
Main            -- Main's parent ...
IO              -- ... is IO.
String          -- String's parent ...
Object          -- ... is Object.