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();
        }
    }
}








Fortran:       REAL FUNCTION EVALRP(TEXT)	
Caution: deals with single digits only.
       CHARACTER*(*) TEXT	
       INTEGER SP,STACKLIMIT		
       PARAMETER (STACKLIMIT = 6)	
       REAL*8 STACK(STACKLIMIT)		
       INTEGER L,D		
       CHARACTER*4 DEED		
       CHARACTER*1 C		
        WRITE (6,1) TEXT	
    1   FORMAT ("Evaluation of the Reverse Polish string ",A,//	
     1   "Char Token Action  SP:Stack...")	
        SP = 0			
        STACK = -666		
        DO L = 1,LEN(TEXT)	
          C = TEXT(L:L)			
          IF (C.LE." ") CYCLE		
          D = ICHAR(C) - ICHAR("0")	
          IF (D.GE.0 .AND. D.LE.9) THEN	
            DEED = "Load"			
            SP = SP + 1				
            IF (SP.GT.STACKLIMIT) STOP "Stack overflow
            STACK(SP) = D			
           ELSE				
            IF (SP.LT.2) STOP "Stack underflow
            DEED = "XEQ"		
            SELECT CASE(C)		
             CASE("+"); STACK(SP - 1) = STACK(SP - 1) + STACK(SP)	
             CASE("-"); STACK(SP - 1) = STACK(SP - 1) - STACK(SP)	
             CASE("*"); STACK(SP - 1) = STACK(SP - 1)*STACK(SP)		
             CASE("/"); STACK(SP - 1) = STACK(SP - 1)/STACK(SP)		
             CASE("^"); STACK(SP - 1) = STACK(SP - 1)**STACK(SP)	
             CASE DEFAULT		
              STOP "Unknown operator
            END SELECT			
            SP = SP - 1		
          END IF		
          WRITE (6,2) L,C,DEED,SP,STACK(1:SP)	
    2     FORMAT (I4,A6,A7,I4,":",66F14.6)	
        END DO			
        EVALRP = STACK(1)	
      END	

      PROGRAM HSILOP
      REAL V
      V = EVALRP("3 4 2 * 1 5 - 2 3 ^ ^ / +")	
      WRITE (6,*) "Result is...",V
      END