I have a custom array used by a calculator, the array acts as an RPN stack. Many real life RPN calculators allow manipulation of the stack, and I am working on the same. To get an idea an example stack would be:
["1", "2", "+"] which would evaluate to 3. The core of it is the operations follow the operands.
["2", "1", "2", "+" "x"] evaluates to 6
["3.1415", "sin"] evaluates to 0
I would like to be able to "roll my stack" As in take the currently evaluated expression at the very end of the stack and roll it to the front. The problem is the operators, as the amount of binary and unary operators changes the way the stack is rotated.
["100", "1", "2", "+"]still would evaluate to 3, because 100 has not been accessed by an operator.
I need a way to recursively roll the stack, to take the last set of evaluated operands and roll it in front off all the operands yet to be evaluated.
Example:
["100", "1", "2", "+"] would roll to ["1", "2", "+", "100",] then ["100", "2", "1", "2", "+" "x"]would roll to ["2", "1", "2", "+" "x", "100"] and ["100", "3.1415", "sin"] would roll to ["3.1415", "sin","100"]
I am having problem with this, and the recursion of it. Currently I am doing this:
// safeRoll
func rollOpStack() {
var lastIndex = opStack.count - 1
var tmp: Op = opStack[lastIndex]
switch tmp {
case .UnaryOperation:
if opStack.count >= 2 {
var tmp2: Op = opStack[lastIndex - 1]
var appender: [Op] = [tmp2, tmp]
opStack.removeLast()
opStack.removeLast()
var appended: [Op] = appender + opStack
opStack = appended
}
case .BinaryOperation:
if opStack.count >= 3 {
var tmp2: Op = opStack[lastIndex - 1]
var tmp3: Op = opStack[lastIndex - 2]
var appender: [Op] = [tmp3, tmp2, tmp]
opStack.removeLast()
opStack.removeLast()
opStack.removeLast()
var appended: [Op] = appender + opStack
opStack = appended
}
default:
if opStack.count > 0 {
opStack.removeLast()
println(opStack)
opStack.insert(tmp, atIndex: 0)
}
}
}
This works... until more binary or unary operators are applied than just one, because the function is not recursive. How can I roll the stack recursively, and ensure that the entirety of the last evaluated list is rolled to the front of the stack? Thanks for the help.
rollOpStackinstead of reading from an instance variable. HaverollOpStackcall itself with the next layer of the stack.