RPN Calculator with undo and redo

I have to follow the Command Pattern in making a reverse polish notation calculator in C++. It needs to do undo and redo. It's due tomorrow morning so I've been banging my head against the table everyday for the last two weeks even tho I know its probably very easy and I'm just over thinking it... specifically I'm having problems understanding how the operators / operands on a stack stored in main() can be accessed (ie. push answer from Calculator?) after calling the invoker (assume that I send the args from stacks in main to Invoker or ConcreteCommand or Command or Calculator), but in general just confused as to how the Invoker or Commands access the operators / operands and which classes are supposed to handle which functions? Im not asking anyone to do my HW but b/c I'm stuck I welcome any suggestions.. please and thank you!

I've posted the assignment here:

http://pastebin.com/ffbAEZex

I posted the code I created (w/some questions I'm having in notes) here:

http://pastebin.com/z7z1t02a
I would propose that you make Calculator have nothing but static methods (it does all the brunt work and doesn't really need to be instantiated). The Commands should use the Calculator's methods and the Invoker should have two stacks of Commands (the undo stack and the redo stack).

main() should instantiate the Invoker first, then as it parses the input it should give the Commands to the Invoker which would place them on the undo stack.

So, for the input 2 3 4 5 + + -:

First, see 4 5 + -> give the Command (+, 5, 4) to the Invoker
Next, see 3 (answer from before=9) + -> give the Command (+, 9, 3) to the Invoker
Finally, see 2 (answer from before=12) - -> give the Command (-, 12, 2) to the Invoker

To do the parsing: whenever you see an operand you push it onto a stack. Whenever you see an operator, you pop the stack twice to get the operands, do the operation, push the result onto the stack, and form a Command (which you will give to the Invoker) from the operator and operands.

After parsing the above, the Invoker should have the final answer (10) which you can query, as well as these Commands on the undo stack:

(-, 12, 2)
(+, 9, 3)
(+, 5, 4)

Or at least that's how much I've thought about it. You could store the results of the operations in the Commands themselves so that they can undo themselves easily (?) or maybe the Invoker can keep track of that. The Calculator should definitely not store the results as it should just be used to do the calculations.
Last edited on
The way these things are usually implemented is like this: the calculator has six operations: +, -, *, /, ^, and PUSH. PUSH is the only operation that's encoded with an operand (here, "operand" is being discussed on a meta level). For example, "1 2 + 3 *" translates to
PUSH 1
PUSH 2
+ (note how the encoding of the operation itself doesn't have an operand)
PUSH 3
*
Like this, you can easily treat literals ("1", "13") in the same way as operators ("+", "-"). They're just instructions that change the calculator's internal state; most importantly, the stack.

Now, this particular program has a quirk that makes the implementation trickier, which is the undo and redo part. For example. For "1 1 + 1 1 + +", you'd get an undo stack that looks like this:
(top) 4
2 2 +
2 1 1 + +
1 1 + 1 1 + +
Now, the way I'd do this is, I'd evaluate the expression eagerly and copy the remaining of the input into the stack. For example (I'll use ';' to represent the position of the read pointer):
Input: ; 1 1 + 1 1 + +
(Push "1 1 + 1 1 + +" onto the undo stack.)
Input: 1 1 + ; 1 1 + +
(Evaluate "1 1 +": 2)
(Push "2 "+"1 1 + +" onto the undo stack.)
Input: 1 1 + 1 1 + ; +
(Evaluate "1 1 +": 2)
(Push "2 "+"2 "+"+" onto the undo stack. The first "2" comes from the RPN stack.)
Input: 1 1 + 1 1 + + ;
(Evaluate "2 2 +": 4)
(Push "4 "+"" onto the undo stack. The first "2" comes from the RPN stack.)
Now the undo stack looks like this:
(top) 4
2 2 +
2 1 1 + +
1 1 + 1 1 + +
Of course, I used strings to make it easy to read, but you would push strings of operations, not strings of characters, into your stack.

I don't know if you'll be able to finish it by tomorrow. It's always a bad idea to wait until the last moment to ask if there's something you don't understand.
Topic archived. No new replies allowed.