Skip to content

Latest commit

 

History

History

PA5

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
README file for Programming Assignment 5  (C++ edition)
=======================================================

Your directory should now contain the following files:

 Makefile
 README
 ast-lex.cc	      -> [cool root]/src/PA5/ast-lex.cc
 ast-parse.cc	      -> [cool root]/src/PA5/ast-parse.cc
 cgen-phase.cc	      -> [cool root]/src/PA5/cgen-phase.cc
 cgen.cc
 cgen.h
 cgen_supp.cc
 cool-tree.cc	      -> [cool root]/src/PA5/cool-tree.cc
 cool-tree.handcode.h
 dumptype.cc	      -> [cool root]/src/PA5/dumptype.cc
 emit.h
 example.cl
 handle_flags.cc      -> [cool root]/src/PA5/handle_flags.cc
 mycoolc	      -> [cool root]/src/PA5/mycoolc*
 stringtab.cc	      -> [cool root]/src/PA5/stringtab.cc
 tree.cc	      -> [cool root]/src/PA5/tree.cc
 utilities.cc	      -> [cool root]/src/PA5/utilities.cc
 *.d

The include (.h) files for this assignment can be found in 
[cool root]/include/PA5

	The Makefile contains targets for compiling and running your
	program, as well as handing it in. DO NOT MODIFY.

	The README contains this info. Part of the assignment is to
	fill the README with the write-up for your project. You should
	explain design decisions, explain why your code is correct,
	and why your test cases are adequate. It is part of the
	assignment to clearly and concisely explain things in text as
	well as to comment your code. Just edit this file.

	In example.cl you should write a correct Cool program which
	tests as many aspects of the code generator as possible. It
	should pass your code generator, and running spim on the
	generated output should run the program correctly.

	cgen.cc is the skeleton file for the code generator. This
	skeleton is much larger than the ones for previous
	assignments.  The skeleton provides three components of the
	code generator:

		- functions to build the inheritance graph; (we supply
		  this in case you didn't get this working for PA4)

		- functions to emit global data and constants;
		 
		- functions to emit spim instructions; (we supply
		  these last two to save you some tedious coding)

	You should work to understand this code, and it will help you
        write the rest of the code generator.

	cgen.h is the header file for the code generator. Feel free to
	add anything you need.

	cgen_supp.cc is general support code for the code generator.
	You can add functions as you see fit, but do not modify the 3
	functions:

		o byte_mode
		o ascii_mode
		o emit_string_constant

	emit.h defines a bunch of macros which should come in handy
	when you actually want to emit code. Feel free to change
	anything here to suit your needs.

        cgen-phase.cc supplies the driver for the compiler. You should
        not modify this code.  The script mycoolc can pass any of the
        standard flags to the code generator; for this assignment, -c
        (code generator debug) may be useful as it sets a global
        variable cgen_debug to true (1).  If you want your code
        generator to print debug information when the option is set,
        write your debug code in the following format:

	      if (cgen_debug)
	      {
		...
	      }

	symtab.h contains a symbol table implementation. You may
        modify this file if you'd like.  To do so, remove the link and
        copy `[course dir]/include/PA5/symtab.h' to your local
        directory.

	cool.h contains definitions that are used by almost all parts
	of the compiler. DO NOT MODIFY.

        tree.h contains the base class `tree_node' of the AST nodes.

        cool-tree.cc, cool-tree.h, and cool-tree.handcode.h contain
        the declarations and definitions of code generation AST nodes.
        You may add fields as you wish, but you shouldn't modify any
        of the methods already there except `code', which you may
        modify or remove as you wish.  Note that cool-tree.handcode.h
        is different from the same file in PA4---this file contains
        function definitions needed for the cgen.cc skeleton.  You may
        modify cool-tree.h or cool-tree.handcode.h, but don't modify
        cool-tree.cc.  Place all method definitions in cgen.cc

	stringtab.h contains functions to manipulate the string table.
	DO NOT MODIFY.

	dumptype.cc contains functions for printing out an abstract
	syntax tree.  DO NOT MODIFY.

        *.d dependency files, generated automatically by the makefile.

Instructions
------------

	To compile your compiler and code generator type:

	% gmake cgen

	To test your compiler, type:

	% ./mycoolc [-o output filename] <file1.cl> <file2.cl> ...

	This command parses all the cool files given on the command
	line, passes them through the semantic checker, and then hands
	the program AST to your code generator.

	To run your compiler on the file example.cl, type:

	% gmake dotest

	To run the produced code:

	% [cool root]/bin/spim -file file1.s
      /* or the output filename you chose */
	
	If you change architectures you must issue

	% gmake clean

	when you switch from one type of machine to the other.  If at
	some point you get weird errors from the linker, you probably
	forgot this step.

	GOOD LUCK!

---8<------8<------8<------8<---cut here---8<------8<------8<------8<---

Write-up for PA5
----------------

The code generator basically takes the AST and generates code for it.
It does this by traversing the AST and emitting code for each node.
First all the metadata needed for the code generation is generated,
then the code is generated. 

The object layout describes the location of attributes, as follows:
	Class tag
	Object size
	Dispatch pointer
	Attributes
So the condegenerator traverses the AST and finds all the constants that
need to be emitted, and emits them.

Then the actual code is printed into the output file.

Edited files
	cgen.cc
		Contains all the code for the code generator and fuctions for
		emit MIPS code.

	cgen.h
		Contains all the method declaration.

	cool-tree.h
		add method declerations to the following classes
			method_class
				IsMethod()
				code(ostream& stream, CgenNode* class_node)
				GetArgNum()
			static_dispatch_class
				GetActuals()
			typecase_class
				GetCases()

	cool-tree.handcode.h
		add class Environment

	Makefile
		-std=c++11

1. Emit code for global constants
----------------------------------

CgenClassTable::code_global_data()

		Define global names as follows

			.globl  class_nameTab
			.globl  Main_protObj
			.globl  Int_protObj
			.globl  String_protObj
			.globl  bool_const0
			.globl  bool_const1
			.globl  _int_tag
			.globl  _bool_tag
			.globl  _string_tag
		
		The tag of the Int, String, and Bool classes.

		_int_tag:
				.word   2
		_bool_tag:
				.word   3
		_string_tag:
				.word   4
		
		Then metadata for the string, int , and boolean constants are emitted

			The cgen generates a string object for every string structured 
			as follows

				str_constn:
					.word	class tag (4)
					.word	object size
					.word	String_dispTab
					.word	string length (int constant)
					.ascii	string constant
					.byte	0	
					.align	2
			
			Generates an int object for every int definition as structured 
			as follows
				int_constn:
					.word	class tag (2)
					.word	object size (4)
					.word	Int_dispTab
					.word	integer value

			The boolean 0 and 1 objects are defined as follows

			bool_const0:
				.word	class tag (3)
				.word	object size (4)
				.word	Bool_dispTab
				.word	0
				
			bool_const1:
				.word	class tag (3)
				.word	object size (4)
				.word	Bool_dispTab
				.word	1

------------------------------------------
Global Tables
------------------------------------------

	Class Name Table

		code_class_nameTab()
		The class name table is a global table that contains all the class names

			class_nameTab:
					.word   str_const7

	Class object table

		code_class_objTab()
		Contains the class object for every class in the program.

			class_objTab:
				.word   Object_protObj
				.word   Object_init
				.word   IO_protObj
				.word   IO_init
				.word   Int_protObj
				.word   Int_init
				.word   Bool_protObj
				.word   Bool_init
				.word   String_protObj
				.word   String_init
				.word   List_protObj
				.word   List_init
				.word   Cons_protObj
				.word   Cons_init
				.word   Nil_protObj
				.word   Nil_init
				.word   Main_protObj
				.word   Main_init

	Coding dispatch tables

		code_dispatch_table()
		All the metadata associated with each object and all the location data
		is described in the dispatch tables.

		For each and ever class node a dispatch table is printed and 
		it contains some methods related to each class. Always the 
		first three methods are Object.abort, Object.type_name, and Object.copy.

	Prototype Objects

		code_prototype_objects()
		Generates a prototype object definition for every class node.
		The structure of the prototype object is as follows

		class_protObj:
			.word	class tag
			.word	size
			.word	class_dispTab
			.word	str_constant50
			.word	int_constant61
		
------------------------------------------
Emit code for initialization mehod of each class
------------------------------------------

For every class in class node, the codes are initialized.

	<ClassName>_init:
		# push fp, s0, ra
		addiu   $sp $sp -12
		sw      $fp 12($sp)
		sw      $s0 8($sp)
		sw      $ra 4($sp)

		# fp now points to the return addr in stack
		addiu   $fp $sp 4

		# move the value in the accumilator to the self register
		move    $s0 $a0

		# Link to the parent if there is a one
		jal     Object_init

		# load each attribute to a0 and save them the register with
		a fixed offset
		la	$a0 int_const10
		sw	$a0 offset($s0)

		# ret = SELF
		move    $a0 $s0

		# pop fp, s0, ra
		lw      $fp 12($sp)
		lw      $s0 8($sp)
		lw      $ra 4($sp)
		addiu   $sp $sp 12

		# return
		jr      $ra

------------------------------------------
Emit code for methods of each methods
------------------------------------------

	class.method:
			# push fp, s0, ra
			addiu   $sp $sp -12
			sw      $fp 12($sp)
			sw      $s0 8($sp)
			sw      $ra 4($sp)

			# fp now points to the return addr in stack
			addiu   $fp $sp 4

			# SELF = a0
			move    $s0 $a0

			# evaluating expression and put it to ACC
			
			- pop fp, s0, ra from stack
				lw	$fp 12($sp)
				lw	$s0 8($sp)
				lw	$ra 4($sp)
				addiu	$sp $sp 12

			- pop arguments from the stack

			- jump to return address
				jr	$ra

------------------------------------------
Error handling
------------------------------------------

Runtime errors will terminate the programme.

dispatch abort
	Called when a dispatch is attempted on a void object. Prints the line
	number, from $t1, and filename, from $a0, at which the dispatch
	occurred, and aborts.

case abort 
	Should be called when a case statement has no match.
	The class name of the object in $a0 is printed, and execution halts.

case abort2 
	Called when a case is attempted on a void object. Prints the line
	number, from $t1, and filename, from $a0, at which the dispatch
	occurred, and aborts.