I made a tweet sized rpn calculator, available here. Here’s the code with no formatting:

function rpn(t,s){for(s=[],t=t.split(' '),i=0;c=t[i++];)s.push((n=parseFloat(c))?n:eval(s.splice(-2,1)[0]+c[0]+s.pop()));return s;}

Here’s a breakdown of the code:

function rpn(t,s){

Nothing much to see here. `t`

is the input string and `s`

is the stack,
defined here for reasons shown later.

for(s=[],t=t.split(' '),i=0;c=t[i++];)

This is the main loop, `s`

is initialised and `t`

is split into tokens.
The tokens are iterated over and the current token is stored in `c`

. This
loop works because in javascript strings are ‘truthy’, so the
loop will continue until c becomes undefined (which happens when i is larger
than the length of the token list.)

As an aside, note that the value of ‘`a = 12`

’ is `12`

and the
value of ‘`var a = 12`

’ is `undefined`

. This is what allows
‘`c=t[i++]`

’ to work.

s.push(...);

Something is always pushed to the stack, either a result or a new value.

(n=parseFloat(c))`<br />`?n:`<br />`eval(s.splice(-2,1)[0]+c[0]+s.pop())

First, try and parse a float from the token, if this worked push it to
the stack and continue the loop. Otherwise, `eval`

the second topmost value
on the stack, plus the first character of the current token, plus the
topmost value on the stack and push the result to the stack.
This means if the stack is `[1, 2]`

and the current operator is `+`

we run
‘`eval('1+2')`

’.

return s;}

Return the stack. This is why s needed to be defined as an argument to the function. If it was defined in the loop like our other variables it wouldn’t be avilable here.

There you have it, a tiny rpn calculator that’s not very safe.

2013-11-14