#!/usr/bin/env python
# A small RPN calculator program written using decimal.Decimal

from decimal import Decimal
import operator
import math

intro = \
"""A simple reverse-Polish calculator.

In reverse-Polish notation (RPN), numbers are pushed onto a stack
and operators pop the values off, operate on them, and push
results. To push numbers, just enter them separated by spaces.
The top of the stack is printed at the end of each line.
To view the current stack, enter "p".
To clear the stack, enter "c"
"""

def curry(f, *a, **kw): # thanks to Python Cookbook, 2nd ed. (O'Reilly)
    def curried(*more_a, **more_kw):
        return f(*(more_a+a), **dict(kw, **more_kw))
    return curried

def help():
    print intro
    for oper, tup in actiondict.iteritems():
        print oper
        print tup[2]


stack = []

actiondict = {# operator: (nargs, function, helpstr)
              #
              # special case: if nargs == 0, the "function" is treated as a
              # constant and pushed onto the stack
              '+':    (2, operator.add, "Pop two numbers, add them, and push the result"),
              '-':    (2, operator.sub, "Pop two numbers, subtract the first from the second, and push the result"),
              '*':    (2, operator.mul, "Pop two numbers, multiply them, and push the result"),
              '/':    (2, operator.div, "Pop two numbers, divide the second by the first, and push the result"),
              '**':   (2, operator.pow, "Pop two numbers, raise the second to the power of the first, and push the result"),
              '%':    (2, operator.mod, "Pop two numbers, find the second modulo the first, and push the result"),
              'sin':  (1, math.sin, "Pop a number in radians, and push its sine"),
              'cos':  (1, math.cos, "Pop a number in radians, and push its cosine"),
              'tan':  (1, math.tan, "Pop a number in radians, and push its tangent"),
              'exp':  (1, math.exp, "Pop a number and push e to that power"),
              'abs':  (1, math.fabs, "Pop a number and push its absolute value"),
              'sqrt': (1, math.sqrt, "Pop a number and push its square root"),
              'ln':   (1, math.log, "Pop a number and push its log base e"),
              'log':  (1, math.log10, "Pop a number and push its log base 10"),
              'lg':   (1, curry(math.log, 2), "Pop a number and push its log base two"),
              'acos': (1, math.acos, "Pop a number and push its arc cosine in radians"),
              'asin': (1, math.asin, "Pop a number and push its arc sin in radians"),
              'atan': (1, math.atan, "Pop a number and push its arc tangent in radians"),
              'pi':   (0, Decimal(str(math.pi)), "Push pi"),
              'e':    (0, Decimal(str(math.e)),  "Push e"),
             }


def main():
    x = raw_input()
    x = x.split()
    for i in x:
        try:
            Decimal(i)
        except:
            if i == "help":
                help()
                return
            if i == "p":
                for num in stack:
                    print num,
                print
                return
            if i == "c":
                del stack[:]
                return
            if i == "quit" or i == "exit":
                raise SystemExit
            if i not in actiondict:
                print ValueError("Invalid input: %s" % i)
                return


    for index, item in enumerate(x):
        try:
            x[index] = Decimal(item)
        except Exception:
            pass

    for i in x:
        if i in actiondict:
            try:
                if actiondict[i][0] == 2:
                    func = actiondict[i][1]
                    op2 = stack.pop()
                    stack.append(func(stack.pop(), op2))
                elif actiondict[i][0] == 1:
                    func = actiondict[i][1]
                    stack.append(func(stack.pop()))
                elif actiondict[i][0] == 0:
                    obj = actiondict[i][1]
                    stack.append(obj)
            except IndexError:
                print "Not enough items on stack!"
        else:
            stack.append(i)
    try:
        print stack[-1]
    except IndexError:
        pass


print intro + """To see a this message again, along with a list of functions, type "help"\n"""

while True:
    try:
        main()
    except:
        raise SystemExit
