Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

YAC, Yet Another Calculator; RPN

Mikhail Pasternak
Registered User
Join date: 1 Oct 2005
Posts: 54
01-19-2007 12:50
CODE
// YAC, Yet Another Calculator
// by Mikhail Pasternak
// Jan 26, 2007
//
// An RPN Calculator
//
// Enter operands and operators by chat (0); the stack is displayed with floating text above the calculator; other communications are sent to owner by llOwnerSay().
// Note that all operands and operators must be separated spaces by or commas.
// Look at the else-if lists of execute_basic_command(), execute_misc_command(), execute_trig_command() to see what operators are available
// To list x, y, z, s in Chat, use the operator "say" (good for cut and paste)
//
// See "RPN Calculator Instructions" - IM Mikhail Pasternak
//

integer TIME_SECONDS = 600 ; // Time that script turns off from non-use
vector color_vector = <1.0, 1.0, 1.0> ; // Color of floating text
float color_alpha = 1.0 ; // Opacity of floating text

integer handle = 0 ;

float E_constant = 2.718281 ;
float trig_arg_mult ;
float trig_result_mult ;
integer Xflag ;

float stack_0 ;
float stack_1 ;
float stack_2 ;
float stack_3 ;

float memory_0 ;
float memory_1 ;
float memory_2 ;
float memory_3 ;

drop()
{
stack_0 = stack_1 ;
stack_1 = stack_2 ;
stack_2 = stack_3 ;
}

push(float value) // Push float onto stack
{
stack_3 = stack_2 ;
stack_2 = stack_1 ;
stack_1 = stack_0 ;
stack_0 = value ;
}

stk_adj_2(float value) // Delete top 2 floats, put value on top of stack, duplicate
// entry s to exit s
{
stack_0 = value ;
stack_1 = stack_2 ;
stack_2 = stack_3 ;
}

degrees() // Set trig functions to accept and report in degrees
{
trig_arg_mult = DEG_TO_RAD ;
trig_result_mult = RAD_TO_DEG ;
}

radians() // Set trig functions to accept and report in radions
{
trig_arg_mult = 1.0 ;
trig_result_mult = 1.0 ;
}

// OPERATORS - start

integer execute_basic_command(string command)
{
integer found = TRUE ;

command = llToLower(llGetSubString(command, 0, 2)) ; // Truncate strings to 3 chars
// max; set to lower case

if(command == "+")
{
stk_adj_2(stack_0 + stack_1) ;
}
else if(command == "-")
{
stk_adj_2(stack_1 - stack_0) ;
}
else if(command == "*")
{
stk_adj_2(stack_0 * stack_1) ;
}
else if(command == "/")
{
stk_adj_2(stack_1 / stack_0) ;
}
else if(command == "^")
{
stk_adj_2( llPow(stack_1, stack_0) ) ;
}
else if(command == "/%") // Integer results of y/, y mod x placed in x, y (resp)
{
integer temp0 = (integer)llFabs(stack_0) ;
integer temp1 = (integer)llFabs(stack_1) ;
stack_0 = temp1 / temp0 ;
stack_1 = temp1 % temp0 ;
}
else if(command == "d") // duplicate x; entry s is lost
{
push(stack_0) ;
}
else if(command == "r") // Rotate X stack; x->y, y->z, z->s, s->x
{
float temp = stack_0 ;

drop() ;
stack_3 = temp ;
}
else if(command == "s") // Swap x and y
{
float temp = stack_0 ;

stack_0 = stack_1 ;
stack_1 = temp ;
}
else
{
found = FALSE ;
}

return(found) ;
}

