Assignments

CS 132: Compiler Design
Spring 2001

All assignments are taken from the PROGRAM sections of Appel's book. The book refers to files in the directory $TIGER, which corresponds to the directory /cs/cs132/src/tiger on Turing.

Chapters 11 and 12

Get copies of all the files in $TIGER/chap11; these contain a complete implementation of the code for Chapter 10, which creates an interference graph for a sequence of assembly instructions (I hope).

Implement the Color and RegAlloc structures, as shown on Page 253 in Appel. Your code need not handle coalescing or spilling. \ Because of this, it may be easier to implement optimistic coloring from scratch --- based on the presentation given in class --- rather than trying to simplify the pseudocode in Chapter 11.

When you implement the simplify phase (picking an order to remove nodes from the interference graph) you should not actually modify the graph. (You'll need the original graph back for the actual coloring phase.) Instead, it should suffice to keep a list of the nodes not yet removed from the graph, and a mapping telling for each node in the graph how many of its neighbors have not yet been removed. There is an implementation of such lookup graphs in the structure Graph.Table.

There's very little left to do after the register allocator is working: finish up the procedure entry/exit routines as specified on pages 208 and 260--262. For procEntryExit3 you may assume that every function needs space in its stack frame for 6 outgoing arguments (i.e., that no function passes more than 6 arguments to its callees). Make Translate.procEntryExit call all these routines in sequence.

Note: For testing purposes, the function Translate.getResult should probably reset the list of fragments back to nil; otherwise fragments from one test can appear in the output of future tests.

Submit your code as chapter 12.

Chapter 9
Due April 4, 2001 [Firm]

Read Chapter 9, and get copies of canon.sml from $TIGER/chap8 and the files in $TIGER/chap9. This assignment has two parts: implementing the structure SparcGen (whose signature CODEGEN is given on page 207 of Appel), and extending the Frame signature and definition as specified on pages 208-209.

The function SparcFrame.string : Tree.label * string -> string is described on page 262 of Appel (see also the figure on page 260). It emits the SPARC assembly language to emit the given label and the given string in the SparcFrame.string. For this assignment, write a function that returns any string you want. (This will be fixed in a later assignment.)

The code in $TIGER/chap9/main.sml also assumes that your semant.sml has a function transProg which creates a new level for the main routine, invokes transExp, passes it to Translate.procEntryExit to make a fragment for the main program, and finally calls Translate.getResult.

Be careful with MOVE. Normally a T.TEMP or a T.MEM appearing in an expression stands for the value in the specified location. However, when it appears on the left-hand-side of a MOVE it is the location itself that is being referenced. So the right way to generate code for MOVE(e1,e2) is not to generate code that starts by computing the values of e1 and e2.

Chapter 7
Due March 28, 2001

First, make sure you have read Chapters 5, 6, and 7 in Appel. Copy the files from $TIGER/chap7, and plug in a working tiger.lex, tiger.grm, and a FindEscape module. (If you do not have a working FindEscape module, comment out the corresponding call in parse.sml). You may change any of the files however you like (e.g., rewrite code, change the definitions of types, etc.), but anything machine-specific should go in the sparcframe.sml file, and anything related to actual generation of intermediate-code should go in the translate.sml file.
  1. Implement the remaining parts of the PROGRAM section of chapter 6:

  2. Implement the remaining parts of the PROGRAM section of chapter 7:
Submit any files to which you have made changes.

Chapter 6
Due February 21, 2001

Implement the module FindEscape as discussed on pages 138--139 of the text. Your module must implement the function findEscape: Absyn.exp -> unit. However, the names and types of any helper functions you define need not exactly match Appel's suggestions.

When submitting your code, record this as assignment 6, not 5!

Chapter 4
Due February 14, 2001

Adapt your parser to return abstract syntax trees, as specified on pages 100-101 in Chapter 4. You will need the files in $TIGER/chap4. The text of the chapter contains some example abstract syntax that it might be helpful to look at.

Remember to group together adjacent type or function definitions into a single abstract syntax declaration.

You'll also need to change the %nonterm line to declare that the nonterminals now are returning interesting values rather than unit. For example, if you have a nonterminal exp then you'll need to say exp of Absyn.exp

Chapter 3
Due February 7, 2001

For reference you might want to look at the ML-Yacc documentation. However, it does not appear particularly helpful, so you should look closely at the examples in the book. (Be aware, however, the the book examples tend to be incomplete; every parser requires a %name, for example.)

Chapter 2
Due January 31, 2001

Carefully read the programming assignment on pages 31-32 of Appel, and implement the required lexer. You will need copies of the files from $TIGER/chap2. The given tiger.lex nearly empty, and will need a lot of work to fill in. It is suggested (though not required) that you proceed in the following order:
  1. Make sure you are familiar with Appendix A, the Tiger Language Reference Manual.
  2. Extend the lexer to handle keywords, punctuation, and whitespace.
  3. Extend the lexer to handle identifiers and integer constants. Remember that the string matched by the given regular expression is bound to the ML variable yytext.
  4. Extend the lexer to handle comments. To handle nesting of comments you will have to extend the approach on page 31 to count nesting depth (using a global counter) and changing states (i.e., calling YYBEGIN) only when appropriate. (Remember that that all states except INITIAL must be declared in the second (Lex-Definitions) portion of the input. The format is a line starting with %s and then a space-separated list of states terminated with a semicolon.) Detect unclosed comments.
  5. Extend the lexer to handle string literals. This is tricky because the lexer is required to return strings with all escape sequences have been expanded away.

    One method is to maintain a global buffer. The lexer can extend this buffer each time it recognizes a piece of the string and can call itself recursively via continue() to get the remaining pieces, until it reaches the end of the string. At this point the entire string can be returned. This technique requires adding at least one more state to the lexer.

    An alternate method is simply to match the entire string as a single token, and then write a separate translating function through which the lexer can pass the source text. This simplifies the lexer's organization, but requires you to implement your own code to detect escape sequences.

There are a number of sample Tiger files in $TIGER/samples to try once you believe your lexer is working, though you will likely need to create your own files for testing a partially-implemented lexer. Submit your code with the following command line: cs132submit tiger.lex

Chapter 1
Due January 24, 2001

Carefully read the programming assignment on pages 10-12 of Appel, and implement the required functions. This will involve extending a copy of the file $TIGER/chap1/slp.sml with the following definitions:
  1. The function maxargs : stm -> int.
  2. The type table.
  3. The functions lookup : table * id -> int and update : table * id * int -> table.
  4. The functions interpStm : stm * table -> table and interpExp : exp * table -> int * table
  5. .
  6. The function interp : stm -> unit.
Submit your code with the following command line: cs132submit slp.sml