Skip to content

Latest commit

 

History

History

ps3-georgewu-zurawicki

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Your job for this assignment is to implement a compiler that maps Cish
source code down to MIPS assembly.  Cish is quite similar to Fish
except that it adds functions, function calls, and local variables.

A Cish program is a list of functions.  Each function is of the form

  var(var1,...,varn) { stmt_list }

mimicking functions in C.  Here, var is the name of the function and
var1,...,varn are the formal parameters of the functions.  The {
stmt_list } is a statement which should return an integer value to the
caller.  The distinguished function main is used to launch the
program.  For Cish, main should take no arguments.

To statements, we have added a new form:

   stmt ::= ... | let var = exp; stmt

The intention is that this evaluates the expression exp, then declares
a new, locally-scoped variables var, and assigns the value of exp to
var as its initial value.  The scope of var extends across the
adjacent statement, and becomes unavailable outside.

To expressions, we have added a new form var(exp1,...,expn) which
represents a function call.  Here, var is the name of the function.

The file test.cish contains a sample program but you'll obviously want
to create more.

I've provided the abstract syntax, lexer, parser, and updated
interpreter.  You have to provide the compiler.  You'll want to follow
the MIPS standard calling convention (see the MIPS manual and lecture
notes for details) except that you do not need to worry about keeping
the stack-pointer double-word aligned.  In particular, when calling a
function, make sure to save any caller-saves registers that you need
preserved across the call, and within a function, make sure to save
any caller-saves registers used by the function.

A simple strategy for compilation is to keep an environment around
that maps variables (including formal parameters and local variables)
to integer offsets relative to the frame-pointer.  One option is to
make a pass over the code and determine how many distinct variables
and where they will live before compiling the code.  After this pass,
you will be able to generate the prologue and epilogue.  Another
strategy is to "push" locally-defined variables on the stack and "pop"
them off as you encounter them.  Regardless, you'll need to keep track
of where each variable lives relative to either the stack or the frame
pointer.

I would suggest pushing temporary values on the stack and popping them
off instead of trying to do something fancier (as sketched in the
class notes.)  Get this working first before you move on to something
more sophisticated!

Finally, to help in debugging, you might want to write some
assembly-language functions as wrappers for the system calls that
print integers and strings.  Then you could just "call" these
functions to get some output.  See section A-44 of the spim manual for
details.

Running make in the current directory generates an exectuable ps4, which
expects a file to compile.