integer execute_misc_command(string command)
{
integer found = TRUE ;

command = llToLower(llGetSubString(command, 0, 2)) ;

if(command == "abs") // Absolute value
{
stack_0 = llFabs(stack_0) ;
}
if(command == "e")
{
push(E_constant ) ;
}
else if(command == "fra") // Fractional part of number
{
float temp = stack_0 ;
stack_0 = temp - (integer)temp ;
}
else if(command == "int") // Integer part of number
{
stack_0 = (integer)stack_0 ;
}
else if(command == "ln")
{
stack_0 = llLog(stack_0) ;
}
else if(command == "log")
{
stack_0 = llLog10(stack_0) ;
}
else if(command == "neg")
{
stack_0 = -stack_0 ;
}
else if(command == "nsa") // During Display(), DON'T say values x,y,z,s
// and DON'Treport free memory
{
Xflag = FALSE ;
}
else if(command == "rou") // Round off fraction
{
stack_0 = llRound(stack_0) ;
}
else if(command == "ran") // Random number between 0 and operand
{
stack_0 = llFrand(stack_0) ;
}
else if(command == "rc0") // Push contents of memory_0 onto the stack
{
push(memory_0) ;
}
else if(command == "rc1")
{
push(memory_1) ;
}
else if(command == "rc2")
{
push(memory_2) ;
}
else if(command == "rc3")
{
push(memory_3) ;
}
else if(command == "say") // During Display(), say valuesx,y,z,s (use in cut & paste)
// and report free memory
{
Xflag = TRUE ;
}
else if(command == "sqr") // Square root
{
stack_0 = llSqrt(stack_0) ;
}
else if(command == "st0") // Store x in memory_0
{
memory_0 = stack_0 ;
}
else if(command == "st1")
{
memory_1 = stack_0 ;
}
else if(command == "st2")
{
memory_2 = stack_0 ;
}
else if(command == "st3")
{
memory_3 = stack_0 ;
}
else
{
found = FALSE ;
}

return(found) ;
}

integer execute_trig_command(string command)
{
integer found = TRUE ;

command = llToLower(llGetSubString(command, 0, 2)) ;

if(command == "aco") // Arc-cosine
{
stack_0 = llAcos(stack_0) * trig_result_mult ;
}
else if(command == "asi")
{
stack_0 = llAsin(stack_0) * trig_result_mult ;
}
else if(command == "ata")
{
stack_0 = llAtan2(stack_0, 1.0) * trig_result_mult ;
}
else if(command == "cos")
{
stack_0 = llCos(stack_0 * trig_arg_mult) ;
}
else if(command == "deg") // Accept/report degress for trig functions
{
degrees() ;
}
else if(command == "pi")
{
push(PI) ;
}
else if(command == "rad") // Accept/report radians for trig functions
{
radians() ;
}
else if(command == "sin")
{
stack_0 = llSin(stack_0 * trig_arg_mult) ;
}
else if(command == "tan")
{
stack_0 = llTan(stack_0 * trig_arg_mult) ;
}
else
{
found = FALSE ;
}

return(found) ;
}


// OPERATORS - end


string pad(integer count, string padding) // Return a string consisting of count copies
// of padding
{
string result ;
integer i ;

if(count <= 0)
{
result = "" ;
}
else if(count == 1)
{
result = padding ;
}
else if(count == 2)
{
result = padding + padding ;
}
else if(count == 3)
{
result = padding + padding + padding ;
}
else
{
for(i=0, result="" ; i < count ; i++)
{
result += padding ;
}
}

return(result) ;
}

string make_exp_string(integer exp) // Produce display string of exponent
// [+|-] + {0} + <num>
{
string sign_string ;
if(exp >= 0)
{
sign_string = "+" ;
}
else
{
sign_string = "-" ;
}
exp = llAbs(exp) ;

string padding = "" ;
if(exp < 10)
{
padding = "0" ;
}

return("e" + sign_string + padding + (string)exp) ;
}

