MCS-178: Introduction to Computer Science II
In this project you will be working with a Java version of the shift-reduce evaluator from Section 13.2 of Concrete Abstractions. Your primary objective is to add one additional feature to the evaluator: the use of exclamation point as a factorial operation. You will work individually.
On the first lab day, I will show you how to open the project up in the BlueJ system, which is a Java programming environment. I will demonstrate how you can interact with the existing code in BlueJ, and I will show and explain some portions of the code. My expectation is that this will pretty well occupy the first day, without your necessarily having any time to start your own work.
As I will demonstrate, to make your own copy of the project and open it up in BlueJ, the steps are as follows:
Download the file evaluate.jar from this web page. You may need to specifically tell your web browser to save this file to disk rather than opening it. This file contains the whole project, all packaged together in one compressed file.
Run BlueJ. You can either find it from your computer's main menu (probably in a submenu called "MCS"), or you can type bluej in a terminal window (also known as a shell).
Within BlueJ, go into the Project menu and select "Open Non BlueJ...". From the file browser window that opens, select the evaluate.jar file. This should open up a new project window. As a side-effect, it also unpacks the contents of evaluate.jar into a directory called evaluate. In the future, when you run BlueJ it can directly open the project from this directory, without needing to go through these three steps.
Before the second lab day, you should have turned in Exercise 13.28 on pages 478-479 as a homework problem. This problem concerns the addition of the factorial operation to the evaluator, at the conceptual level of adding it to the table, rather than at the detailed level of adding it to the Java code. Because this will serve as the foundation of your work, you should bring a copy of it with you to lab.
One item you may specifically want to check, because I
have frequently seen students get it wrong, is that you correctly
handle factorials of factorials, such as "3!!"
. I would
be happy to talk with you about your design, if you don't want to
progress into the Java coding without some confirmation of your design
work.
Also, if you are for some reason held up on this homework problem, the first two sections of coding can be done without any real dependence on it.
Add a procedure to the Evaluate class (as a public
static
method) which takes an integer argument (that is, a
value of type int
) and returns its factorial (which
should again be of type int
). For now, you can assume
that the argument is nonnegative and small enough that its factorial
can be represented as an int
. (Extra credit problems address
these issues.) You will receive partial credit if you have a working
procedure that calls itself recursively (as a Scheme version normally
would). For full credit, you need to write a version that uses a
while
or for
loop to carry out an iteration.
Be sure to test your procedure on its own, using BlueJ.
Values on the evaluator's stack are stored as Strings. This
explains why the procedure operateInts
for carrying out
arithmetic operations is accompanied by a wrapper procedure
operate
that converts the operands from Strings to ints
and converts the result back into a String. You will need to provide
a similar wrapper for your factorial procedure, unless you want to do
the type conversions inside the factorial procedure itself or inside
the reduce
procedure.
Modify the reduce
procedure, which corresponds to the
Scheme procedure reduce!
, so as to perform the
appropriate kind of reduction if the top of the stack contains an
exclamation point and a number. This should make use of your
procedure for computing factorials. You should test your modified
reduce
procedure in BlueJ, after manually pushing
appropriate strings onto the exprStack
.
Your table from Exercise 13.28 needs to be translated into Java.
Make the appropriate additions to the isReduce
and
isShift
procedures, which are the Java equivalents of the
Scheme procedures reduce?
and shift?
. Be
sure to test your modified procedures on their own, using BlueJ, to
verify that they correspond to your table.
At this point, you should have all the pieces in place to test evaluating expressions that contain exclamation points. Do so.
You can do any of these, or more than one if you like. They are mostly independent of each other, though there is some interaction between the second and third.
The program is currently light on error checking. Change your
factorial procedure so that it throw
s an
Error
if asked to compute the factorial of a negative
number. Also, the RAStack class has one error check already in place,
but really should have another one as well. Find that second place
and introduce the error check.
If you take the factorial of a reasonably large integer, you'll
find that the result is incorrect because the correct answer wouldn't
fit in the number of bits available for an int
. (You
encountered this same issue in SLIME.) You can fix this by using the
BigInteger class from the Java API.
Because large integers can arise even without factorials, you
shouldn't limit yourself just to factorials: you should use
BigIntegers consistently throughout the whole evaluator.
What happens if you evaluate an expression like "7/2"
?
Explain why. Design and program a modification to the evaluator so
that it will provide more precise answers in cases like this.
You should write a report that uses your table from Exercise 13.28 as the focal point for explaining your modifications to the evaluator. Your target audience should be people who are familiar with the original evaluator but who don't know what feature you were adding or how you were doing so.
Your report should include the code for all modified or newly added procedures. However, don't include any procedures that are left unchanged.
You need not comment upon testing unless there is some bug that you found in the course of testing but were unable to fix. In that case, it is important for you to report what you found to be not working. Otherwise, you will lose double points: one loss of points for the programming difficulty, and another for (apparently) not having done adequate enough testing to uncover the existence of the bug.
If you take any of the extra credit opportunities, be sure to specifically mention them in your report, rather than relying on me to spot them in your code.
The gradesheet shows how the report will be graded.