Task

Create a stack-based evaluator for an expression in   reverse Polish notation (RPN)   that also shows the changes in the stack as each individual token is processed as a table.



 Assume an input of a correct, space separated, string of tokens of an RPN expression
 Test with the RPN expression generated from the   Parsing/Shunting-yard algorithm   task: 

         3 4 2 * 1 5 - 2 3 ^ ^ / + 

 Print or display the output here


Notes

    ^    means exponentiation in the expression above.
    /    means division.


See also

   Parsing/Shunting-yard algorithm for a method of generating an RPN from an infix expression.
   Several solutions to 24 game/Solve make use of RPN evaluators (although tracing how they work is not a part of that task).
   Parsing/RPN to infix conversion.
   Arithmetic evaluation.


 
use IO;
use Struct;
 
bundle Default {
  class RpnCalc {
    function : Main(args : String[]) ~ Nil {
      Caculate("3 4 2 * 1 5 - 2 3 ^ ^ / +");
    }
 
    function : native : Caculate(rpn : String) ~ Nil {
      rpn->PrintLine();
 
      tokens := rpn->Split(" ");
      stack := FloatVector->New();
      each(i : tokens) {
        token := tokens[i]->Trim();
        if(token->Size() > 0) {
          if(token->Get(0)->IsDigit()) {
            stack->AddBack(token->ToFloat());
          }
          else {
            right := stack->Get(stack->Size() - 1); stack->RemoveBack();
            left := stack->Get(stack->Size() - 1); stack->RemoveBack();
            select(token->Get(0)) {
              label '+': {
                stack->AddBack(left + right);
              }
 
              label '-': {
                stack->AddBack(left - right);
              }
 
              label '*': {
                stack->AddBack(left * right);
              }
 
              label '/': {
                stack->AddBack(left / right);
              }
 
              label '^': {
                stack->AddBack(right->Power(left));
              }
            };
          };  
          PrintStack(stack);
        };
      };
      Console->Print("result: ")->PrintLine(stack->Get(0));
    }
 
    function : PrintStack(stack : FloatVector) ~ Nil {
      "  ["->Print();
      each(i : stack) {
        stack->Get(i)->Print();
        if(i + 1< stack->Size()) {
          ", "->Print();
        };
      };
      ']'->PrintLine();
    }
  }
}
 