## 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-usevector  color_vector = <1.0, 1.0, 1.0> ;  // Color of floating textfloat   color_alpha  = 1.0 ;  // Opacity of floating textinteger 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    }            }`