Due Monday 9 Apr. 2001 11:59 PM.
For this project, you will write a Reverse Polish Notation (RPN) calculator that evaluates postfix expressions. The calculator will be written in Java and will emphasize a stack-like data structure, Java GUI construction (using the MVC Pattern), and stream I/O.
Consider the mathematical expression
Postfix calculations can be implemented in a very straightforward manner using a stack. As you get an operand, push it on the stack. As you get an operand, pop its arguments, do the operations, and push the result. The first operand of a binary operation is always the lower one on the stack (and the one entered first), so a binary operation is implemented with code like
second = pop(); first = pop(); push(first - second);
RPN is familiar to many students as how Hewlett-Packard calculators behave.
The calculate will also support two "roll" operations, as found on HP calculators. Rolling it "up" moves the top of the stack to the bottom, thus moving all other values up one place. Rolling it "down" similarly moves the bottom of the stack to the top. Observe that these operations break the strict stack behavior.
Instead of using a stack, you must implement a deque (or doubly-ended queue, pronounced like "deck"). A deque is like a queue, except that it supports enqueues and dequeues at each end. For the sake of convenience and familiarity, we continue to use the word "stack" in this assignment to refer to this deque.
The calculator will accept two kinds of input:
In "Expression mode", the user enters a postfix expression via a text file or keyboard. Upon entering the expression or pressing a button, the expression is evaluated. Any results are left on the stack.
In this mode, the GUI has four available operations:
In "Immediate mode", operands and operators are entered via buttons on a GUI, and an operation is performed immediately after each operator is entered.
In this mode, the GUI has a button for each of the arithmetic and stack operations listed below. It also has a button for each digit, a number's sign, a decimal point, and a button used to terminate a number. E.g., the number -98.5 can be entered via a six-button sequence of
- 9 8 . 5 ENTERAs on most calculators, it is simpler if this negation button is distinct from the subtraction button.
xcalc -rpn
which provides a GUI-based immediate mode RPN
calculator.
dc
which provides a keyboard-based RPN calculator with
both expression and immediate modes.
The calculator will work with floating point numbers.
Use the types double
and Double
.
The calculator will support the following operations and their keyboard syntax:
You must use the provided
IDeque
interface.
Arrays and CList
s are both natural candidates for
the underlying data structure.
The calculator will have a GUI interface for entering numbers and the above operations. It will also have a way to swap between expression and immediate mode, without changing the stack contents. In each mode, the irrelevant GUI features should be disabled. In expression mode, the user can type in an expression, load an expression from a text file, save an expression to a text file, or evaluate this expression. For simplicity, you may hard-wire into your program a single text filename for this. The top of stack (if any) is displayed at all times -- note that the top of stack only changes when an expression is evaluated, not while it is entered.
If you wish you may add extra elements to your program, but these won't be graded. E.g., to help you debug, you might want to display the top 2 or more elements of the stack at all times, instead of just the top 1 element.
This project is divided into two milestones. In the first milestone, you write the model. In the second milestone, you write the view and control.
Milestone #1: Due Monday, Apr. 2 at 11:59 PM.
Write a class RPNEngine
that implements
ICalculator
and uses or implements a IDeque
.
You may add more methods to ICalculator
if you are
adding more features.
We've provided
an example of printing a string to a file.
Use this as a guide for file I/O you need.
In particular, write a singleton class SaveStringToFile
that prints the given string to a file.
You'll also need a class LoadStringFromFile
.
Finish writing the class
FormStream
extending StreamTokenizer
that evaluates
an expression from the appropriate text field.
We have given the code for everything but the parse() function.
Evaluation is a loop, "parsing" all the "tokens" it encounters.
If the next token is a number, push it onto the RPNEngine;
if it is an operator, perform the operation.
FormStream()
takes in a Reader
and a RPNEngine
; the Reader
should be a
StringReader
for the appropriate text field.
E.g.,
FormStream myStream = new FormStream(new StringReader(theStringFromEntryBox), myRPNEngine); myStream.parse();
See the Java API for more details about
StreamTokenizer
, StringReader
, and such.
To recap, you need to write the following classes:
RPNEngine
, SaveStringToFile
LoadStringFromFile
, and FormStream
.
Turn in with project name rpn1
.
Milestone #2. Due Monday, Apr. 9 at 11:59 PM.
Write a Java GUI view and controller for the RPN calculator. You can use the provided GUI as an example, although it follows slightly different behavior specifications. Feel free to design your own layout as long as it meets the above specifications. We've provided some stub code. Use the State Pattern in the control to implement the two modes.
Turn in with project name rpn2
.