Interpret StackyMath! Time for you to implement my new stack based language! It's called StackyMath. This will be a stack based language with 8 operations on the stack and ways to add numbers to the stack.

List of operations:


/: Division. Performed on the top 2 numbers of the stack. Pushes the result back on the stack.
*: Multiplication. Performed on the top 2 numbers of the stack. Pushes the result back on the stack
-: Subtraction. Performed on the top 2 numbers of the stack. Pushes the result back on the stack
+: Addition. Performed on the top 2 numbers of the stack. Pushes the result back on the stack
^: Exponentiation. Performed on the top 2 numbers of the stack. Pushes the result back on the stack
%: Modulo. Performed on the top 2 numbers of the stack. Pushes the result back on the stack
!: Factorial. Performed on the top number on the stack. Pushes the result back on the stack
D: Duplicate the top number on the stack


Operations defined in pseudo code:


/: push(pop divided by pop)
*: push(pop times pop)
-: push(pop minus pop)
+: push(pop plus pop)
^: push(pop to the pop)
%: push(pop mod pop)
!: push(factorial pop)
D: t = pop; push(t); push(t)


How to push numbers to the stack:

Adding numbers to the stack is easy, just put the raw number in your program where you need it. If you need to put multiple numbers on the stack you can separate them with a comma (,). Your program will not need to process - numbers in the input, If the user wants one they should push the number they want negated, zero, and -. Numbers in the input of the program are also constrained to positive integers.

Input:

Your program should take the input on the command line, or from std in. Input will only consist of numbers (no scientific notation or decimals) delimited by , as needed, and the operations defined above.

Output:

Your program should print the number on the top of the stack.

Error cases:


If the program tries to over-pop the stack, you should print StackUnderflowException!!! . 
If you have division by zero, print DivisionByZeroException!!!
If a number that exceeds 64-bits, either while executing the program or processing a number in the input, print NumberOverflowException!!!
If somehow you get a negative number on the top of the stack and you need to do a factorial, print NegativeFactorialException!!!
If you have a floating point number on the tops of the stack and the next operation is factorial, print FloatingFactorialException!!!
If no numbers are on the stack when the program exits (i.e. the program was empty) print EmptyProgram!!!


Notes:


All error output to should got yo std err or closest equivalent.
All numbers are constrained to 64-bit floating point.


Example programs:

50,47*                 -&gt; 2350
50,47/                 -&gt; 0.94
100,8!                 -&gt; 40320  
100D*                  -&gt; 10000
!                      -&gt; StackUnderflowException!!!
5,2/!                  -&gt; FloatingFactorialException!!!  
4,3!2*/                -&gt; 3 
654,489,48,43/5*7D+-*% -&gt; 77.68749999999909
                       -&gt; EmptyProgram!!!


(I can add more if needed)
Ruby, 412 410 404 392 380 377 characters

def e m,x='Exception';warn m+x+?!*3;exit;end
def o;e'StackUnderflow'if$*==[];$*.pop;end
u=-&gt;n{e'DivisionByZero'if n.infinite?;e'NumberOverflow'if n&gt;2**64;$*&lt;&lt;n}
f=-&gt;n{e'NegativeFactorial'if n&lt;0;e'FloatingFactorial'if n.to_i&lt;n;n&lt;2?1:f[n-1]*n}
gets.gsub(/(\d+)|([+*\/%^-])|(!)|D/){$1?u[$1.to_f]:$2?u[eval"o#{$2&gt;?A?:**:$2}o"]:$3?u[f[o]]:u[x=o]+u[x]}
e'EmptyProgram',''if$*==[]
p o


This is regular precision version using Float. The result precision is as in the sample code, but numeric overflow detection is not exact.

Sample run:

bash-4.3$ ruby StackyMath.rb &lt;&lt;&lt; '654,489,48,43/5*7D+-*%'
77.68749999999909


Ruby, 378 377 characters

def e m,x='Exception';warn m+x+?!*3;exit;end
def o;e'StackUnderflow'if$*==[];$*.pop;end
u=-&gt;n{e'NumberOverflow'if n&gt;2**64;$*&lt;&lt;n}
f=-&gt;n{e'NegativeFactorial'if n&lt;0;e'FloatingFactorial'if n.to_i&lt;n;n&lt;2?1:f[n-1]*n}
gets.gsub(/(\d+)|([+*\/%^-])|(!)|D/){$1?u[Rational$1]:$2?u[eval"o#{$2&gt;?A?:**:$2}o"]:$3?u[f[o]]:u[x=o]+u[x]}rescue e'DivisionByZero'
e'EmptyProgram',''if$*==[]
p o.to_f


This is high precision version using Rational. The result precision is not always the same as in the sample code, but numeric overflow detection is exact.

Sample run:

bash-4.3$ ruby StackyMath-hi.rb &lt;&lt;&lt; '654,489,48,43/5*7D+-*%'
77.6875