MCS-388 Lab 6: Wildcard Lab (Spring 2006)
Due: May 17, 2006
For this lab, you are free to choose your own objective(s), selecting
those that you think would be most educational and interesting.
I list below some example objectives. You are welcome to choose from
among them, or to come up with other ideas of your own. Particularly
if you come up with other ideas of your own, it would be wise to
discuss them with me in advance, to get a second opinion regarding
whether the degree of ambitiousness is appropriate.
If you choose a relatively ambitious objective, a single objective
should be sufficient to generate a piece of work worthy of being
called an MCS-388 lab report. If you stick with small, incremental
objectives, you may need to assemble a few of them together to make a
lab's worth. If you are unsure whether the scope of what you are
undertaking is appropriate, talk with me. I would also be happy to
talk with you as you work through any of these that you choose.
Checking for uses of potentially uninitialized variables
Using data-flow analysis to do optimizing transformations is perhaps
over-ambitious, but using data-flow analysis to provide warning or
error messages is comparatively straightforward. You could, for
example, do a structured live-variable analysis to discover those
non-parameter local variables that are live at the start of a
procedure, and report them as being used while potentially
By modifying your AST classes, you can implement a number of simple
optimizations. Many of these would be best done through a
transformation pass over the AST prior to the code generation:
- constant folding
- use of immediate operands
- algebraic identities
- use of the $zero register
- targeting computations directly into the destination register
- simplifying control-flow statements with constant tests
- any others you notice
Leftovers from prior labs
If there is anything interesting you didn't get around to in a prior
lab, you could do it now.
Adding another basic type
You could add
float as an alternative to
and do the appropriate type checking, introduction of conversion
operations, and emission of correct code for the overloaded operators
on each type.
There are lots of possible variations on this, such as:
I would suggest you start simple.
- one-dimensional vs. multi-dimensional
- local vs. global
- size must be a constant vs. size must be a constant expression
vs. size can be any expression
- passing by reference vs. by copying vs. not at all
Improved error handling
The reporting and recovery from syntactic errors is currently rather
primitive in most of your compilers. You could improve this.
Overcoming implementation restrictions
Right now, procedures can only take four arguments, can have a limited
number of local variables, and can have bodies of only limited
complexity. You could relax one or more of these restrictions. For
example, you could pass additional arguments on the stack, or could
use the stack frame for additional local variables or temporaries.
You could add the boolean operators
!. For the first two, you'll
probably want to do "short-circuit" evaluation, like in the C family
of languages. That is, depending on the value of the left-hand
operand of a
||, it may not be
necessary to evaluate the right-hand operand at all.
Other language features
What is your favorite language feature that is missing? Do you long
for fancier control flow structures? Assignment operators like
+= in C? Call by value-result? Multiple assignment?
Whatever you miss, you are welcome to add!
Instructor: Max Hailperin <email@example.com>