# Comp 212 Spring 2001, Project 2: RPN Calculator

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.

## Overview of RPN (postfix) evaluation

Consider the mathematical expression

(5 + 3) * 2 - 9
This is called infix notation, because the operators are inbetween the operands. Because of precedence, we are sometimes forced to group subexpressions with parentheses. Alternatively, we can write the same calculation, placing the operators after the operands:
5 3 + 2 * 9 -
Note that parentheses are no longer needed; this is always the case. (Another benefit of postfix over infix is that it easily handles operands with more than two arguments. This however won't be important for this project.)

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.

## Roll operations

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.

## Specifications

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:

• load an expression from a file into a text field,
• save an expression in the text field into a file,
• evaluate the expression in the text field, and
• modify the expression in the text field via the keyboard.

• 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  ENTER
```
As on most calculators, it is simpler if this negation button is distinct from the subtraction button.

For the sake of comparison, you can look at the UNIX programs
• `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:

• +, -, *, / are all the standard binary operations. It is an error if there are fewer than two items on the stack.
• c clears the stack, i.e., pops all values from the stack.
• p pops and discards the top element of the stack.
• r rolls the stack up one position.
• R rolls the stack down one position.

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.

## Milestones

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`.