PA5
Folders and files
Name | Name | 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.