RPN Interpreter

(http://www.gnu.org/copyleft/fdl.html) in the spirit of which this script is GPL'd. Copyright (C) 2013 Subus Tremor
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
This is a reverse polish notation interpreter - it's also called 0-address-machine as it does not need addressable storage locations for it's operation . 
It interprets rpn expressions. (see the code which operands are supported- feel free to change/extend it)
There is no debugging etc. provided.
Create a box, and drop this script in it. Then edit the script and assign a rpn input expression to the input list - or even better :-) add an Input routine to it.
Save the script and touch your box to run the code.
<lsl>
// Simple RPN calculator as lsl plugin sample for my Real Inworld Computer - by Subus Tremor
// made to compare it to the Real Inworld Computers rpn batch domme program notecard
list inlist; // Input as list
list stack; // our stack
push(string val) {
 stack = val + stack;
}
string pop() {
 string ret = llList2String(stack,0);
 stack = llDeleteSubList(stack,0,0);
 return ret;
}
string abop (string a, string b, string func) { // does rout = a op b
 string rout;
 integer iout;
 float fout;
 if((~llSubStringIndex(a,"."))||(~llSubStringIndex(b,"."))) { //float
 float fa = (float)a;
 float fb = (float)b;
 integer fia;
 if(func=="+") fout = fa + fb;
 if(func=="-") fout = fa - fb;
 if(func=="*") fout = fa * fb;
 if(func=="/") fout = fa / fb;
 if(func=="sin") fout = llSin(fa);
 if(func=="cos") fout = llCos(fa);
 if(func=="abs") fout = llFabs(fa);
 rout = (string)fout;
 if(func=="round") {iout = llRound(fa); rout = (string)iout;} 
 }
 else { //integer
 integer ia = (integer)a;
 integer ib = (integer)b;
 if(func=="+") iout = ia + ib;
 if(func=="-") iout = ia - ib;
 if(func=="*") iout = ia * ib;
 if(func=="/") iout = ia / ib;
 if(func=="%") iout = ia % ib;
 if(func=="abs") iout = llAbs(ia);
 if(func=="ceil") iout = llCeil((float)a);
 if(func=="floor") iout = llFloor((float)a);
 rout = (string)iout;
 }
 return rout;
}
// two calculation samples - implement your own clever input providing to the calculator 
list rpntask1 = [ "3", "4", "+", "2", "1", "+", "+", "2", "*", "20", "-"]; // sample 1
 // does: (((3+4)+(2+1))*2)-20
list rpntask2 = [ "3.14", "sin", "0.001593", "/", "1", "-"]; // sample 2
 // does: (sin(3.14)/0.001593)-1
 
default
{
 state_entry() { // provide some input to the calculator
 inlist = rpntask2;
 }
 touch_start(integer num_detected) { // start calculation when touched
 state running;
 } 
}
state running
{
 state_entry() { //RPN calculation :-) do what we have to do while we are active
 integer inpointer=0; // point to an item in inlist 
 string _out; // the special variable _out
 string b; // the second operator variable
 string _last; // keep the last input token till calculation
 //by intention written with jumps to make it compareable to the rpn domme program - the batch language of my Inworld computers
 @next;
 _out=llList2String(inlist,inpointer); // take next
 _last=_out;
 inpointer++;
 if(_out=="") jump end;
 if(llSubStringIndex("+-*/%",_out)>=0) jump args2; // ifin _out +-*/% args2
 if(llSubStringIndex("sincosroundceilfloor",_out)>=0) jump args1; // ifin _out sincosroundceilfloor args1
 push(_out); // push _out
 jump next;
 @args2;
 b=pop(); // pop , var b _out
 @args1;
 _out=pop(); // pop
 _out=abop(_out,b,_last);// abop _out b _last
 llSay(0,_out); // out
 push(_out); // push _out
 jump next;
 @end;
 llSay(0,"RPN calculation finished"); // finished
 llResetScript();
 } 
}
</lsl>