(de leftAssoc (Op)
   (member Op '("*" "/" "+" "-")) )

(de precedence (Op)
   (case Op
      ("\^" 4)
      (("*" "/") 3)
      (("+" "-") 2) ) )

(de rpnToInfix (Str)
   (let Stack NIL
      (prinl "Token  Stack")
      (for Token (str Str "_")
         (cond
            ((num? Token) (push 'Stack (cons 9 @)))  # Highest precedence
            ((not (cdr Stack)) (quit "Stack empty"))
            (T
               (let (X (pop 'Stack)  P (precedence Token))
                  (set Stack
                     (cons P
                        (pack
                           (if ((if (leftAssoc Token) < <=) (caar Stack) P)
                              (pack "(" (cdar Stack) ")")
                              (cdar Stack) )
                           " " Token " "
                           (if ((if (leftAssoc Token) <= <) (car X) P)
                              (pack "(" (cdr X) ")")
                              (cdr X) ) ) ) ) ) ) )
         (prin Token)
         (space 6)
         (println Stack) )
      (prog1 (cdr (pop 'Stack))
         (and Stack (quit "Garbage remained on stack")) ) ) )


/* Uses a push-down pop-up stack for the stack (instead of array) */
cvt: procedure options (main);                /* 10 Sept. 2012 */
   declare (true initial ('1'b), false initial ('0'b) ) bit (1);
   declare list character (1) controlled, written bit (1) controlled;
   declare (RPN, out) character (100) varying;
   declare s character (1);
   declare input_priority (5) fixed (1) static initial (1, 1, 2, 2, 3);
   declare stack_priority (5) fixed (1) static initial (1, 1, 2, 2, 4);
   declare (i, ki, kl) fixed binary;

   put ('Convert a Reverse Polish expression to orthodox.');
   put skip list ('Enclose the expression in apostrophes:');
   get list (RPN);
   put skip list ('The original Reverse Polish expression = ' || RPN);
   out = '';

   allocate list, written;
   list = substr(RPN, length(RPN), 1); written = false;

translation:
   do i = length (RPN)-1 to 1 by -1;
      s = substr(RPN, i, 1);
      if s = ' ' then iterate;
      ki = index('+-*/^', s);
      kl = index('+-*/^', list);
      if ki > 0 then /* we have an operator */
         do;
            if input_priority (ki) < stack_priority (kl) then
               do; /* transfer ')' to list, then operator. */
                  allocate list, written;
                  list = '('; written = false;
                  out = ')' || out;
               end;
            allocate list, written;
            list = s; written = false;
         end;
      else /* It's a variable name */
         do;
            out = s || out;
next_list:
            if allocation(list) > 0 then if written then free written, list;
            if allocation(list) > 0 then if list = '(' then
               do; out = list || out; free written, list; end;
            if allocation (list) = 0 then leave translation;
            if written then go to next_list;
            written = true;
            out = list || out; /* Output an operator. */
         end;
      put skip edit ('INPUT=' || s) (a); call show_stack;
      put edit (' OUTPUT=', out) (col(30), 2 a);
   end;
   put skip list ('ALGEBRAIC EXPRESSION=', out);

end cvt;


"""
>>> # EXAMPLE USAGE
>>> result = rpn_to_infix('3 4 2 * 1 5 - 2 3 ^ ^ / +', VERBOSE=True)
TOKEN  STACK
3      ['3']
4      ['3', '4']
2      ['3', '4', '2']
*      ['3', Node('2','*','4')]
1      ['3', Node('2','*','4'), '1']
5      ['3', Node('2','*','4'), '1', '5']
-      ['3', Node('2','*','4'), Node('5','-','1')]
2      ['3', Node('2','*','4'), Node('5','-','1'), '2']
3      ['3', Node('2','*','4'), Node('5','-','1'), '2', '3']
^      ['3', Node('2','*','4'), Node('5','-','1'), Node('3','^','2')]
^      ['3', Node('2','*','4'), Node(Node('3','^','2'),'^',Node('5','-','1'))]
/      ['3', Node(Node(Node('3','^','2'),'^',Node('5','-','1')),'/',Node('2','*','4'))]
+      [Node(Node(Node(Node('3','^','2'),'^',Node('5','-','1')),'/',Node('2','*','4')),'+','3')]
"""

prec_dict =  {'^':4, '*':3, '/':3, '+':2, '-':2}
assoc_dict = {'^':1, '*':0, '/':0, '+':0, '-':0}

class Node:
    def __init__(self,x,op,y=None):
        self.precedence = prec_dict[op]
        self.assocright = assoc_dict[op]
        self.op = op
        self.x,self.y = x,y

    def __str__(self):
        """
        Building an infix string that evaluates correctly is easy.
        Building an infix string that looks pretty and evaluates
        correctly requires more effort.
        """
        # easy case, Node is unary
        if self.y == None:
            return '%s(%s)'%(self.op,str(self.x))

        # determine left side string
        str_y = str(self.y)
        if  self.y < self or \
            (self.y == self and self.assocright) or \
            (str_y[0] is '-' and self.assocright):

            str_y = '(%s)'%str_y
        # determine right side string and operator
        str_x = str(self.x)
        str_op = self.op
        if self.op is '+' and not isinstance(self.x, Node) and str_x[0] is '-':
            str_x = str_x[1:]
            str_op = '-'
        elif self.op is '-' and not isinstance(self.x, Node) and str_x[0] is '-':
            str_x = str_x[1:]
            str_op = '+'
        elif self.x < self or \
             (self.x == self and not self.assocright and \
              getattr(self.x, 'op', 1) != getattr(self, 'op', 2)):

            str_x = '(%s)'%str_x
        return ' '.join([str_y, str_op, str_x])

    def __repr__(self):
        """
        >>> repr(Node('3','+','4')) == repr(eval(repr(Node('3','+','4'))))
        True
        """
        return 'Node(%s,%s,%s)'%(repr(self.x), repr(self.op), repr(self.y))

    def __lt__(self, other):
        if isinstance(other, Node):
            return self.precedence < other.precedence
        return self.precedence < prec_dict.get(other,9)

    def __gt__(self, other):
        if isinstance(other, Node):
            return self.precedence > other.precedence
        return self.precedence > prec_dict.get(other,9)

    def __eq__(self, other):
        if isinstance(other, Node):
            return self.precedence == other.precedence
        return self.precedence > prec_dict.get(other,9)

def rpn_to_infix(s, VERBOSE=False):
    """

    converts rpn notation to infix notation for string s

    """
    if VERBOSE : print('TOKEN  STACK')

    stack=[]
    for token in s.replace('^','^').split():
        if token in prec_dict:
            stack.append(Node(stack.pop(),token,stack.pop()))
        else:
            stack.append(token)

        # can't use \t in order to make global docstring pass doctest
        if VERBOSE : print(token+' '*(7-len(token))+repr(stack))

    return str(stack[0])

strTest = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
strResult = rpn_to_infix(strTest, VERBOSE=False)
print ("Input: ",strTest)
print ("Output:",strResult)

print()

strTest = "1 2 + 3 4 + ^ 5 6 + ^"
strResult = rpn_to_infix(strTest, VERBOSE=False)
print ("Input: ",strTest)
print ("Output:",strResult)


#lang racket
(require racket/dict)

(define (RPN->infix expr)
  (define-values (res _)
    (for/fold ([stack '()] [prec '()]) ([t expr])
      (show t stack prec)
      (cond
        [(dict-has-key? operators t)
         (match-define (list pt at) (dict-ref operators t))
         (match-define (list y x ss ...) stack)
         (match-define (list py px ps ...) prec)
         (define fexpr
           (cond
             [(> pt (max px py)) "(~a) ~a (~a)"]
             [(or (< px pt) (and (= pt px) (eq? at 'r))) "(~a) ~a ~a"]
             [(or (< py pt) (and (= pt py) (eq? at 'l))) "~a ~a (~a)"]
             [else "~a ~a ~a"]))
         (define term (format fexpr x t y))
         (values (cons term ss) (cons pt ps))]
        [else (values (cons t stack) (cons +inf.0 prec))])))
  (car res))

;; the list of operators and their properties
(define operators '((+ 2 l) (- 2 l) (* 3 l) (/ 3 l) (^ 4 r)))

;; printing out the intermediate stages
(define (show t stack prec)
  (printf "~a\t" t)
  (for ([s stack] [p prec])
    (if (eq? +inf.0 p) (printf "[~a] " s) (printf "[~a {~a}] " s p)))
  (newline))


/*REXX program  converts  Reverse Polish Notation  (RPN)    ───►    an infix notation.  */
showAction = 1                                   /*  0  if no   showActions   wanted.   */
         # = 0                                   /*initialize stack pointer to 0 (zero).*/
        oS = '+ - / * ^'                         /*the operator symbols.                */
        oP = '2 2 3 3 4'                         /*the operator priorities.             */
        oA = '◄ ◄ ◄ ◄ ►'                         /*the operator associations.           */
say  "infix: "   toInfix( "3 4 2 * 1 5 - 2 3 ^ ^ / +" )
say  "infix: "   toInfix( "1 2 + 3 4 + ^ 5 6 + ^" )     /* [↓]  Sprechen Sie Deutsch?   */
say  "infix: "   toInfix( "Mond Sterne Schlamm + * Feur Suppe * ^" )
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
pop:       pop= #;                 #= # - 1;                     return @.pop
push:      #= # + 1;               @.#= arg(1);                  return
/*──────────────────────────────────────────────────────────────────────────────────────*/
stack2str: $=;             do j=1  for #;          _ = @.j;      y= left(_, 1)
                           if pos(' ', _)==0  then _ = '{'strip( substr(_, 2) )"}"
                                              else _ =           substr(_, 2)
                           $=$  '{'strip(y _)"}"
                           end   /*j*/
           return space($)
/*──────────────────────────────────────────────────────────────────────────────────────*/
toInfix:   parse arg rpn;   say copies('─', 80 - 1);             say 'RPN: '  space(rpn)

               do N=1  for words(RPN)                  /*process each of the RPN tokens.*/
               ?= word(RPN, N)                         /*obtain next item in the list.  */
               if pos(?,oS)==0  then call push '¥' ?   /*when in doubt, add a Yen to it.*/
                                else do;   g= pop();    gp= left(g, 1);    g= substr(g, 2)
                                           h= pop();    hp= left(h, 1);    h= substr(h, 2)
                                     tp= substr(oP, pos(?, oS),  1)
                                     ta= substr(oA, pos(?, oS),  1)
                                     if hp<tp  |  (hp==tp & ta=='►')  then h= "("h")"
                                     if gp<tp  |  (gp==tp & ta=='◄')  then g= "("g")"
                                     call  push   tp  ||  h  ?  g
                                     end
                if showAction  then say   right(?, 25)    "──►"    stack2str()
                end   /*N*/

           return space( substr( pop(), 2) )


rpn = RPNExpression.new("3 4 2 * 1 5 - 2 3 ^ ^ / +")
infix = rpn.to_infix
ruby = rpn.to_ruby


func p(pair, prec) {
    pair[0] < prec ? "( #{pair[1]} )" : pair[1]
}

func rpm_to_infix(string) {
    say "#{'='*17}\n#{string}"
    var stack = []
    string.each_word { |w|
        if (w ~~ /\d/) {
            stack << [9, Num(w)]
        }
        else {
            var y = stack.pop
            var x = stack.pop
            given(w) {
              when ('^')   { stack << [4, [p(x,5), w, p(y,4)].join(' ')] }
              when (<* />) { stack << [3, [p(x,3), w, p(y,3)].join(' ')] }
              when (<+ ->) { stack << [2, [p(x,2), w, p(y,2)].join(' ')] }
            }
            say stack
        }
    }
    say '-'*17
    stack.map{_[1]}
}

var tests = [
    '3 4 2 * 1 5 - 2 3 ^ ^ / +',
    '1 2 + 3 4 + ^ 5 6 + ^',
]

tests.each { say rpm_to_infix(_).join(' ') }


package require Tcl 8.5

# Helpers
proc precassoc op {
    dict get {^ {4 right} * {3 left} / {3 left} + {2 left} - {2 left}} $op
}
proc pop stk {
    upvar 1 $stk s
    set val [lindex $s end]
    set s [lreplace $s end end]
    return $val
}

proc rpn2infix rpn {
    foreach token $rpn {
	switch $token {
	    "^" - "/" - "*" - "+" - "-" {
		lassign [pop stack] bprec b
		lassign [pop stack] aprec a
		lassign [precassoc $token] p assoc
		if {$aprec < $p || ($aprec == $p && $assoc eq "right")} {
		    set a "($a)"
		}
		if {$bprec < $p || ($bprec == $p && $assoc eq "left")} {
		    set b "($b)"
		}
		lappend stack [list $p "$a $token $b"]
	    }
	    default {
		lappend stack [list 9 $token]
	    }
	}
	puts "$token -> $stack"
    }
    return [lindex $stack end 1]
}

puts [rpn2infix {3 4 2 * 1 5 - 2 3 ^ ^ / +}]
puts [rpn2infix {1 2 + 3 4 + ^ 5 6 + ^}]


;; alias for circumflex, which is reserved syntax
(defvar exp (intern "^"))

(defvar *prec* ^((,exp . 4) (* . 3) (/ . 3) (+ . 2) (- . 2)))

(defvar *asso* ^((,exp . :right) (* . nil)
                 (/ . :left) (+ . nil) (- . :left)))

(defun debug-print (label val)
  (format t "~a: ~a\n" label val)
  val)

(defun rpn-to-lisp (rpn)
  (let (stack)
    (each ((term rpn))
      (if (symbolp (debug-print "rpn term" term))
        (let ((right (pop stack))
              (left (pop stack)))
          (push ^(,term ,left ,right) stack))
        (push term stack))
      (debug-print "stack" stack))
    (if (rest stack)
      (return-from error "*excess stack elements*"))
      (debug-print "lisp" (pop stack))))

(defun prec (term)
  (or (cdr (assoc term *prec*)) 99))

(defun asso (term dfl)
  (or (cdr (assoc term *asso*)) dfl))

(defun inf-term (op term left-or-right)
  (if (atom term)
    `@term`
    (let ((pt (prec (car term)))
          (po (prec op))
          (at (asso (car term) left-or-right))
          (ao (asso op left-or-right)))
      (cond
        ((< pt po) `(@(lisp-to-infix term))`)
        ((> pt po) `@(lisp-to-infix term)`)
        ((and (eq at ao) (eq left-or-right ao)) `@(lisp-to-infix term)`)
        (t `(@(lisp-to-infix term))`)))))

(defun lisp-to-infix (lisp)
  (tree-case lisp
    ((op left right) (let ((left-inf (inf-term op left :left))
                           (right-inf (inf-term op right :right)))
                       `@{left-inf} @op @{right-inf}`))
    (()              (return-from error "*stack underflow*"))
    (else            `@lisp`)))

(defun string-to-rpn (str)
  (debug-print "rpn"
    (mapcar (do if (int-str @1) (int-str @1) (intern @1))
            (tok-str str #/[^ \t]+/))))

(debug-print "infix"
  (block error
     (tree-case *args*
       ((a b . c) "*excess args*")
       ((a) (lisp-to-infix (rpn-to-lisp (string-to-rpn a))))
       (else "*arg needed*"))))


Option Strict On

Imports System.Text.RegularExpressions

Module Module1

    Class Operator_
        Sub New(t As Char, p As Integer, Optional i As Boolean = False)
            Token = t
            Precedence = p
            IsRightAssociative = i
        End Sub

        Property Token As Char
            Get
                Return m_token
            End Get
            Private Set(value As Char)
                m_token = value
            End Set
        End Property

        Property Precedence As Integer
            Get
                Return m_precedence
            End Get
            Private Set(value As Integer)
                m_precedence = value
            End Set
        End Property

        Property IsRightAssociative As Boolean
            Get
                Return m_right
            End Get
            Private Set(value As Boolean)
                m_right = value
            End Set
        End Property

        Private m_token As Char
        Private m_precedence As Integer
        Private m_right As Boolean
    End Class

    ReadOnly operators As New Dictionary(Of Char, Operator_) From {
        {"+"c, New Operator_("+"c, 2)},
        {"-"c, New Operator_("-"c, 2)},
        {"/"c, New Operator_("/"c, 3)},
        {"*"c, New Operator_("*"c, 3)},
        {"^"c, New Operator_("^"c, 4, True)}
    }

    Class Expression
        Public Sub New(e As String)
            Ex = e
        End Sub

        Sub New(e1 As String, e2 As String, o As Operator_)
            Ex = String.Format("{0} {1} {2}", e1, o.Token, e2)
            Op = o
        End Sub

        ReadOnly Property Ex As String
        ReadOnly Property Op As Operator_
    End Class

    Function PostfixToInfix(postfix As String) As String
        Dim stack As New Stack(Of Expression)

        For Each token As String In Regex.Split(postfix, "\s+")
            Dim c = token(0)
            Dim op = operators.FirstOrDefault(Function(kv) kv.Key = c).Value
            If Not IsNothing(op) AndAlso token.Length = 1 Then
                Dim rhs = stack.Pop()
                Dim lhs = stack.Pop()

                Dim opPrec = op.Precedence

                Dim lhsPrec = If(IsNothing(lhs.Op), Integer.MaxValue, lhs.Op.Precedence)
                Dim rhsPrec = If(IsNothing(rhs.Op), Integer.MaxValue, rhs.Op.Precedence)

                Dim newLhs As String
                If lhsPrec < opPrec OrElse (lhsPrec = opPrec AndAlso c = "^") Then
                    'lhs.Ex = "(" + lhs.Ex + ")"
                    newLhs = "(" + lhs.Ex + ")"
                Else
                    newLhs = lhs.Ex
                End If

                Dim newRhs As String
                If rhsPrec < opPrec OrElse (rhsPrec = opPrec AndAlso c <> "^") Then
                    'rhs.Ex = "(" + rhs.Ex + ")"
                    newRhs = "(" + rhs.Ex + ")"
                Else
                    newRhs = rhs.Ex
                End If

                stack.Push(New Expression(newLhs, newRhs, op))
            Else
                stack.Push(New Expression(token))
            End If

            'Print intermediate result
            Console.WriteLine("{0} -> [{1}]", token, String.Join(", ", stack.Reverse().Select(Function(e) e.Ex)))
        Next

        Return stack.Peek().Ex
    End Function

    Sub Main()
        Dim inputs = {"3 4 2 * 1 5 - 2 3 ^ ^ / +", "1 2 + 3 4 + ^ 5 6 + ^"}
        For Each e In inputs
            Console.WriteLine("Postfix : {0}", e)
            Console.WriteLine("Infix : {0}", PostfixToInfix(e))
            Console.WriteLine()
        Next
        Console.ReadLine() 'remove before submit
    End Sub

End Module


import "/seq" for Stack
import "/pattern" for Pattern

class Expression {
    static ops { "-+/*^" }

    construct new(ex, op, prec) {
        _ex = ex
        _op = op
        _prec = prec
    }

    static build(e1, e2, o) { new("%(e1) %(o) %(e2)", o, (ops.indexOf(o)/2).floor) }

    ex { _ex }
    ex=(other) { _ex = other }
    prec { _prec }

    toString { _ex }
}

var postfixToInfix = Fn.new { |postfix|
    var expr = Stack.new()
    var p = Pattern.new("+1/s")
    for (token in p.splitAll(postfix)) {
        var c = token[0]
        var idx = Expression.ops.indexOf(c)
        if (idx != -1 && token.count == 1) {
            var r = expr.pop()
            var l = expr.pop()
            var opPrec = (idx/2).floor
            if (l.prec < opPrec || (l.prec == opPrec && c == "^")) {
                l.ex = "(%(l.ex))"
            }
            if (r.prec < opPrec || (r.prec == opPrec && c != "^")) {
                r.ex = "(%(r.ex))"
            }
            expr.push(Expression.build(l.ex, r.ex, token))
        } else {
            expr.push(Expression.new(token, "", 3))
        }
        System.print("%(token) -> %(expr)")
    }
    return expr.peek().ex
}

var es = [
    "3 4 2 * 1 5 - 2 3 ^ ^ / +",
    "1 2 + 3 4 + ^ 5 6 + ^"
]
for (e in es) {
    System.print("Postfix : %(e)")
    System.print("Infix : %(postfixToInfix.call(e))\n")
}


tests:=T("3 4 2 * 1 5 - 2 3 ^ ^ / +","1 2 + 3 4 + ^ 5 6 + ^");

var opa=D(
   "^",T(4, True),
   "*",T(3, False), "/",T(3, False),
   "+",T(2, False), "-",T(2, False) );

const nPrec = 9;

foreach t in (tests) { parseRPN(t) }

fcn parseRPN(e){
   println("\npostfix:", e);
   stack:=L();
   foreach tok in (e.split()){
      println("token: ", tok);
      opPrec,rAssoc:=opa.find(tok,T(Void,Void));
      if(opPrec){
	 rhsPrec,rhsExpr := stack.pop();
	 lhsPrec,lhsExpr := stack.pop();
	 if(lhsPrec < opPrec or (lhsPrec == opPrec and rAssoc))
	    lhsExpr = "(" + lhsExpr + ")";
	 lhsExpr += " " + tok + " ";
	 if(rhsPrec < opPrec or (rhsPrec == opPrec and not rAssoc)){
	    lhsExpr += "(" + rhsExpr + ")"
	 } else
	    lhsExpr += rhsExpr;
	 lhsPrec = opPrec;
	 stack.append(T(lhsPrec,lhsExpr));
      } else
	 stack.append(T(nPrec, tok));
      foreach f in (stack){
         println(0'|    %d "%s"|.fmt(f.xplode()))
      }
   }
   println("infix:", stack[0][1])
}


[Float] a
[String = ((Float, Float) -> Float)] b
b[‘+’] = (x, y) -> y + x
b[‘-’] = (x, y) -> y - x
b[‘*’] = (x, y) -> y * x
b[‘/’] = (x, y) -> y / x
b[‘^’] = (x, y) -> y ^ x

L(c) ‘3 4 2 * 1 5 - 2 3 ^ ^ / +’.split(‘ ’)
   I c C b
      V first  = a.pop()
      V second = a.pop()
      a.append(b[c](first, second))
   E
      a.append(Float(c))
   print(c‘ ’a)


*        RPN calculator         RC 25/01/2019
REVPOL   CSECT
         USING  REVPOL,R13         base register
         B      72(R15)            skip savearea
         DC     17F'0'             savearea
         STM    R14,R12,12(R13)    save previous context
         ST     R13,4(R15)         link backward
         ST     R15,8(R13)         link forward
         LR     R13,R15            set addressability
         XPRNT  TEXT,L'TEXT        print expression !?
         L      R4,0               js=0  offset in stack
         LA     R5,0               ns=0  number of stack items
         LA     R6,0               jt=0  offset in text
         LA     R7,TEXT            [email protected]
         MVC    CC,0(R7)           cc first char of token
       DO WHILE=(CLI,CC,NE,X'00')  do while cc<>'0'x
         MVC    CTOK,=CL5' '         ctok=''
         MVC    CTOK(1),CC           ctok=cc
         CLI    CC,C' '              if cc=' '
         BE     ITERATE              then goto iterate
       IF CLI,CC,GE,C'0',AND,CLI,CC,LE,C'9' THEN
         MVC    DEED,=C'Load'        deed='Load'
         XDECI  R2,0(R7)             r2=cint(text); [email protected]
         ST     R2,STACK(R4)         stack(js)=cc
         SR     R1,R7                lt  length of token
         BCTR   R1,0                 lt-1
         EX     R1,MVCV              MVC CTOK("R1"),0(R7)
         AR     R6,R1                jt+=lt-1
         AR     R7,R1                @text+=lt-1
         LA     R4,4(R4)             js+=4
         LA     R5,1(R5)             ns++
       ELSE     ,                    else
         MVC    DEED,=C'Exec'        deed='Exec'
         LA     R9,STACK-8(R4)       @stack(j-1)
       IF CLI,CC,EQ,C'+' THEN        if cc='+' then
         L      R1,STACK-8(R4)         stack(j-1)
         A      R1,STACK-4(R4)         stack(j-1)+stack(j)
         ST     R1,0(R9)               stack(j-1)=stack(j-1)+stack(j)
       ENDIF    ,                    endif
       IF CLI,CC,EQ,C'-' THEN        if cc='-' then
         L      R1,STACK-8(R4)         stack(j-1)
         S      R1,STACK-4(R4)         stack(j-1)-stack(j)
         ST     R1,0(R9)               stack(j-1)=stack(j-1)-stack(j)
       ENDIF    ,                    endif
       IF CLI,CC,EQ,C'*' THEN        if cc='*' then
         L      R3,STACK-8(R4)         stack(j-1)
         M      R2,STACK-4(R4)         stack(j-1)*stack(j)
         ST     R3,0(R9)               stack(j-1)=stack(j-1)*stack(j)
       ENDIF    ,                    endif
       IF CLI,CC,EQ,C'/' THEN        if cc='/' then
         L      R2,STACK-8(R4)         stack(j-1)
         SRDA   R2,32                  for sign propagation
         D      R2,STACK-4(R4)         stack(j-1)/stack(j)
         ST     R3,0(R9)               stack(j-1)=stack(j-1)/stack(j)
       ENDIF    ,                    endif
       IF CLI,CC,EQ,C'^' THEN        if cc='^' then
         LA     R3,1                   r3=1
         L      R0,STACK-4(R4)         r0=stack(j) [loop count]
EXPONENT M      R2,STACK-8(R4)         r3=r3*stack(j-1)
         BCT    R0,EXPONENT            if r0--<>0 then goto exponent
         ST     R3,0(R9)               stack(j-1)=stack(j-1)^stack(j)
       ENDIF    ,                    endif
         S      R4,=F'4'             js-=4
         BCTR   R5,0                 ns--
       ENDIF    ,                  endif
         MVC    PG,=CL80' '          clean buffer
         MVC    PG(4),DEED           output deed
         MVC    PG+5(5),CTOK         output cc
         MVC    PG+11(6),=C'Stack:'  output
         LA     R2,1                 i=1
         LA     R3,STACK             @stack
         LA     R9,PG+18             @buffer
       DO WHILE=(CR,R2,LE,R5)        do i=1 to ns
         L      R1,0(R3)               stack(i)
         XDECO  R1,XDEC                edit stack(i)
         MVC    0(5,R9),XDEC+7         output stack(i)
         LA     R2,1(R2)               i=i+1
         LA     R3,4(R3)               @stack+=4
         LA     R9,6(R9)               @buffer+=6
       ENDDO    ,                    enddo
         XPRNT  PG,L'PG              print
ITERATE  LA     R6,1(R6)             jt++
         LA     R7,1(R7)             @text++
         MVC    CC,0(R7)             cc next char
       ENDDO    ,                  enddo
         L      R1,STACK           stack(1)
         XDECO  R1,XDEC            edit stack(1)
         MVC    XDEC(4),=C'Val='   output
         XPRNT  XDEC,L'XDEC        print stack(1)
         L      R13,4(0,R13)       restore previous savearea pointer
         LM     R14,R12,12(R13)    restore previous context
         XR     R15,R15            rc=0
         BR     R14                exit
MVCV     MVC    CTOK(0),0(R7)      patern mvc
TEXT     DC     C'3 4 2 * 1 5 - 2 3 ^ ^ / +',X'00'
STACK    DS     16F                stack(16)
DEED     DS     CL4
CC       DS     C
CTOK     DS     CL5
PG       DS     CL80
XDEC     DS     CL12
         YREGS
         END    REVPOL


INCLUDE "D2:REAL.ACT" ;from the Action! Tool Kit

DEFINE PTR="CARD"
DEFINE BUFFER_SIZE="60"
DEFINE ENTRY_SIZE="6"
DEFINE MAX_SIZE="10"
BYTE ARRAY stack(BUFFER_SIZE)
BYTE stackSize=[0]

BYTE FUNC IsEmpty()
  IF stackSize=0 THEN
    RETURN (1)
  FI
RETURN (0)

PTR FUNC GetPtr(BYTE i)
RETURN (stack+i*ENTRY_SIZE)

PROC Push(REAL POINTER v)
  REAL POINTER p

  IF stackSize=MAX_SIZE THEN
    PrintE("Error: stack is full!")
    Break()
  FI
  p=GetPtr(stackSize)
  RealAssign(v,p)
  stackSize==+1
RETURN

PROC Pop(REAL POINTER v)
  REAL POINTER p

  IF IsEmpty() THEN
    PrintE("Error: stack is empty!")
    Break()
  FI
  stackSize==-1
  p=GetPtr(stackSize)
  RealAssign(p,v)
RETURN

PROC PrintStack()
  INT i
  REAL POINTER p

  FOR i=0 TO stackSize-1
  DO
    p=GetPtr(i)
    PrintR(p) Put(32)
  OD
  PutE()
RETURN

BYTE FUNC GetToken(CHAR ARRAY s BYTE start CHAR ARRAY t)
  BYTE pos

  pos=start
  WHILE pos<=s(0) AND s(pos)#'
  DO
    pos==+1
  OD
  SCopyS(t,s,start,pos-1)
RETURN (pos)

PROC MyPower(REAL POINTER base,exp,res)
  INT i,expI
  REAL tmp

  expI=RealToInt(exp)
  IF expI<0 THEN Break() FI

  IntToReal(1,res)
  FOR i=1 TO expI
  DO
    RealMult(res,base,tmp)
    RealAssign(tmp,res)
  OD
RETURN

PROC Process(CHAR ARRAY s)
  DEFINE Pop21="Pop(v2) Pop(v1)"
  CHAR ARRAY t(100)
  BYTE i,j
  CHAR c
  REAL v1,v2,v3

  i=1
  WHILE i<=s(0)
  DO
    WHILE i<=s(0) AND s(i)='
    DO i==+1 OD
    IF i>s(0) THEN EXIT FI

    i=GetToken(s,i,t)
    IF SCompare(t,"+")=0 THEN
      Pop21 RealAdd(v1,v2,v3)
      Print("calc +: ")
    ELSEIF SCompare(t,"-")=0 THEN
      Pop21 RealSub(v1,v2,v3)
      Print("calc -: ")
    ELSEIF SCompare(t,"*")=0 THEN
      Pop21 RealMult(v1,v2,v3)
      Print("calc *: ")
    ELSEIF SCompare(t,"/")=0 THEN
      Pop21 RealDiv(v1,v2,v3)
      Print("calc /: ")
    ELSEIF SCompare(t,"^")=0 THEN
      Pop21 MyPower(v1,v2,v3)
      Print("calc ^: ")
    ELSE
      ValR(t,v3)
      PrintF("push %S: ",t)
    FI
    Push(v3)
    PrintStack()
  OD
RETURN

PROC Test(CHAR ARRAY s)
  PrintE(s) PutE()
  Process(s)
RETURN

PROC Main()
  Put(125) PutE() ;clear the screen
  Test("3 4 2 * 1 5 - 2 3 ^ ^ / +")
RETURN


with Ada.Text_IO, Ada.Containers.Vectors;

procedure RPN_Calculator is

  package IIO is new Ada.Text_IO.Float_IO(Float);

   package Float_Vec is new Ada.Containers.Vectors
     (Index_Type => Positive, Element_Type => Float);
   Stack: Float_Vec.Vector;

   Input: String := Ada.Text_IO.Get_Line;
   Cursor: Positive := Input'First;
   New_Cursor: Positive;

begin
   loop
      -- read spaces
      while Cursor <= Input'Last and then Input(Cursor)=' ' loop
         Cursor := Cursor + 1;
      end loop;

      exit when Cursor > Input'Last;

      New_Cursor := Cursor;
      while New_Cursor <= Input'Last and then Input(New_Cursor) /= ' ' loop
         New_Cursor := New_Cursor + 1;
      end loop;

      -- try to read a number and push it to the stack
      declare
         Last: Positive;
         Value: Float;
         X, Y: Float;
      begin
         IIO.Get(From => Input(Cursor .. New_Cursor - 1),
                 Item => Value,
                 Last => Last);
         Stack.Append(Value);
         Cursor := New_Cursor;

      exception -- if reading the number fails, try to read an operator token
         when others =>
            Y := Stack.Last_Element; Stack.Delete_Last; -- pick two elements
            X := Stack.Last_Element; Stack.Delete_Last; -- from the stack
            case Input(Cursor) is
               when '+' => Stack.Append(X+Y);
               when '-' => Stack.Append(X-Y);
               when '*' => Stack.Append(X*Y);
               when '/' => Stack.Append(X/Y);
               when '^' => Stack.Append(X ** Integer(Float'Rounding(Y)));
               when others => raise Program_Error with "unecpected token '"
                  & Input(Cursor) & "' at column" & Integer'Image(Cursor);
            end case;
            Cursor := New_Cursor;
      end;

      for I in Stack.First_Index .. Stack.Last_Index loop
         Ada.Text_IO.Put(" ");
         IIO.Put(Stack.Element(I), Aft => 5, Exp => 0);
      end loop;
      Ada.Text_IO.New_Line;
   end loop;

   Ada.Text_IO.Put("Result = ");
   IIO.Put(Item => Stack.Last_Element, Aft => 5, Exp => 0);

end RPN_Calculator;


# RPN Expression evaluator - handles numbers and + - * / ^    #
#     the right-hand operand for ^ is converted to an integer #

# expression terminator #
CHAR end of expression character = REPR 12;

# evaluates the specified rpn expression #
PROC evaluate = ( STRING rpn expression )VOID:
BEGIN

    [ 256 ]REAL   stack;
    INT           stack pos := 0;

    # pops an element off the stack #
    PROC pop = REAL:
    BEGIN
        stack pos -:= 1;
        stack[ stack pos + 1 ]
    END; # pop #

    INT rpn pos := LWB rpn expression;

    # evaluate tokens from the expression until we get the end of expression #
    WHILE

        # get the next token from the string #

        STRING token type;
        REAL   value;

        # skip spaces #
        WHILE rpn expression[ rpn pos ] = " "
        DO
            rpn pos +:= 1
        OD;

        # handle the token #
        IF rpn expression[ rpn pos ] = end of expression character
        THEN
            # no more tokens #
            FALSE

        ELSE
            # have a token #

            IF  rpn expression[ rpn pos ] >= "0"
            AND rpn expression[ rpn pos ] <= "9"
            THEN
                # have a number #

                # find where the nmumber is in the expression #
                INT  number start = rpn pos;
                WHILE (   rpn expression[ rpn pos ] >= "0"
                      AND rpn expression[ rpn pos ] <= "9"
                      )
                   OR rpn expression[ rpn pos ] = "."
                DO
                    rpn pos +:= 1
                OD;

                # read the number from the expression #
                FILE number f;
                associate( number f
                         , LOC STRING := rpn expression[ number start : rpn pos - 1 ]
                         );
                get( number f, ( value ) );
                close( number f );

                token type := "number"

            ELSE
                # must be an operator #
                CHAR op      = rpn expression[ rpn pos ];
                rpn pos    +:= 1;

                REAL arg1   := pop;
                REAL arg2   := pop;
                token type  := op;

                value := IF   op = "+"
                         THEN
                             # add the top two stack elements #
                             arg1 + arg2
                         ELIF op = "-"
                         THEN
                             # subtract the top two stack elements #
                             arg2 - arg1
                         ELIF op = "*"
                         THEN
                             # multiply the top two stack elements #
                             arg2 * arg1
                         ELIF op = "/"
                         THEN
                             # divide the top two stack elements #
                             arg2 / arg1
                         ELIF op = "^"
                         THEN
                             # raise op2 to the power of op1 #
                             arg2 ^ ENTIER arg1
                         ELSE
                             # unknown operator #
                             print( ( "Unknown operator: """ + op + """", newline ) );
                             0
                         FI

            FI;

            TRUE
        FI
    DO
        # push the new value on the stack and show the new stack #

        stack[ stack pos +:= 1 ] := value;

        print( ( ( token type + "            " )[ 1 : 8 ] ) );
        FOR element FROM LWB stack TO stack pos
        DO
            print( ( " ", fixed( stack[ element ], 8, 4 ) ) )
        OD;
        print( ( newline ) )

    OD;

    print( ( "Result is: ", fixed( stack[ stack pos ], 12, 8 ), newline ) )

END; # evaluate #

main: (

    # get the RPN expresson from the user #

    STRING rpn expression;

    print( ( "Enter expression: " ) );
    read( ( rpn expression, newline ) );

    # add a space to terminate the final token and an expression terminator #
    rpn expression +:= " " + end of expression character;

    # execute the expression #
    evaluate( rpn expression )

)


1000 DECLARE EXTERNAL SUB rpn
1010 PUBLIC NUMERIC R(64)                             ! stack
1020 PUBLIC STRING expn$                              ! for keyboard input
1030 PUBLIC NUMERIC i, lenn, n, true, false           ! global values
1040 LET true = -1
1050 LET false = 0
1060 DO
1070    PRINT "enter an RPN expression:"
1080    INPUT expn$
1090    IF LEN( expn$ ) = 0 THEN EXIT DO
1100    PRINT "expn: ";expn$
1110    CALL rpn( expn$ )
1120 LOOP
1130 END
1140 !
1150 ! interpret reverse polish (postfix) expression
1160 EXTERNAL SUB rpn( expn$ )
1170 DECLARE EXTERNAL FUNCTION is_digit, get_number
1180 DECLARE EXTERNAL SUB print_stack
1190 DECLARE STRING ch$
1200 LET expn$ = expn$ & " "                          ! must terminate line with space
1210 LET lenn = LEN( expn$ )
1220 LET i = 0
1230 LET n = 1
1240 LET R(n) = 0.0                                   ! push zero for unary operations
1250 DO
1260    IF i >= lenn THEN EXIT DO                     ! at end of line
1270    LET i = i + 1
1280    IF expn$(i:i) <> " " THEN                     ! skip white spaces
1290       IF is_digit( expn$(i:i) ) = true THEN      ! push number onto stack
1300          LET n = n + 1
1310          LET R(n) = get_number
1320          CALL print_stack
1330       ELSEIF expn$(i:i) = "+" then               ! add and pop stack
1340          IF n < 2 THEN
1350             PRINT "stack underflow"
1360          ELSE
1370             LET R(n-1) = R(n-1) + R(n)
1380             LET n = n - 1
1390             CALL print_stack
1400          END IF
1410       ELSEIF expn$(i:i) = "-" then               ! subtract and pop stack
1420          IF n < 2 THEN
1430             PRINT "stack underflow"
1440          ELSE
1450             LET R(n-1) = R(n-1) - R(n)
1460             LET n = n - 1
1470             CALL print_stack
1480          END IF
1490       ELSEIF expn$(i:i) = "*" then               ! multiply and pop stack
1500          IF n < 2 THEN
1510             PRINT "stack underflow"
1520          ELSE
1530             LET R(n-1) = R(n-1) * R(n)
1540             LET n = n - 1
1550             CALL print_stack
1560          END IF
1570       ELSEIF expn$(i:i) = "/" THEN               ! divide and pop stack
1580          IF n < 2 THEN
1590             PRINT "stack underflow"
1600          ELSE
1610             LET R(n-1) = R(n-1) / R(n)
1620             LET n = n - 1
1630             CALL print_stack
1640          END IF
1650       ELSEIF expn$(i:i) = "^" THEN               ! raise to power and pop stack
1660          IF n < 2 THEN
1670             PRINT "stack underflow"
1680          ELSE
1690             LET R(n-1) = R(n-1) ^ R(n)
1700             LET n = n - 1
1710             CALL print_stack
1720          END IF
1730       ELSE
1740          PRINT REPEAT$( " ", i+5 ); "^ error"
1750          EXIT DO
1760       END IF
1770    END IF
1780 LOOP
1790 PRINT "result: "; R(n)                           ! end of main program
1800 END SUB
1810 !
1820 ! extract a number from a string
1830 EXTERNAL FUNCTION get_number
1840 DECLARE EXTERNAL FUNCTION is_digit
1850 LET j = 1                                        ! start of number string
1860 DECLARE STRING number$                           ! buffer for conversion
1870 DO                                               ! get integer part
1880    LET number$(j:j) = expn$(i:i)
1890    LET i = i + 1
1900    LET j = j + 1
1910    IF is_digit( expn$(i:i) ) = false THEN
1920       IF expn$(i:i) = "." then
1930          LET number$(j:j) = expn$(i:i)           ! include decimal point
1940          LET i = i + 1
1950          LET j = j + 1
1960          DO WHILE is_digit( expn$(i:i) ) = true  ! get fractional part
1970             LET number$(j:j) = expn$(i:i)
1980             LET i = i + 1
1990             LET j = j + 1
2000          LOOP
2010       END IF
2020       EXIT DO
2030    END IF
2040 LOOP
2050 LET get_number = VAL( number$ )
2060 END FUNCTION
2070 !
2080 ! check for digit character
2090 EXTERNAL FUNCTION is_digit( ch$ )
2100 IF "0" <= expn$(i:i) AND expn$(i:i) <= "9" THEN
2110    LET is_digit = true
2120 ELSE
2130    LET is_digit = false
2140 END IF
2150 END FUNCTION
2160 !
2170 EXTERNAL SUB print_stack
2180 PRINT expn$(i:i);"    ";
2190 FOR ptr=n TO 2 STEP -1
2200    PRINT USING "-----%.####":R(ptr);
2210 NEXT ptr
2220 PRINT
2230 END SUB


grammar rpnC ;
//
//  rpn Calculator
//
//  Nigel Galloway - April 7th., 2012
//
@members {
Stack<Double> s = new Stack<Double>();
}
rpn	:	(WS* (num|op) (WS | WS* NEWLINE {System.out.println(s.pop());}))*;
num	:	'-'? Digit+ ('.' Digit+)? {s.push(Double.parseDouble($num.text));};
Digit	:	'0'..'9';
op	:	'-' {double x = s.pop(); s.push(s.pop() - x);}
	|	'/' {double x = s.pop(); s.push(s.pop() / x);}
	|	'*' {s.push(s.pop() * s.pop());}
	|	'^' {double x = s.pop(); s.push(Math.pow(s.pop(), x));}
	|	'+' {s.push(s.pop() + s.pop());};
WS	:	(' ' | '\t'){skip()};
NEWLINE	:	'\r'? '\n';


evalRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +")
evalRPN(s){
	stack := []
	out := "For RPN expression: '" s "'`r`n`r`nTOKEN`t`tACTION`t`t`tSTACK`r`n"
	Loop Parse, s
		If A_LoopField is number
			t .= A_LoopField
		else
		{
			If t
				stack.Insert(t)
				, out .= t "`tPush num onto top of stack`t" stackShow(stack) "`r`n"
				, t := ""
			If InStr("+-/*^", l := A_LoopField)
			{
				a := stack.Remove(), b := stack.Remove()
				stack.Insert(	 l = "+" ? b + a
						:l = "-" ? b - a
						:l = "*" ? b * a
						:l = "/" ? b / a
						:l = "^" ? b **a
						:0	)
				out .= l "`tApply op " l " to top of stack`t" stackShow(stack) "`r`n"
			}
		}
	r := stack.Remove()
	out .= "`r`n The final output value is: '" r "'"
	clipboard := out
	return r
}
StackShow(stack){
	for each, value in stack
		out .= A_Space value
	return subStr(out, 2)
}


      @% = &60B
      RPN$ = "3 4 2 * 1 5 - 2 3 ^ ^ / +"

      DIM Stack(1000)
      SP% = 0

      FOR i% = 1 TO LEN(RPN$)
        Token$ = MID$(RPN$,i%,1)
        IF Token$ <> " " THEN
          PRINT Token$ " :";
          CASE Token$ OF
            WHEN "+": PROCpush(FNpop + FNpop)
            WHEN "-": PROCpush(-FNpop + FNpop)
            WHEN "*": PROCpush(FNpop * FNpop)
            WHEN "/": n = FNpop : PROCpush(FNpop / n)
            WHEN "^": n = FNpop : PROCpush(FNpop ^ n)
            WHEN "0","1","2","3","4","5","6","7","8","9":
              PROCpush(VALMID$(RPN$,i%))
              WHILE ASCMID$(RPN$,i%)>=48 AND ASCMID$(RPN$,1)<=57
                i% += 1
              ENDWHILE
          ENDCASE
          FOR j% = SP%-1 TO 0 STEP -1 : PRINT Stack(j%); : NEXT
          PRINT
        ENDIF
      NEXT i%
      END

      DEF PROCpush(n)
      IF SP% > DIM(Stack(),1) ERROR 100, "Stack full"
      Stack(SP%) = n
      SP% += 1
      ENDPROC

      DEF FNpop
      IF SP% = 0 ERROR 100, "Stack empty"
      SP% -= 1
      = Stack(SP%)


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

void die(const char *msg)
{
	fprintf(stderr, "%s", msg);
	abort();
}

#define MAX_D 256
double stack[MAX_D];
int depth;

void push(double v)
{
	if (depth >= MAX_D) die("stack overflow\n");
	stack[depth++] = v;
}

double pop()
{
	if (!depth) die("stack underflow\n");
	return stack[--depth];
}

double rpn(char *s)
{
	double a, b;
	int i;
	char *e, *w = " \t\n\r\f";

	for (s = strtok(s, w); s; s = strtok(0, w)) {
		a = strtod(s, &e);
		if (e > s)		printf(" :"), push(a);
#define binop(x) printf("%c:", *s), b = pop(), a = pop(), push(x)
		else if (*s == '+')	binop(a + b);
		else if (*s == '-')	binop(a - b);
		else if (*s == '*')	binop(a * b);
		else if (*s == '/')	binop(a / b);
		else if (*s == '^')	binop(pow(a, b));
#undef binop
		else {
			fprintf(stderr, "'%c': ", *s);
			die("unknown oeprator\n");
		}
		for (i = depth; i-- || 0 * putchar('\n'); )
			printf(" %g", stack[i]);
	}

	if (depth != 1) die("stack leftover\n");

	return pop();
}

int main(void)
{
	char s[] = " 3 4 2 * 1 5 - 2 3 ^ ^ / + ";
	printf("%g\n", rpn(s));
	return 0;
}


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


#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <iterator>
#include <cstdlib>

double rpn(const std::string &expr){
  std::istringstream iss(expr);
  std::vector<double> stack;
  std::cout << "Input\tOperation\tStack after" << std::endl;
  std::string token;
  while (iss >> token) {
    std::cout << token << "\t";
    double tokenNum;
    if (std::istringstream(token) >> tokenNum) {
      std::cout << "Push\t\t";
      stack.push_back(tokenNum);
    } else {
      std::cout << "Operate\t\t";
      double secondOperand = stack.back();
      stack.pop_back();
      double firstOperand = stack.back();
      stack.pop_back();
      if (token == "*")
	stack.push_back(firstOperand * secondOperand);
      else if (token == "/")
	stack.push_back(firstOperand / secondOperand);
      else if (token == "-")
	stack.push_back(firstOperand - secondOperand);
      else if (token == "+")
	stack.push_back(firstOperand + secondOperand);
      else if (token == "^")
	stack.push_back(std::pow(firstOperand, secondOperand));
      else { //just in case
	std::cerr << "Error" << std::endl;
	std::exit(1);
      }
    }
    std::copy(stack.begin(), stack.end(), std::ostream_iterator<double>(std::cout, " "));
    std::cout << std::endl;
  }
  return stack.back();
}

int main() {
  std::string s = " 3 4 2 * 1 5 - 2 3 ^ ^ / + ";
  std::cout << "Final answer: " << rpn(s) << std::endl;

  return 0;
}


import ceylon.collection {

	ArrayList
}

shared void run() {

	value ops = map {
		"+" -> plus<Float>,
		"*" -> times<Float>,
		"-" -> ((Float a, Float b) => a - b),
		"/" -> ((Float a, Float b) => a / b),
		"^" -> ((Float a, Float b) => a ^ b)
	};

	void printTableRow(String|Float token, String description, {Float*} stack) {
		print("``token.string.padTrailing(8)````description.padTrailing(30)````stack``");
	}

	function calculate(String input) {

		value stack = ArrayList<Float>();
		value tokens = input.split().map((String element)
			=> if(ops.keys.contains(element)) then element else parseFloat(element));

		print("Token   Operation                     Stack");

		for(token in tokens.coalesced) {
			if(is Float token) {
				stack.push(token);
				printTableRow(token, "push", stack);
			} else if(exists op = ops[token], exists first = stack.pop(), exists second = stack.pop()) {
				value result = op(second, first);
				stack.push(result);
				printTableRow(token, "perform ``token`` on ``formatFloat(second, 1, 1)`` and ``formatFloat(first, 1, 1)``", stack);
			} else {
				throw Exception("bad syntax");
			}
		}
		return stack.pop();
	}

	print(calculate("3 4 2 * 1 5 - 2 3 ^ ^ / +"));
}


(ns rosettacode.parsing-rpn-calculator-algorithm
  (:require clojure.math.numeric-tower
            clojure.string
            clojure.pprint))

(def operators
  "the only allowable operators for our calculator"
  {"+" +
   "-" -
   "*" *
   "/" /
   "^" clojure.math.numeric-tower/expt})

(defn rpn
  "takes a string and returns a lazy-seq of all the stacks"
  [string]
  (letfn [(rpn-reducer [stack item] ; this takes a stack and one item and makes a new stack
            (if (contains? operators item)
              (let [operand-1 (peek stack) ; if we used lists instead of vectors, we could use destructuring, but stacks would look backwards
                    stack-1 (pop stack)]   ;we're assuming that all the operators are binary
                (conj (pop stack-1)
                      ((operators item) (peek stack-1) operand-1)))
              (conj stack (Long. item))))] ; if it wasn't an operator, we'll assume it's a long. Could choose bigint, or even read-line
    (reductions rpn-reducer [] (clojure.string/split string #"\s+")))) ;reductions is like reduce only shows all the intermediate steps

(let [stacks (rpn "3 4 2 * 1 5 - 2 3 ^ ^ / +")] ;bind it so we can output the answer separately.
  (println "stacks: ")
  (clojure.pprint/pprint stacks)
  (print "answer:" (->> stacks last first)))


% Split string by whitespace
split = iter (expr: string) yields (string)
    own whitespace: string := " \r\n\t"
    cur: array[char] := array[char]$[]
    for c: char in string$chars(expr) do
        if string$indexc(c, whitespace) = 0 then
            array[char]$addh(cur, c)
        else
            if array[char]$empty(cur) then continue end
            yield(string$ac2s(cur))
            cur := array[char]$[]
        end
    end
    if ~array[char]$empty(cur) then
        yield(string$ac2s(cur))
    end
end split

% Tokenize a RPN expression
token = oneof[number: real, op: char]
tokens = iter (expr: string) yields (token) signals (parse_error(string))
    own operators: string := "+-*/^"
    for t: string in split(expr) do
        if string$size(t) = 1 cand string$indexc(t[1], operators)~=0 then
            yield(token$make_op(t[1]))
        else
            yield(token$make_number(real$parse(t)))
            except when bad_format:
                signal parse_error(t)
            end
        end
    end
end tokens

% Print the stack
print_stack = proc (stack: array[real])
    po: stream := stream$primary_output()
    for num: real in array[real]$elements(stack) do
        stream$puts(po, f_form(num, 5, 5) || " ")
    end
    stream$putl(po, "")
end print_stack

% Evaluate an expression, printing the stack at each point
evaluate_rpn = proc (expr: string) returns (real) signals (parse_error(string), bounds)
    stack: array[real] := array[real]$[]
    for t: token in tokens(expr) do
        tagcase t
            tag number (n: real): array[real]$addh(stack, n)
            tag op (f: char):
                r: real := array[real]$remh(stack)
                l: real := array[real]$remh(stack)
                n: real
                if     f='+' then n := l+r
                elseif f='-' then n := l-r
                elseif f='*' then n := l*r
                elseif f='/' then n := l/r
                elseif f='^' then n := l**r
                end
                array[real]$addh(stack, n)
        end
        print_stack(stack)
    end resignal parse_error
    return(array[real]$reml(stack))
end evaluate_rpn

start_up = proc ()
    po: stream := stream$primary_output()
    expr: string := "3 4 2 * 1 5 - 2 3 ^ ^ / +"

    stream$putl(po, "Expression: " || expr)
    stream$putl(po, "Result: " || f_form(evaluate_rpn(expr), 5, 5))
end start_up


       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.


(setf (symbol-function '^) #'expt)  ; Make ^ an alias for EXPT

(defun print-stack (token stack)
    (format T "~a: ~{~a ~}~%" token (reverse stack)))

(defun rpn (tokens &key stack verbose )
  (cond
    ((and (not tokens) (not stack)) 0)
    ((not tokens) (car stack))
    (T
      (let* ((current (car tokens))
             (next-stack (if (numberp current)
                           (cons current stack)
                           (let* ((arg2 (car stack))
                                  (arg1 (cadr stack))
                                  (fun (car tokens)))
                             (cons (funcall fun arg1 arg2) (cddr stack))))))
        (when verbose
          (print-stack current next-stack))
        (rpn (cdr tokens) :stack next-stack :verbose verbose)))))


import std.stdio, std.string, std.conv, std.typetuple;

void main() {
    auto input = "3 4 2 * 1 5 - 2 3 ^ ^ / +";
    writeln("For postfix expression: ", input);
    writeln("\nToken            Action            Stack");
    real[] stack;
    foreach (tok; input.split()) {
        auto action = "Apply op to top of stack";
        switch (tok) {
            foreach (o; TypeTuple!("+", "-", "*", "/", "^")) {
                case o:
                    mixin("stack[$ - 2]" ~
                          (o == "^" ? "^^" : o) ~ "=stack[$ - 1];");
                    stack.length--;
                    break;
            }
            break;
            default:
                action = "Push num onto top of stack";
                stack ~= to!real(tok);
        }
        writefln("%3s    %-26s  %s", tok, action, stack);
    }
    writeln("\nThe final value is ", stack[0]);
}


;; RPN (postfix) evaluator

(lib 'hash)

(define OPS (make-hash))
(hash-set OPS "^" expt)
(hash-set OPS "*" *)
(hash-set OPS "/" //) ;; float divide
(hash-set OPS "+" +)
(hash-set OPS "-" -)

(define (op? op) (hash-ref OPS op))

;; algorithm : https://en.wikipedia.org/wiki/Reverse_Polish_notation#Postfix_algorithm

(define (calculator rpn S)
	(for ((token rpn))
	(if (op? token)
		(let [(op2 (pop S)) (op1 (pop S))]
			(unless (and op1 op2) (error "cannot calculate expression at:" token))
	    	(push S ((op? token) op1 op2))
	    	(writeln op1 token op2 "→" (stack-top S)))
	    (push S (string->number token))))
	(pop S))

(define (task rpn)
 (define S (stack 'S))
 (calculator (text-parse rpn) S ))


open string generic monad io

type OpType = Push | Operate
  deriving Show

type Op = Op (OpType typ) input stack
  deriving Show

parse str = split " " str

eval stack []      = []
eval stack (x::xs) = op :: eval nst xs
  where (op, nst)  = conv x stack
        conv "+"@x = operate x (+)
        conv "-"@x = operate x (-)
        conv "*"@x = operate x (*)
        conv "/"@x = operate x (/)
        conv "^"@x = operate x (**)
        conv x     = \stack ->
          let n = gread x::stack in
          (Op Push x n, n)
        operate input fn (x::y::ys) =
          let n = (y `fn` x) :: ys in
          (Op Operate input n, n)

print_line (Op typ input stack) = do
  putStr input
  putStr "\t"
  put typ
  putStr "\t\t"
  putLn stack

print ((Op typ input stack)@x::xs) lv = print_line x `seq` print xs (head stack)
print [] lv = lv

print_result xs = do
  putStrLn "Input\tOperation\tStack after"
  res <- return $ print xs 0
  putStrLn ("Result: " ++ show res)

res = parse "3 4 2 * 1 5 - 2 3 ^ ^ / +" |> eval []
print_result res ::: IO


-module(rpn).
-export([eval/1]).

parse(Expression) ->
    parse(string:tokens(Expression," "),[]).

parse([],Expression) ->
    lists:reverse(Expression);
parse(["+"|Xs],Expression) ->
    parse(Xs,[fun erlang:'+'/2|Expression]);
parse(["-"|Xs],Expression) ->
    parse(Xs,[fun erlang:'-'/2|Expression]);
parse(["*"|Xs],Expression) ->
    parse(Xs,[fun erlang:'*'/2|Expression]);
parse(["/"|Xs],Expression) ->
    parse(Xs,[fun erlang:'/'/2|Expression]);
parse(["^"|Xs],Expression) ->
    parse(Xs,[fun math:pow/2|Expression]);
parse([X|Xs],Expression) ->
    {N,_} = string:to_integer(X),
    parse(Xs,[N|Expression]).

%% The expression should be entered as a string of numbers and
%% operators separated by spaces. No error handling is included if
%% another string format is used.
eval(Expression) ->
    eval(parse(Expression),[]).

eval([],[N]) ->
    N;
eval([N|Exp],Stack) when is_number(N) ->
    NewStack = [N|Stack],
    print(NewStack),
    eval(Exp,NewStack);
eval([F|Exp],[X,Y|Stack]) ->
    NewStack = [F(Y,X)|Stack],
    print(NewStack),
    eval(Exp,NewStack).

print(Stack) ->
    lists:map(fun (X) when is_integer(X) -> io:format("~12.12b ",[X]);
                  (X) when is_float(X) -> io:format("~12f ",[X]) end, Stack),
    io:format("~n").


let reduce op = function
  | b::a::r -> (op a b)::r
  | _ -> failwith "invalid expression"

let interprete s = function
  | "+" -> "add",    reduce ( + ) s
  | "-" -> "subtr",  reduce ( - ) s
  | "*" -> "mult",   reduce ( * ) s
  | "/" -> "divide", reduce ( / ) s
  | "^" -> "exp",    reduce ( ** ) s
  | str -> "push", (System.Double.Parse str) :: s

let interp_and_show s inp =
  let op,s'' = interprete s inp
  printf "%5s%8s " inp op
  List.iter (printf " %-6.3F") (List.rev s'')
  printf "\n";
  s''

let eval str =
  printfn "Token  Action  Stack";
  let ss = str.ToString().Split() |> Array.toList
  List.fold interp_and_show [] ss


: ^ over swap 1 ?do over * loop nip ;
s" 3 4 2 * 1 5 - 2 3 ^ ^ / +" evaluate .


      REAL FUNCTION EVALRP(TEXT)	!Evaluates a Reverse Polish string.
Caution: deals with single digits only.
       CHARACTER*(*) TEXT	!The RPN string.
       INTEGER SP,STACKLIMIT		!Needed for the evaluation.
       PARAMETER (STACKLIMIT = 6)	!This should do.
       REAL*8 STACK(STACKLIMIT)		!Though with ^ there's no upper limit.
       INTEGER L,D		!Assistants for the scan.
       CHARACTER*4 DEED		!A scratchpad for the annotation.
       CHARACTER*1 C		!The character of the moment.
        WRITE (6,1) TEXT	!A function that writes messages... Improper.
    1   FORMAT ("Evaluation of the Reverse Polish string ",A,//	!Still, it's good to see stuff.
     1   "Char Token Action  SP:Stack...")	!Such as a heading for the trace.
        SP = 0			!Commence with the stack empty.
        STACK = -666		!This value should cause trouble.
        DO L = 1,LEN(TEXT)	!Step through the text.
          C = TEXT(L:L)			!Grab a character.
          IF (C.LE." ") CYCLE		!Boring.
          D = ICHAR(C) - ICHAR("0")	!Uncouth test to check for a digit.
          IF (D.GE.0 .AND. D.LE.9) THEN	!Is it one?
            DEED = "Load"			!Yes. So, load its value.
            SP = SP + 1				!By going up one.
            IF (SP.GT.STACKLIMIT) STOP "Stack overflow!"	!Or, maybe not.
            STACK(SP) = D			!And stashing the value.
           ELSE				!Otherwise, it must be an operator.
            IF (SP.LT.2) STOP "Stack underflow!"	!They all require two operands.
            DEED = "XEQ"		!So, I'm about to do so.
            SELECT CASE(C)		!Which one this time?
             CASE("+"); STACK(SP - 1) = STACK(SP - 1) + STACK(SP)	!A + B = B + A, so it is easy.
             CASE("-"); STACK(SP - 1) = STACK(SP - 1) - STACK(SP)	!A is in STACK(SP - 1), B in STACK(SP)
             CASE("*"); STACK(SP - 1) = STACK(SP - 1)*STACK(SP)		!Again, order doesn't count.
             CASE("/"); STACK(SP - 1) = STACK(SP - 1)/STACK(SP)		!But for division, A/B becomes A B /
             CASE("^"); STACK(SP - 1) = STACK(SP - 1)**STACK(SP)	!So, this way around.
             CASE DEFAULT		!This should never happen!
              STOP "Unknown operator!"	!If the RPN script is indeed correct.
            END SELECT			!So much for that operator.
            SP = SP - 1		!All of them take two operands and make one.
          END IF		!So much for that item.
          WRITE (6,2) L,C,DEED,SP,STACK(1:SP)	!Reveal the state now.
    2     FORMAT (I4,A6,A7,I4,":",66F14.6)	!Aligned with the heading of FORMAT 1.
        END DO			!On to the next symbol.
        EVALRP = STACK(1)	!The RPN string being correct, this is the result.
      END	!Simple enough!

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


#define NULL 0

type node
    'implement the stack as a linked list
    n as double
    p as node ptr
end type

function spctok( byref s as string ) as string
    'returns everything in the string up to the first space
    'modifies the original string to begin at the fist non-space char after the first space
    dim as string r
    dim as double i = 1
    while mid(s,i,1)<>" " and i<=len(s)
        r += mid(s,i,1)
        i+=1
    wend
    do
        i+=1
    loop until mid(s,i,1)<>" " or i >= len(s)
    s = right(s,len(s)-i+1)
    return r
end function

sub print_stack( byval S as node ptr )
    'display everything on the stack
    print "Stack   <---   ";
    while S->p <> NULL
        S = S->p
        print S->n;"   ";
    wend
    print
end sub

sub push( byval S as node ptr, v as double )
    'push a value onto the stack
    dim as node ptr x
    x = allocate(sizeof(node))
    x->n = v
    x->p = S->p
    S->p = x
end sub

function pop( byval S as node ptr ) as double
    'pop a value from the stack
    if s->P = NULL then return -99999
    dim as double r = S->p->n
    dim as node ptr junk = S->p
    S->p = S->p->p
    deallocate(junk)
    return r
end function

dim as string s = "3 4 2 * 1 5 - 2 3 ^ ^ / +", c
dim as node StackHead

while len(s) > 0
    c = spctok(s)
    print "Token: ";c;"  ";
    select case c
        case "+"
            push(@StackHead, pop(@StackHead) + pop(@StackHead))
            print "Operation +     ";
        case "-"
            push(@StackHead, -(pop(@StackHead) - pop(@StackHead)))
            print "Operation -     ";
        case "/"
            push(@StackHead, 1./(pop(@StackHead) / pop(@StackHead)))
            print "Operation /     ";
        case "*"
            push(@StackHead, pop(@StackHead) * pop(@StackHead))
            print "Operation *     ";
        case "^"
            push(@StackHead, pop(@StackHead) ^ pop(@StackHead))
            print "Operation ^     ";
        case else
            push(@StackHead, val(c))
            print "Operation push  ";
    end select
    print_stack(@StackHead)
wend


def evaluate( expr ) =
  stack = []

  for token <- expr.split( '''\s+''' )
    case number( token )
      Some( n ) ->
        stack = n : stack
        println( "push $token: ${stack.reversed()}" )
      None ->
        case {'+': (+), '-': (-), '*': (*), '/': (/), '^': (^)}.>get( token )
          Some( op ) ->
            stack = op( stack.tail().head(), stack.head() ) : stack.tail().tail()
            println( "perform $token: ${stack.reversed()}" )
          None -> error( "unrecognized operator '$token'" )

  stack.head()

res = evaluate( '3 4 2 * 1 5 - 2 3 ^ ^ / +' )
println( res + (if res is Integer then '' else " or ${float(res)}") )


package main

import (
    "fmt"
    "math"
    "strconv"
    "strings"
)

var input = "3 4 2 * 1 5 - 2 3 ^ ^ / +"

func main() {
    fmt.Printf("For postfix %q\n", input)
    fmt.Println("\nToken            Action            Stack")
    var stack []float64
    for _, tok := range strings.Fields(input) {
        action := "Apply op to top of stack"
        switch tok {
        case "+":
            stack[len(stack)-2] += stack[len(stack)-1]
            stack = stack[:len(stack)-1]
        case "-":
            stack[len(stack)-2] -= stack[len(stack)-1]
            stack = stack[:len(stack)-1]
        case "*":
            stack[len(stack)-2] *= stack[len(stack)-1]
            stack = stack[:len(stack)-1]
        case "/":
            stack[len(stack)-2] /= stack[len(stack)-1]
            stack = stack[:len(stack)-1]
        case "^":
            stack[len(stack)-2] =
                math.Pow(stack[len(stack)-2], stack[len(stack)-1])
            stack = stack[:len(stack)-1]
        default:
            action = "Push num onto top of stack"
            f, _ := strconv.ParseFloat(tok, 64)
            stack = append(stack, f)
        }
        fmt.Printf("%3s    %-26s  %v\n", tok, action, stack)
    }
    fmt.Println("\nThe final value is", stack[0])
}


def evaluateRPN(expression) {
    def stack = [] as Stack
    def binaryOp = { action -> return { action.call(stack.pop(), stack.pop()) } }
    def actions = [
        '+': binaryOp { a, b -> b + a },
        '-': binaryOp { a, b -> b - a },
        '*': binaryOp { a, b -> b * a },
        '/': binaryOp { a, b -> b / a },
        '^': binaryOp { a, b -> b ** a }
    ]
    expression.split(' ').each { item ->
        def action = actions[item] ?: { item as BigDecimal }
        stack.push(action.call())

        println "$item: $stack"
    }
    assert stack.size() == 1 : "Unbalanced Expression: $expression ($stack)"
    stack.pop()
}


calcRPN :: String -> [Double]
calcRPN = foldl interprete [] . words

interprete s x
  | x `elem` ["+","-","*","/","^"] = operate x s
  | otherwise = read x:s
  where
    operate op (x:y:s) = case op of
      "+" -> x + y:s
      "-" -> y - x:s
      "*" -> x * y:s
      "/" -> y / x:s
      "^" -> y ** x:s


procedure main()
   EvalRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +")
end

link printf
invocable all

procedure EvalRPN(expr)          #: evaluate (and trace stack) an RPN string

   stack := []
   expr ? until pos(0) do {
      tab(many(' '))                         # consume previous seperator
      token := tab(upto(' ')|0)              # get token
      if token := numeric(token) then {      # ... numeric
         push(stack,token)
         printf("pushed numeric   %i : %s\n",token,list2string(stack))
         }
      else {                                 # ... operator
         every b|a := pop(stack)             # pop & reverse operands
         case token of {
            "+"|"-"|"*"|"^"   : push(stack,token(a,b))
            "/"               : push(stack,token(real(a),b))
            default           : runerr(205,token)
            }
         printf("applied operator %s : %s\n",token,list2string(stack))
         }
   }
end

procedure list2string(L)         #: format list as a string
   every (s := "[ ") ||:= !L || " "
   return s || "]"
end


   a: , <;._1 ' ' , '3 4 2 * 1 5 - 2 3 ^ ^ / +'
┌┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
││3│4│2│*│1│5│-│2│3│^│^│/│+│
└┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘


import java.util.LinkedList;

public class RPN{
	public static void main(String[] args) {
		evalRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +");
	}

	private static void evalRPN(String expr){
		LinkedList<Double> stack = new LinkedList<Double>();
		System.out.println("Input\tOperation\tStack after");
		for (String token : expr.split("\\s")){
			System.out.print(token + "\t");
			if (token.equals("*")) {
				System.out.print("Operate\t\t");
				double secondOperand = stack.pop();
				double firstOperand = stack.pop();
				stack.push(firstOperand * secondOperand);
			} else if (token.equals("/")) {
				System.out.print("Operate\t\t");
				double secondOperand = stack.pop();
				double firstOperand = stack.pop();
				stack.push(firstOperand / secondOperand);
			} else if (token.equals("-")) {
				System.out.print("Operate\t\t");
				double secondOperand = stack.pop();
				double firstOperand = stack.pop();
				stack.push(firstOperand - secondOperand);
			} else if (token.equals("+")) {
				System.out.print("Operate\t\t");
				double secondOperand = stack.pop();
				double firstOperand = stack.pop();
				stack.push(firstOperand + secondOperand);
			} else if (token.equals("^")) {
				System.out.print("Operate\t\t");
				double secondOperand = stack.pop();
				double firstOperand = stack.pop();
				stack.push(Math.pow(firstOperand, secondOperand));
			} else {
				System.out.print("Push\t\t");
				try {
					stack.push(Double.parseDouble(token+""));
				} catch (NumberFormatException e) {
    					System.out.println("\nError: invalid token " + token);
    					return;
				}
			}
			System.out.println(stack);
		}
		if (stack.size() > 1) {
			System.out.println("Error, too many operands: " + stack);
			return;
		}
		System.out.println("Final answer: " + stack.pop());
	}
}


const e = '3 4 2 * 1 5 - 2 3 ^ ^ / +';
const s = [], tokens = e.split(' ');
for (const t of tokens) {
  const n = Number(t);
  if (!isNaN(n)) {
    s.push(n);
  } else {
    if (s.length < 2) {
      throw new Error(`${t}: ${s}: insufficient operands.`);
    }
    const o2 = s.pop(), o1 = s.pop();
    switch (t) {
      case '+': s.push(o1 + o2); break;
      case '-': s.push(o1 - o2); break;
      case '*': s.push(o1 * o2); break;
      case '/': s.push(o1 / o2); break;
      case '^': s.push(Math.pow(o1, o2)); break;
      default: throw new Error(`Unrecognized operator: [${t}]`);
    }
  }
  console.log(`${t}: ${s}`);
}

if (s.length > 1) {
  throw new Error(`${s}: insufficient operators.`);
}


function rpn(s)
    stack = Any[]
    for op in map(eval, map(parse, split(s)))
        if isa(op, Function)
            arg2 = pop!(stack)
            arg1 = pop!(stack)
            push!(stack, op(arg1, arg2))
        else
            push!(stack, op)
        end
        println("$op: ", join(stack, ", "))
    end
    length(stack) != 1 && error("invalid RPN expression $s")
    return stack[1]
end
rpn("3 4 2 * 1 5 - 2 3 ^ ^ / +")


// version 1.1.2

fun rpnCalculate(expr: String) {
    if (expr.isEmpty()) throw IllegalArgumentException("Expresssion cannot be empty")
    println("For expression = $expr\n")
    println("Token           Action             Stack")
    val tokens = expr.split(' ').filter { it != "" }
    val stack = mutableListOf<Double>()
    for (token in tokens) {
        val d = token.toDoubleOrNull()
        if (d != null) {
            stack.add(d)
            println(" $d   Push num onto top of stack  $stack")
        }
        else if ((token.length > 1) || (token !in "+-*/^")) {
            throw IllegalArgumentException("$token is not a valid token")
        }
        else if (stack.size < 2) {
            throw IllegalArgumentException("Stack contains too few operands")
        }
        else {
            val d1 = stack.removeAt(stack.lastIndex)
            val d2 = stack.removeAt(stack.lastIndex)
            stack.add(when (token) {
                "+"  -> d2 + d1
                "-"  -> d2 - d1
                "*"  -> d2 * d1
                "/"  -> d2 / d1
                else -> Math.pow(d2, d1)
            })
            println(" $token     Apply op to top of stack    $stack")
        }
    }
    println("\nThe final value is ${stack[0]}")
}

fun main(args: Array<String>) {
    val expr = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
    rpnCalculate(expr)
}


{calc 3 4 2 * 1 5 - 2 3 pow pow / +}
->
 3:
 4: 3
 2: 4 3
 *: 2 4 3
 1: 8 3
 5: 1 8 3
 -: 5 1 8 3
 2: -4 8 3
 3: 2 -4 8 3
 pow: 3 2 -4 8 3
 pow: 8 -4 8 3
 /: 65536 8 3
 +: 0.0001220703125 3
 -> 3.0001220703125

where

{def calc
 {def calc.r
  {lambda {:x :s}
   {if {empty? :x}
    then -> {car :s}
    else {car :x}: {disp :s}{br}
         {calc.r {cdr :x}
                 {if {unop? {car :x}}
                  then {cons {{car :x} {car :s}} {cdr :s}}
                  else {if {binop? {car :x}}
                  then {cons {{car :x} {car {cdr :s}} {car :s}} {cdr {cdr :s}}}
                  else {cons {car :x} :s}} }}}}}
 {lambda {:s}
  {calc.r {list :s} nil}}}

using the unop? & binop? functions to test unary and binary operators

{def unop?
 {lambda {:op}
  {or {W.equal? :op sqrt}       // n sqrt  sqrt(n)
      {W.equal? :op exp}        // n exp   exp(n)
      {W.equal? :op log}        // n log   log(n)
      {W.equal? :op cos}        // n cos   cos(n)
      ... and so                // ...
}}}

{def binop?
 {lambda {:op}
  {or {W.equal? :op +}          // m n +     m+n
      {W.equal? :op -}          // m n -     m-n
      {W.equal? :op *}          // m n *     m*n
      {W.equal? :op /}          // m n /     m/n
      {W.equal? :op %}          // m n %     m%n
      {W.equal? :op pow}        // m n pow   m^n
      ... and so on             // ...
}}}

and  the list, empty? and disp functions to create
a list from a string, test its emptynes and display it.

{def list
 {lambda {:s}
  {if {W.empty? {S.rest :s}}
   then {cons {S.first :s} nil}
   else {cons {S.first :s} {list {S.rest :s}}}}}}

{def empty?
 {lambda {:x}
  {W.equal? :x nil}}}

{def disp
 {lambda {:l}
  {if {empty? :l}
   then
   else {car :l} {disp {cdr :l}}}}}

Note that everything is exclusively built on 5 lambdatalk primitives:
- "cons, car, cdr", to create lists,
- "W.equal?" which test the equality between two words,
- and the "or" boolean function.


global stack$

expr$ = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
print "Expression:"
print expr$
print

print "Input","Operation","Stack after"

stack$=""
token$ = "#"
i = 1
token$ = word$(expr$, i)
token2$ = " "+token$+" "

do
    print "Token ";i;": ";token$,
    select case
    'operation
    case instr("+-*/^",token$)<>0
        print "operate",
        op2$=pop$()
        op1$=pop$()
        if op1$=""  then
            print "Error: stack empty for ";i;"-th token: ";token$
            end
        end if

        op1=val(op1$)
        op2=val(op2$)

        select case token$
        case "+"
            res = op1+op2
        case "-"
            res = op1-op2
        case "*"
            res = op1*op2
        case "/"
            res = op1/op2
        case "^"
            res = op1^op2
        end select

        call push str$(res)
    'default:number
    case else
        print "push",
        call push token$
    end select
    print "Stack: ";reverse$(stack$)
    i = i+1
    token$ = word$(expr$, i)
    token2$ = " "+token$+" "
loop until token$ =""

res$=pop$()
print
print "Result:" ;res$
extra$=pop$()
if extra$<>"" then
    print "Error: extra things on a stack: ";extra$
end if
end

'---------------------------------------
function reverse$(s$)
    reverse$ = ""
    token$="#"
    while token$<>""
        i=i+1
        token$=word$(s$,i,"|")
        reverse$ = token$;" ";reverse$
    wend
end function
'---------------------------------------
sub push s$
    stack$=s$+"|"+stack$    'stack
end sub

function pop$()
    'it does return empty on empty stack
    pop$=word$(stack$,1,"|")
    stack$=mid$(stack$,instr(stack$,"|")+1)
end function


local stack = {}
function push( a ) table.insert( stack, 1, a ) end
function pop()
    if #stack == 0 then return nil end
    return table.remove( stack, 1 )
end
function writeStack()
    for i = #stack, 1, -1 do
        io.write( stack[i], " " )
    end
    print()
end
function operate( a )
    local s
    if a == "+" then
        push( pop() + pop() )
        io.write( a .. "\tadd\t" ); writeStack()
    elseif a == "-" then
        s = pop(); push( pop() - s )
        io.write( a .. "\tsub\t" ); writeStack()
    elseif a == "*" then
        push( pop() * pop() )
        io.write( a .. "\tmul\t" ); writeStack()
    elseif a == "/" then
        s = pop(); push( pop() / s )
        io.write( a .. "\tdiv\t" ); writeStack()
    elseif a == "^" then
        s = pop(); push( pop() ^ s )
        io.write( a .. "\tpow\t" ); writeStack()
    elseif a == "%" then
        s = pop(); push( pop() % s )
        io.write( a .. "\tmod\t" ); writeStack()
    else
        push( tonumber( a ) )
        io.write( a .. "\tpush\t" ); writeStack()
    end
end
function calc( s )
    local t, a = "", ""
    print( "\nINPUT", "OP", "STACK" )
    for i = 1, #s do
        a = s:sub( i, i )
        if a == " " then operate( t ); t = ""
        else t = t .. a
        end
    end
    if a ~= "" then operate( a ) end
    print( string.format( "\nresult: %.13f", pop() ) )
end
--[[ entry point ]]--
calc( "3 4 2 * 1 5 - 2 3 ^ ^ / +" )
calc( "22 11 *" )


Module Rpn_Calc {
	Rem Form 80,60
	function rpn_calc(a$) {
		def m=0
		dim token$()
		token$()=piece$(a$," ")
		l=len(token$())
		dim type(l)=0, reg(l)
		where=-1
		for i=0 to  l-1
			c=val(token$(i),"",m)
			if m>-1 then
				where++
				reg(where)=c
			else
				reg(where-1)=eval(str$(reg(where-1))+token$(i)+str$(reg(where)))
				where--
			end if
			inf=each(reg(),1, where+1)
			while inf
				export$<=token$(i)+" ["+str$(inf^,"")+"] "+ str$(array(inf))+{
				}
				token$(i)=" "
			end while
		next i
		=reg(0)
	}
	Global export$
	document export$
	example1=rpn_calc("3 4 2 * 1 5 - 2 3 ^ ^ / +")
	example2=rpn_calc("1 2 + 3 4 + ^ 5 6 + ^")
	Print example1, example2
	Rem Print #-2, Export$
	ClipBoard Export$
}
Rpn_Calc


calc[rpn_] :=
  Module[{tokens = StringSplit[rpn], s = "(" <> [email protected]@# <> ")" &, op, steps},
   op[o_, x_, y_] := ToExpression[[email protected] <> o <> [email protected]];
   steps = FoldList[Switch[#2, _?DigitQ, Append[#, FromDigits[#2]],
        _, Append[#[[;; -3]], op[#2, #[[-2]], #[[-1]]]]
        ] &, {}, tokens][[2 ;;]];
   Grid[Transpose[{# <> ":" & /@ tokens,
      StringRiffle[ToString[#, InputForm] & /@ #] & /@ steps}]]];
Print[calc["3 4 2 * 1 5 - 2 3 ^ ^ / +"]];


rmod(i, j) := mod(j, i)$
rpow(x, y) := y^x$

rpn(sexpr) := (
    operands: [],
    expr: charlist(sexpr),

    for token in expr do (
        if token = "+" then (
            push(pop(operands) + pop(operands), operands)
        )
        elseif token = "-" then (
            push(-1 * (pop(operands) - pop(operands)), operands)
        )
        elseif token = "*" then (
            push(pop(operands) * pop(operands), operands)
        )
        elseif token = "/" then (
            push(1 / (pop(operands) / pop(operands)), operands)
        )
        elseif token = "%" then (
            push(rmod(pop(operands), pop(operands)), operands)
        )
        elseif token = "^" then (
            push(rpow(pop(operands), pop(operands)), operands)
        )
        elseif token # " " then (
            push(parse_string(token), operands)
        ),

        if token # " " then (
            print(token, " : ", operands)
        )
    ),

    pop(operands)
)$

rpn("3 4 2 * 1 5 - 2 3 ^ ^ / +"), numer;


RPN = function(inputText)
    tokens = inputText.split
    stack = []
    while tokens
        tok = tokens.pull
        if "+-*/^".indexOf(tok) != null then
            b = stack.pop
            a = stack.pop
            if tok == "+" then stack.push a + b
            if tok == "-" then stack.push a - b
            if tok == "*" then stack.push a * b
            if tok == "/" then stack.push a / b
            if tok == "^" then stack.push a ^ b
        else
            stack.push val(tok)
        end if
        print tok + " --> " + stack
    end while
    return stack[0]
end function

print RPN("3 4 2 * 1 5 - 2 3 ^ ^ / +")


.ig
    RPN parser implementation in TROFF

..
.\" \(*A stack implementation
.nr Ac 0
.af Ac 1
.de APUSH
.if (\\n(Ac>=0)&(\\n(Ac<27) \{ \
.	nr Ac +1
.	af Ac A
.	nr A\\n(Ac \\$1
.	af Ac 1
\}
..
.de APOP
.if (\\n(Ac>0)&(\\n(Ac<27) \{ \
.	af Ac A
.	rr A\\n(Ac \\$1
.	af Ac 1
.	nr Ac -1
..
.\" Facility to print entire stack
.de L2
.af Ac 1
.if \\n(Li<=\\n(Ac \{ \
.	af Li A
\\n(A\\n(Li
.	af Li 1
.	nr Li +1
.	L2
\}
..
.de APRINT
.nr Li 1
.L2
.br
..
.\" Integer exponentiation algorithm
.de L1
.if \\n(Li<\\$2 \{ \
.	nr Rs \\n(Rs*\\$1
.	nr Li +1
.	L1 \\$1 \\$2
\}
..
.de EXP
.nr Li 0
.nr Rs 1
.L1 \\$1 \\$2
..
.\" RPN Parser
.de REAP
.af Ac A
.nr O2 \\n(A\\n(Ac
.af Ac 1
.nr Ai \\n(Ac-1
.af Ai A
.nr O1 \\n(A\\n(Ai
.APOP
.APOP
..
.de RPNPUSH
.ie '\\$1'+' \{ \
.	REAP
.	nr Rs \\n(O1+\\n(O2
\}
.el \{ \
.	ie '\\$1'-' \{ \
.		REAP
.		nr Rs \\n(O1-\\n(O2
\}
.	el \{ \
.		ie '\\$1'*' \{ \
.			REAP
.			nr Rs \\n(O1*\\n(O2
\}
.		el \{ \
.			ie '\\$1'/' \{ \
.				REAP
.				nr Rs \\n(O1/\\n(O2
\}
.			el \{ \
.				ie '\\$1'%' \{ \
.					REAP
.					nr Rs \\n(O1%\\n(O2
\}
.				el \{ \
.					ie '\\$1'^' \{ \
.						REAP
.						EXP \\n(O1 \\n(O2
\}
.					el .nr Rs \\$1
\}
\}
\}
\}
\}
.APUSH \\n(Rs
.APRINT
..
.de RPNPRINT
.if \\n(Ac>1 .tm ERROR (rpn.roff): Malformed input expression. Evaluation stack size: \\n(Ac > 1 .
\\n(AA
..
.de RPNPARSE
.RPNPUSH \\$1
.ie \\n(.$>1 \{ \
.	shift
.	RPNPARSE \\[email protected]
\}
.el .RPNPRINT
..
.RPNPARSE 3 4 2 * 1 5 - 2 3 ^ ^ / + \" Our input expression


/* NetRexx */
options replace format comments java crossref symbols nobinary

numeric digits 20

rpnDefaultExpression = '3 4 2 * 1 5 - 2 3 ^ ^ / +'
EODAD = '.*'

parse arg rpnString

if rpnString = '.' then rpnString = rpnDefaultExpression
if rpnString = '' then do
  say 'Enter numbers or operators [to stop enter' EODAD']:'
  loop label rpnloop forever
    rpnval = ask
    if rpnval == EODAD then leave rpnloop
    rpnString = rpnString rpnval
    end rpnloop
  end

rpnString = rpnString.space(1)
say rpnString':' evaluateRPN(rpnString)

return

-- -----------------------------------------------------------------------------
method evaluateRPN(rpnString) public static returns Rexx

  stack = LinkedList()
  op = 0
  L = 'L'
  R = 'R'
  rpnString = rpnString.strip('b')
  say 'Input\tOperation\tStack after'
  loop label rpn while rpnString.length > 0
    parse rpnString token rest
    rpnString = rest.strip('b')
    say token || '\t\-'
    select label tox case token
      when '*' then do
        say 'Operate\t\t\-'
        op[R] = Rexx stack.pop()
        op[L] = Rexx stack.pop()
        stack.push(op[L] * op[R])
        end
      when '/' then do
        say 'Operate\t\t\-'
        op[R] = Rexx stack.pop()
        op[L] = Rexx stack.pop()
        stack.push(op[L] / op[R])
        end
      when '+' then do
        say 'Operate\t\t\-'
        op[R] = Rexx stack.pop()
        op[L] = Rexx stack.pop()
        stack.push(op[L] + op[R])
        end
      when '-' then do
        say 'Operate\t\t\-'
        op[R] = Rexx stack.pop()
        op[L] = Rexx stack.pop()
        stack.push(op[L] - op[R])
        end
      when '^' then do
        say 'Operate\t\t\-'
        op[R] = Rexx stack.pop()
        op[L] = Rexx stack.pop()
        -- If exponent is a whole number use Rexx built-in exponentiation operation, otherwise use Math.pow()
        op[R] = op[R] + 0
        if op[R].datatype('w') then stack.push(op[L] ** op[R])
        else stack.push(Rexx Math.pow(op[L], op[R]))
        end
      otherwise do
        if token.datatype('n') then do
          say 'Push\t\t\-'
          stack.push(token)
          end
        else do
          say 'Error\t\t\-'
          end
        end
      end tox
      calc = Rexx
      say stack.toString
    end rpn
    say
    calc = stack.toString
  return calc


import math, rdstdin, strutils, tables

type Stack = seq[float]

proc opPow(s: var Stack) =
  let b = s.pop
  let a = s.pop
  s.add a.pow b

proc opMul(s: var Stack) =
  let b = s.pop
  let a = s.pop
  s.add a * b

proc opDiv(s: var Stack) =
  let b = s.pop
  let a = s.pop
  s.add a / b

proc opAdd(s: var Stack) =
  let b = s.pop
  let a = s.pop
  s.add a + b

proc opSub(s: var Stack) =
  let b = s.pop
  let a = s.pop
  s.add a - b

proc opNum(s: var Stack; num: float) =
  s.add num

let ops = toTable({"^": opPow,
                   "*": opMul,
                   "/": opDiv,
                   "+": opAdd,
                   "-": opSub})

proc getInput(inp = ""): seq[string] =
  var inp = inp
  if inp.len == 0:
    inp = readLineFromStdin "Expression: "
  result = inp.strip.split

proc rpnCalc(tokens: seq[string]): seq[seq[string]] =
  var s: Stack
  result = @[@["TOKEN","ACTION","STACK"]]
  for token in tokens:
    var action = ""
    if ops.hasKey token:
      action = "Apply op to top of stack"
      ops[token](s)
    else:
      action = "Push num onto top of stack"
      s.opNum token.parseFloat
    result.add(@[token, action, s.join(" ")])

let rpn = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
echo "For RPN expression: ", rpn
let rp = rpnCalc rpn.getInput

var maxColWidths = newSeq[int](rp[0].len)
for i in 0 .. rp[0].high:
  for x in rp:
    maxColWidths[i] = max(maxColWidths[i], x[i].len + 3)

for x in rp:
  for i, y in x:
    stdout.write y.alignLeft(maxColWidths[i])
  echo ""


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


(* binop : ('a -> 'a -> 'a) -> 'a list -> 'a list *)
let binop op = function
  | b::a::r -> (op a b)::r
  | _ -> failwith "invalid expression"

(* interp : float list -> string -> string * float list *)
let interp s = function
  | "+" -> "add",    binop ( +. ) s
  | "-" -> "subtr",  binop ( -. ) s
  | "*" -> "mult",   binop ( *. ) s
  | "/" -> "divide", binop ( /. ) s
  | "^" -> "exp",    binop ( ** ) s
  | str -> "push", (float_of_string str) :: s

(* interp_and_show : float list -> string -> float list *)
let interp_and_show s inp =
  let op,s' = interp s inp in
  Printf.printf "%s\t%s\t" inp op;
  List.(iter (Printf.printf "%F ") (rev s'));
  print_newline ();
  s'

(* rpn_eval : string -> float list *)
let rpn_eval str =
  Printf.printf "Token\tAction\tStack\n";
  let ss = Str.(split (regexp_string " ") str) in
  List.fold_left interp_and_show [] ss


/* ooRexx *************************************************************
* 10.11.2012 Walter Pachl  translated from PL/I via REXX
**********************************************************************/
fid='rpl.txt'
ex=linein(fid)
Say 'Input:' ex
/* ex=' 3 4 2 * 1 5 - 2 3 ^ ^ / +' */
Numeric Digits 15
expr=''
st=.circularqueue~new(100)
Say 'Stack contents:'
do While ex<>''
  Parse Var ex ch +1 ex
  expr=expr||ch;
  if ch<>' ' then do
    If pos(ch,'0123456789')>0 Then     /* a digit goes onto stack    */
      st~push(ch)
    Else Do                            /* an operator                */
      op=st~pull                       /* get top element            */
      select                           /* and modify the (now) top el*/
        when ch='+' Then st~push(st~pull +  op)
        when ch='-' Then st~push(st~pull -  op)
        when ch='*' Then st~push(st~pull *  op)
        when ch='/' Then st~push(st~pull /  op)
        when ch='^' Then st~push(st~pull ** op)
        end;
      Say st~string(' ','L')           /* show stack in LIFO order   */
      end
    end
  end
Say 'The reverse polish expression = 'expr
Say 'The evaluated expression = 'st~pull


estack = [];

epush(x) = {
    estack = vector(#estack + 1, i, if(i <= #estack, estack[i], x));
    return(#estack);
};

epop() = {
    local(val = estack[#estack]);
    estack = vector(#estack - 1, i, estack[i]);
    return(val);
};

registerRPNToken(t) = {
    local(o1, o2);

    if(type(t) == "t_STR",
        if(t == "+", o2 = epop(); o1 = epop(); epush(o1 + o2),
        if(t == "-", o2 = epop(); o1 = epop(); epush(o1 - o2),
        if(t == "*", o2 = epop(); o1 = epop(); epush(o1 * o2),
        if(t == "/", o2 = epop(); o1 = epop(); epush(o1 / o2),
        if(t == "%", o2 = epop(); o1 = epop(); epush(o1 % o2),
        if(t == "^", o2 = epop(); o1 = epop(); epush(o1 ^ o2)
        )))))),
    if(type(t) == "t_INT" || type(t) == "t_REAL" || type(t) == "t_FRAC",
        epush(t))
    );
    print(estack);
};

parseRPN(s) = {
    estack = [];
    for(i = 1, #s, registerRPNToken(s[i]));

    if(#estack > 1, error("Malformed postfix expression."));
    return(estack[1]);
};

parseRPN([3, 4, 2, "*", 1, 5, "-", 2, 3, "^", "^", "/", "+"]); \\ Our input expression


use strict;
use warnings;
use feature 'say';

my $number   = '[+-]?(?:\.\d+|\d+(?:\.\d*)?)';
my $operator = '[-+*/^]';

my @tests = ('3 4 2 * 1 5 - 2 3 ^ ^ / +');

for (@tests) {
    while (
        s/ \s* ((?<left>$number))     # 1st operand
           \s+ ((?<right>$number))    # 2nd operand
           \s+ ((?<op>$operator))     # operator
           (?:\s+|$)                  # more to parse, or done?
         /
           ' '.evaluate().' '         # substitute results of evaluation
         /ex
    ) {}
    say;
}

sub evaluate {
  (my $a = "($+{left})$+{op}($+{right})") =~ s/\^/**/;
  say $a;
  eval $a;
}


with javascript_semantics
procedure evalRPN(string s)
    sequence stack = {},
             ops = split(s)
    for i=1 to length(ops) do
        string op = ops[i]
        switch op
            case "+": stack[-2] = stack[-2]+stack[-1]; stack = stack[1..-2]
            case "-": stack[-2] = stack[-2]-stack[-1]; stack = stack[1..-2]
            case "*": stack[-2] = stack[-2]*stack[-1]; stack = stack[1..-2]
            case "/": stack[-2] = stack[-2]/stack[-1]; stack = stack[1..-2]
            case "^": stack[-2] = power(stack[-2],stack[-1]); stack = stack[1..-2]
            default : stack = append(stack,scanf(op,"%d")[1][1])
        end switch
        ?{op,stack}
    end for
end procedure
evalRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +")


<?php
function rpn($postFix){
    $stack = Array();
    echo "Input\tOperation\tStack\tafter\n" ;
	$token = explode(" ", trim($postFix));
	$count = count($token);

    for($i = 0 ; $i<$count;$i++)
	{
        echo $token[$i] ." \t";
        $tokenNum = "";

        if (is_numeric($token[$i])) {
            echo  "Push";
			array_push($stack,$token[$i]);
        }
        else
        {
            echo "Operate";
            $secondOperand = end($stack);
			array_pop($stack);
            $firstOperand = end($stack);
            array_pop($stack);

            if ($token[$i] == "*")
				array_push($stack,$firstOperand * $secondOperand);
            else if ($token[$i] == "/")
                array_push($stack,$firstOperand / $secondOperand);
            else if ($token[$i] == "-")
                array_push($stack,$firstOperand - $secondOperand);
            else if ($token[$i] == "+")
                array_push($stack,$firstOperand + $secondOperand);
            else if ($token[$i] == "^")
                array_push($stack,pow($firstOperand,$secondOperand));
            else {
                die("Error");
            }
        }
		echo "\t\t" . implode(" ", $stack) .  "\n";
    }
    return end($stack);
}

echo "Compute Value: " . rpn("3 4 2 * 1 5 - 2 3 ^ ^ / + ");
?>


(de rpnCalculator (Str)
   (let (^ **  Stack)  # Define '^' from the built-in '**'
      (prinl "Token  Stack")
      (for Token (str Str "*+-/\^")
         (if (num? Token)
            (push 'Stack @)
            (set (cdr Stack)
               ((intern Token) (cadr Stack) (pop 'Stack)) ) )
         (prin Token)
         (space 6)
         (println Stack) )
      (println (car Stack)) ) )


Calculator: procedure options (main);            /* 14 Sept. 2012 */
   declare expression character (100) varying initial ('');
   declare ch character (1);
   declare (stack controlled, operand) float (18);
   declare in file input;

   open file (in) title ('/CALCULAT.DAT,type(text),recsize(100)');
   on endfile (in) go to done;

   put ('Stack contents:');
main_loop:
   do forever;
      get file (in) edit (ch) (a(1));
      expression = expression || ch;
      if ch = ' ' then iterate;
      select (ch);
         when ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
            do; allocate stack; stack = ch; iterate main_loop; end;
         when ('+') do; operand = stack; free stack; stack = stack +  operand; end;
         when ('-') do; operand = stack; free stack; stack = stack -  operand; end;
         when ('*') do; operand = stack; free stack; stack = stack *  operand; end;
         when ('/') do; operand = stack; free stack; stack = stack /  operand; end;
         when ('^') do; operand = stack; free stack; stack = stack ** operand; end;
      end;
      call show_stack;
   end;

done:
   put skip list ('The reverse polish expression = ' || expression);
   put skip list ('The evaluated expression = ' || stack);

end Calculator;


CREATE OR REPLACE FUNCTION rpn_calc(str VARCHAR2) RETURN NUMBER AS
  TYPE  num_aa    IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
  TYPE  num_stack IS RECORD (a num_aa, top PLS_INTEGER DEFAULT 0);
  ns    num_stack;
  pos1  INTEGER := 1;
  pos2  INTEGER;
  token VARCHAR2(100);
  op2   NUMBER;
  PROCEDURE push(s IN OUT NOCOPY num_stack, x NUMBER) IS
    BEGIN
      s.top := s.top + 1;
      s.a(s.top) := x;
    END;
  FUNCTION pop(s IN OUT NOCOPY num_stack) RETURN NUMBER IS
      x NUMBER;
    BEGIN
      x := s.a(s.top);
      s.top := s.top - 1;
      RETURN x;
    END;
  PROCEDURE print_stack(s num_stack) IS  -- for debugging only; remove from final version
      ps VARCHAR2(4000);
    BEGIN
      FOR i IN 1 .. s.top LOOP
        ps := ps || s.a(i) || ' ';
      END LOOP;
      DBMS_OUTPUT.put_line('Stack: ' || RTRIM(ps));
    END;
BEGIN
  WHILE pos1 <= LENGTH(str) LOOP
    pos2  := INSTR(str || ' ', ' ', pos1);
    token := SUBSTR(str, pos1, pos2 - pos1);
    pos1  := pos2 + 1;
    CASE token
         WHEN '+' THEN push(ns, pop(ns) + pop(ns));
         WHEN '-' THEN op2 := pop(ns); push(ns, pop(ns) - op2);
         WHEN '*' THEN push(ns, pop(ns) * pop(ns));
         WHEN '/' THEN op2 := pop(ns); push(ns, pop(ns) / op2);
         WHEN '^' THEN op2 := pop(ns); push(ns, POWER(pop(ns), op2));
         ELSE push(ns, TO_NUMBER(token));
    END CASE;
    print_stack(ns);    -- for debugging purposes only
  END LOOP;
  RETURN pop(ns);
END rpn_calc;
/