string display_float(float value) // Create a display string of floating point number
// (String should be 14-15 chars long, trail space)
// Manitissa is 7 decimal digits (about) of precision // Display as a decimal or scientific notation
{
integer exp ;
string sign_string ;
string num_string ;


if(llGetSubString((string)value, 0, 0) == "-") // Save sign as a string
{
sign_string = "-" ;
}
else
{
sign_string = " " ; // 2 spaces for plus
}
value = llFabs(value) ;

// (strings should be 12 characters in length
if(value == 0.0) // Handle 0.0 as a special case
{
num_string = "0.000000 " ;
}
else if(value >= 1e7) // Large number, scientific notation
{
exp = llFloor(llLog10(value)) ;
num_string = (string)(value * llPow(10, -exp)) + make_exp_string(exp) ;
}
else if(value >= 1.0) // 9,999,999 to 1.0 - regular decimal notation
{
num_string = llGetSubString((string)value, 0, 7) + " " ;
}
else // value < .1 and value != 0.0, scientific notation
{
exp = llFloor(llLog10(value)) ;
num_string = (string)(value * llPow(10, -exp)) + make_exp_string(exp) ;
}

num_string = sign_string + num_string + " " ;

return(num_string) ;
}

display_stack()
{
if(Xflag == TRUE) // say x, y, z, s to owner (see "say", in execute_misc_command())
{
llOwnerSay( display_float( stack_0) + " "
+ display_float( stack_1) + " "
+ display_float( stack_2) + " "
+ display_float( stack_3) ) ;

llOwnerSay((string)llGetFreeMemory() + " bytes free Memory") ;
}

string tstring = display_float( stack_3) + "\n"
+ display_float( stack_2) + "\n"
+ display_float( stack_1) + "\n"
+ display_float( stack_0) ;
llSetText(tstring, color_vector, color_alpha) ;
}

turn_display_off()
{
llSetText("", <0,0,0>, 0) ;
}

turn_on()
{
llListenRemove(handle) ;
llSetTimerEvent(TIME_SECONDS) ;
handle = llListen(0, "", llGetOwner(), "") ;
llOwnerSay("Calculator ON") ;
display_stack() ;
}

turn_off()
{
llListenRemove(handle) ;
llSetTimerEvent(0) ;
llOwnerSay("Calculator OFF") ;
turn_display_off() ;
}

initialize()
{
stack_3 = stack_2 = stack_1 = stack_0 = 0.0 ;
memory_3 = memory_2 = memory_1 = memory_0 = 0.0 ;
Xflag = TRUE ;
degrees() ;
llOwnerSay("Initializing") ;
turn_on() ;
}

default
{

on_rez(integer num_param)
{
llOwnerSay("rezzing") ;
}

state_entry()
{
initialize() ;
}

touch_start(integer total_number)
{
if(llGetOwner() == llDetectedKey(0)) // only owner can turn calculator ON
{
turn_on() ;
}
}

listen(integer channel, string name, key id, string message)
{
if(channel == 0 && id == llGetOwner()) // Only listen for owner on CH 0
{
// Parse input line, demlited by spaces and commas
list strings = llParseString2List( message, [ " ", "," ], [] ) ;
integer length = llGetListLength(strings) ; // how many strings
integer i ;
for(i=0 ; i < length ; i++) // Process each string
{
string next_string = llList2String(strings, i) ;
// Truncate string to lower case, 3 chars max
if(llToLower(llGetSubString(next_string, 0, 2)) == "off")
{
turn_off() ; // Turn calculator off
return ;
}
// See if string is a command
if( execute_basic_command(next_string) == FALSE )
if( execute_misc_command(next_string) == FALSE )
if( execute_trig_command(next_string) == FALSE )
{
push( (float)next_string ) ; // Else convert to float (0 on fail)
} // and push on stack
}
@Listen_1 ;
display_stack() ; // Now Display stack in floating text
llSetTimerEvent(TIME_SECONDS) ; // reset key timer
}
}

timer()
{
turn_off() ; // times up, no activity, turn off Calculator
}

}

Nada Epoch
The Librarian
Join date: 4 Nov 2002
Posts: 1,423
Discussion Thread
01-21-2007 16:51
/54/de/161927/1.html
_____________________
i've got nothing. ;)