Task: Parsing_RPN calculator algorithm



C#: using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.Threading;

namespace RPNEvaluator
{
    class RPNEvaluator
    {
        static void Main(string[] args)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

            string rpn = "3 4 2 * 1 5 - 2 3 ^ ^ / +";
            Console.WriteLine("{0}\n", rpn);

            decimal result = CalculateRPN(rpn);
            Console.WriteLine("\nResult is {0}", result);
        }

        static decimal CalculateRPN(string rpn)
        {
            string[] rpnTokens = rpn.Split(' ');
            Stack<decimal> stack = new Stack<decimal>();
            decimal number = decimal.Zero;

            foreach (string token in rpnTokens)
            {
                if (decimal.TryParse(token, out number))
                {
                    stack.Push(number);
                }
                else
                {
                    switch (token)
                    {
                        case "^":
                        case "pow":
                            {
                                number = stack.Pop();
                                stack.Push((decimal)Math.Pow((double)stack.Pop(), (double)number));
                                break;
                            }
                        case "ln":
                            {
                                stack.Push((decimal)Math.Log((double)stack.Pop(), Math.E));
                                break;
                            }
                        case "sqrt":
                            {
                                stack.Push((decimal)Math.Sqrt((double)stack.Pop()));
                                break;
                            }
                        case "*":
                            {
                                stack.Push(stack.Pop() * stack.Pop());
                                break;
                            }
                        case "/":
                            {
                                number = stack.Pop();
                                stack.Push(stack.Pop() / number);
                                break;
                            }
                        case "+":
                            {
                                stack.Push(stack.Pop() + stack.Pop());
                                break;
                            }
                        case "-":
                            {
                                number = stack.Pop();
                                stack.Push(stack.Pop() - number);
                                break;
                            }
                        default:
                            Console.WriteLine("Error in CalculateRPN(string) Method!");
                            break;
                    }
                }
                PrintState(stack);
            }

            return stack.Pop();
        }

        static void PrintState(Stack<decimal> stack)
        {
            decimal[] arr = stack.ToArray();

            for (int i = arr.Length - 1; i >= 0; i--)
            {
                Console.Write("{0,-8:F3}", arr[i]);
            }
            
            Console.WriteLine();
        }
    }
}







COBOL:        IDENTIFICATION DIVISION.
       PROGRAM-ID. RPN.
       AUTHOR.  Bill Gunshannon.
       INSTALLATION.  
       DATE-WRITTEN.  9 Feb 2020.
      ************************************************************
      ** Program Abstract:
      **   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.
      ************************************************************
       
       DATA DIVISION.
       
       
       WORKING-STORAGE SECTION.
       
       01  LineIn               PIC X(25).
       01  IP                   PIC 99
                  VALUE 1.
       01  CInNum               PIC XXXX.

       01  Stack                PIC S999999V9999999
               OCCURS  50 times.
       01  SP                   PIC 99
                  VALUE 1.
       01  Operator             PIC X.
       01  Value1               PIC S999999V9999999.
       01  Value2               PIC S999999V9999999.
       01  Result               PIC S999999V9999999.
       01  Idx                  PIC 99.
       01  FormatNum            PIC ZZZZZZ9.9999999.
       01  Zip                  PIC X.
       
       PROCEDURE DIVISION.
       
       Main-Program.
            DISPLAY "Enter the RPN Equation: " 
                     WITH NO ADVANCING.
            ACCEPT LineIn.

            PERFORM UNTIL IP GREATER THAN 
                          FUNCTION STORED-CHAR-LENGTH(LineIn)


            UNSTRING LineIn DELIMITED BY SPACE INTO CInNum 
                    WITH POINTER IP

            MOVE CInNum TO Operator

            PERFORM Do-Operation

            PERFORM Show-Stack

            END-PERFORM.

            DISPLAY "End Result: " FormatNum

           STOP RUN.
       
       Do-Operation.

          EVALUATE Operator
          WHEN "+"
                        PERFORM Pop
                        Compute Result = Value2 + Value1
                        PERFORM Push

          WHEN "-"
                        PERFORM Pop
                        Compute Result = Value2 - Value1
                        PERFORM Push

          WHEN "*"
                        PERFORM Pop
                        Compute Result = Value2 * Value1
                        PERFORM Push

          WHEN "/"
                        PERFORM Pop
                        Compute Result = Value2 / Value1
                        PERFORM Push

          WHEN "^"
                        PERFORM Pop
                        Compute Result = Value2 ** Value1
                        PERFORM Push

          WHEN NUMERIC
                       MOVE Operator TO Result
                       PERFORM Push
          END-EVALUATE.


       Show-Stack.

              DISPLAY "STACK: " WITH NO ADVANCING.
              MOVE 1 TO Idx.
              PERFORM UNTIL (Idx = SP)
                      MOVE Stack(Idx) TO FormatNum
                      IF Stack(Idx) IS NEGATIVE
                         THEN
                              DISPLAY "    -" FUNCTION TRIM(FormatNum)
                                             WITH NO ADVANCING
                         ELSE
                              DISPLAY FormatNum WITH NO ADVANCING
                     END-IF
                      ADD 1 to Idx
              END-PERFORM.
                      DISPLAY " ".

       Push.

             MOVE Result TO Stack(SP)
             ADD 1 TO SP.

       Pop.

            SUBTRACT 1 FROM SP
            MOVE Stack(SP) TO Value1
            SUBTRACT 1 FROM SP
            MOVE Stack(SP) TO Value2.


       END-PROGRAM.