Difference between revisions of "User:Void Singer/Functions"

From Second Life Wiki
Jump to navigation Jump to search
m (clean up)
m (new function)
Line 2: Line 2:
{{void-box
{{void-box
|title=[[User:Void_Singer|Return to Void Singers user page]]
|title=[[User:Void_Singer|Return to Void Singers user page]]
}}
{{void-box
|title=uParseEquation
|content=
* Parses a string equation and returns a formatted result
* Supports the following operations and proper order of operations:
** Parenthesis("'''('''","''')'''")
** Negation ("'''-'''")
** Exponentiation ("'''^'''")
** Division and Multiplication ("'''/'''", "'''*'''")
** Subtraction & Addition ("'''-'''", "'''+'''")
* Supports (Case insensitive) constant replacement:
** "'''e'''" ([http://en.wikipedia.org/wiki/E_(mathematical_constant) Euler's Number]: '''2.7182817''')
** "'''pi'''" ([http://en.wikipedia.org/wiki/Pi Archimedes' Constant]: '''3.1415927''')
** "'''phi'''" ([http://en.wikipedia.org/wiki/Golden_ratio Golden Ratio]: '''1.6180340''')
* Supports implied multiplication of parenthesis and constants
** (2)3 == 2*3
** 2pi == 2*pi
* Supports Roots in the format of '''x^(1/y)''' (the "y" root of "x", where both are decimal numbers)
* Supports error detection:
** Unsuported characters
** Invalid/Missing Operators
** Divide by Zero
** Empty/Missing Parenthesis
** Ignores spaces
<lsl>string uParseEquation( string vStrTmp ){
    list    lst_OPS = ["+", "-", "*", "/", "^"];
    list    vLstEqn;
    list    vLstTmp;
    list    vLstSwp;
    integer vIdxFnd;
    integer vIdxBgn;
    integer vIdxEnd;
    integer vIntCnt;
    integer vIntErr;
   
    vStrTmp = llToLower( "(" + vStrTmp + ")" );
    vLstTmp = llParseString2List( vStrTmp, lst_OPS + ["pi", "phi"], [] );
    vLstTmp = llParseString2List( (string)vLstTmp, ["0", "1", "2", "3", "4", "5", "6", "7"], [] );
    vLstTmp = llParseString2List( (string)vLstTmp, ["8", "9", ".", "e", "(", ")", " ", "="], [] );
    if (vLstTmp != []){
        jump Err0;
    }
    vStrTmp = llDumpList2String( llParseStringKeepNulls( vStrTmp, ["e"], [] ), "(2.7182817)" );
    vStrTmp = llDumpList2String( llParseStringKeepNulls( vStrTmp, ["pi"], [] ), "(3.1415927)" );
    vStrTmp = llDumpList2String( llParseStringKeepNulls( vStrTmp, ["phi"], [] ), "(1.6180340)" );
    vLstEqn = llParseString2List( vStrTmp, [" ", "="], lst_OPS + ["(", ")"] );
    while (~(vIdxEnd = vIdxBgn = llListFindList( vLstEqn, (list)")" ))){
        while (llList2String( vLstEqn, vIdxBgn ) != "(" && ~(--vIdxBgn));
        if (~vIdxBgn){
            if (vIdxEnd - vIdxBgn > 1){
                if (~llListFindList( lst_OPS,
                                    (list)llList2String( vLstTmp = llList2List( vLstEqn, -~vIdxBgn, ~-vIdxEnd ),
                                    0xFFFFFFFF ) )){
                    jump Err1;
                }
                if (~(vIdxFnd = llListFindList( lst_OPS, (list)llList2String( vLstTmp, 0 ) ))){
                    if (1 == vIdxFnd  && !~llListFindList( lst_OPS, (list)llList2String( vLstTmp, 1 ) )){
                        vLstTmp = llListReplaceList( vLstTmp, (list)(-llList2Float( vLstTmp, 1 )), 0, 1 );
                    }else{
                        jump Err2;
                    }
                }
                vIntCnt = ([] != vLstTmp);
                while(++vIntCnt < 0){
                    if (~llListFindList( lst_OPS, (list)llList2String( vLstTmp, vIntCnt) )){
                        if (~(vIdxFnd = llListFindList( lst_OPS, (list)llList2String( vLstTmp, ++vIntCnt ) ))){
                            if (1 == vIdxFnd && !~llListFindList( lst_OPS, (list)llList2String( vLstTmp, -~vIntCnt) )){
                                vLstTmp = llListReplaceList( vLstTmp, (list)(-llList2Float( vLstTmp, vIntCnt )), vIntCnt, -~vIntCnt );
                                --vIntCnt;
                            }else{
                                jump Err3;
                            }
                        }
                    }else{
                        jump Err4;
                    }
                }
                vIntCnt = 4;
                do{
                    while (~(vIdxFnd = llListFindList( vLstTmp, (list)llList2String( lst_OPS, vIntCnt ) ))){
                        if (1 & vIntCnt){
                            if (2 & vIntCnt){
                                if (llList2String( vLstTmp, -~vIdxFnd )){
                                    vLstSwp = ["*", 1 / llList2Float( vLstTmp, -~vIdxFnd )];
                                }else{
                                    jump Err5;
                                }
                            }else{
                                vLstSwp = ["+", -llList2Float( vLstTmp, -~vIdxFnd )];
                            }
                        }else{
                            if (vIntCnt){
                                if (4 & vIntCnt){
                                    vLstSwp = (list)llPow( llList2Float( vLstTmp, ~-vIdxFnd ), llList2Float( vLstTmp, -~vIdxFnd ) );
                                }else{
                                    vLstSwp = (list)( llList2Float( vLstTmp, ~-vIdxFnd ) * llList2Float( vLstTmp, -~vIdxFnd ) );
                                }
                            }else{
                                vLstSwp = (list)( llList2Float( vLstTmp, ~-vIdxFnd ) + llList2Float( vLstTmp, -~vIdxFnd ) );
                            }
                        }
                        vLstTmp = llListReplaceList( vLstTmp, vLstSwp, vIdxFnd - !(1 & vIntCnt), -~vIdxFnd );
                    }
                }while (~(--vIntCnt));
                vLstEqn = llListReplaceList( vLstEqn, vLstTmp, vIdxBgn, vIdxEnd );
            }else{
                jump Err6;
            }
            if (!~llListFindList( lst_OPS + [")", ""], (list)llList2String( vLstEqn, -~vIdxBgn ) )){
                vLstEqn = llListInsertList( vLstEqn, (list)"*", -~vIdxBgn );
            }
            if (vIdxBgn){
                if (!~llListFindList( lst_OPS + (list)"(", (list)llList2String( vLstEqn, ~-vIdxBgn ) )){
                    vLstEqn = llListInsertList( vLstEqn, (list)"*", vIdxBgn );
                }
            }
        }else{
            jump Err7;
        }
    }
    if (~llListFindList( vLstEqn, (list)"(" )){
        jump Err8;
    }
    if (vLstEqn != ["="]){
        jump Err9;
    }
    if ((integer)vStrTmp == (float)(vStrTmp = llList2String( vLstEqn, 0 ))){
        vStrTmp = (string)((integer)vStrTmp);
    }else{
        vIntCnt = llStringLength( vStrTmp );
        while ("0" == llGetSubString( vStrTmp, --vIntCnt, vIntCnt  ));
        vStrTmp = llGetSubString( vStrTmp, 0, vIntCnt );
    }
    jump Errors;
    @Err9; ++vIntErr;
    @Err7; @Err8; ++vIntErr;
    @Err6; ++vIntErr;
    @Err5; ++vIntErr;
    @Err4; ++vIntErr;
    @Err3; ++vIntErr;
    @Err1; @Err2; ++vIntErr;
    @Err0;
    vStrTmp =
      "Error: " +
      llList2String( ["Unsupported Character(s)",
                      "Outside Operator(s)",
                      "Stacked Operator(s)",
                      "Missing Operator(s)",
                      "Divide By Zero",
                      "Empty Parenthesis",
                      "Missing Parenthesis",
                      "Catastrophic Failure"],
                    vIntErr ) +
      "\n" + llDumpList2String( vLstEqn, " " ) + "\n" + vStrTmp;
    @Errors;
    return vStrTmp;
}
/*//--                          License Text                          --//*/
/*//  Free to copy, use, modify, distribute, or sell, with attribution.  //*/
/*//    (C)2010 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ]    //*/
/*//  Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
/*//  All usages must contain a plain text copy of the previous 2 lines.  //*/
/*//--                                                                  --//*/</lsl>
:[[User:Void_Singer/Functions#Return_to_Void_Singers_user_page|Return to top]]
}}
}}



Revision as of 01:05, 20 October 2010

uParseEquation

  • Parses a string equation and returns a formatted result
  • Supports the following operations and proper order of operations:
    • Parenthesis("(",")")
    • Negation ("-")
    • Exponentiation ("^")
    • Division and Multiplication ("/", "*")
    • Subtraction & Addition ("-", "+")
  • Supports (Case insensitive) constant replacement:
  • Supports implied multiplication of parenthesis and constants
    • (2)3 == 2*3
    • 2pi == 2*pi
  • Supports Roots in the format of x^(1/y) (the "y" root of "x", where both are decimal numbers)
  • Supports error detection:
    • Unsuported characters
    • Invalid/Missing Operators
    • Divide by Zero
    • Empty/Missing Parenthesis
    • Ignores spaces

<lsl>string uParseEquation( string vStrTmp ){

   list    lst_OPS = ["+", "-", "*", "/", "^"];
   list    vLstEqn;
   list    vLstTmp;
   list    vLstSwp;
   integer vIdxFnd;
   integer vIdxBgn;
   integer vIdxEnd;
   integer vIntCnt;
   integer vIntErr;
   
   vStrTmp = llToLower( "(" + vStrTmp + ")" );
   vLstTmp = llParseString2List( vStrTmp, lst_OPS + ["pi", "phi"], [] );
   vLstTmp = llParseString2List( (string)vLstTmp, ["0", "1", "2", "3", "4", "5", "6", "7"], [] );
   vLstTmp = llParseString2List( (string)vLstTmp, ["8", "9", ".", "e", "(", ")", " ", "="], [] );
   if (vLstTmp != []){
       jump Err0;
   }
   vStrTmp = llDumpList2String( llParseStringKeepNulls( vStrTmp, ["e"], [] ), "(2.7182817)" );
   vStrTmp = llDumpList2String( llParseStringKeepNulls( vStrTmp, ["pi"], [] ), "(3.1415927)" );
   vStrTmp = llDumpList2String( llParseStringKeepNulls( vStrTmp, ["phi"], [] ), "(1.6180340)" );
   vLstEqn = llParseString2List( vStrTmp, [" ", "="], lst_OPS + ["(", ")"] );
   while (~(vIdxEnd = vIdxBgn = llListFindList( vLstEqn, (list)")" ))){
       while (llList2String( vLstEqn, vIdxBgn ) != "(" && ~(--vIdxBgn));
       if (~vIdxBgn){
            if (vIdxEnd - vIdxBgn > 1){
               if (~llListFindList( lst_OPS,
                                    (list)llList2String( vLstTmp = llList2List( vLstEqn, -~vIdxBgn, ~-vIdxEnd ),
                                    0xFFFFFFFF ) )){
                   jump Err1;
               }
               if (~(vIdxFnd = llListFindList( lst_OPS, (list)llList2String( vLstTmp, 0 ) ))){
                   if (1 == vIdxFnd  && !~llListFindList( lst_OPS, (list)llList2String( vLstTmp, 1 ) )){
                       vLstTmp = llListReplaceList( vLstTmp, (list)(-llList2Float( vLstTmp, 1 )), 0, 1 );
                   }else{
                       jump Err2;
                   }
               }
               vIntCnt = ([] != vLstTmp);
               while(++vIntCnt < 0){
                   if (~llListFindList( lst_OPS, (list)llList2String( vLstTmp, vIntCnt) )){
                       if (~(vIdxFnd = llListFindList( lst_OPS, (list)llList2String( vLstTmp, ++vIntCnt ) ))){
                           if (1 == vIdxFnd && !~llListFindList( lst_OPS, (list)llList2String( vLstTmp, -~vIntCnt) )){
                               vLstTmp = llListReplaceList( vLstTmp, (list)(-llList2Float( vLstTmp, vIntCnt )), vIntCnt, -~vIntCnt );
                               --vIntCnt;
                           }else{
                               jump Err3;
                           } 
                       }
                   }else{
                       jump Err4;
                   } 
               }
               vIntCnt = 4;
               do{
                   while (~(vIdxFnd = llListFindList( vLstTmp, (list)llList2String( lst_OPS, vIntCnt ) ))){
                       if (1 & vIntCnt){
                           if (2 & vIntCnt){
                               if (llList2String( vLstTmp, -~vIdxFnd )){
                                   vLstSwp = ["*", 1 / llList2Float( vLstTmp, -~vIdxFnd )];
                               }else{
                                   jump Err5;
                               } 
                           }else{
                               vLstSwp = ["+", -llList2Float( vLstTmp, -~vIdxFnd )];
                           }
                       }else{
                           if (vIntCnt){
                               if (4 & vIntCnt){
                                   vLstSwp = (list)llPow( llList2Float( vLstTmp, ~-vIdxFnd ), llList2Float( vLstTmp, -~vIdxFnd ) );
                               }else{
                                   vLstSwp = (list)( llList2Float( vLstTmp, ~-vIdxFnd ) * llList2Float( vLstTmp, -~vIdxFnd ) );
                               }
                           }else{
                               vLstSwp = (list)( llList2Float( vLstTmp, ~-vIdxFnd ) + llList2Float( vLstTmp, -~vIdxFnd ) );
                           }
                       }
                       vLstTmp = llListReplaceList( vLstTmp, vLstSwp, vIdxFnd - !(1 & vIntCnt), -~vIdxFnd );
                   }
               }while (~(--vIntCnt));
               vLstEqn = llListReplaceList( vLstEqn, vLstTmp, vIdxBgn, vIdxEnd );
           }else{
               jump Err6;
           }
           if (!~llListFindList( lst_OPS + [")", ""], (list)llList2String( vLstEqn, -~vIdxBgn ) )){
               vLstEqn = llListInsertList( vLstEqn, (list)"*", -~vIdxBgn );
           }
           if (vIdxBgn){
               if (!~llListFindList( lst_OPS + (list)"(", (list)llList2String( vLstEqn, ~-vIdxBgn ) )){
                   vLstEqn = llListInsertList( vLstEqn, (list)"*", vIdxBgn );
               }
           }
       }else{
           jump Err7;
       } 
   }
   if (~llListFindList( vLstEqn, (list)"(" )){
       jump Err8;
   }
   if (vLstEqn != ["="]){
       jump Err9;
   }
   if ((integer)vStrTmp == (float)(vStrTmp = llList2String( vLstEqn, 0 ))){
       vStrTmp = (string)((integer)vStrTmp);
   }else{
       vIntCnt = llStringLength( vStrTmp );
       while ("0" == llGetSubString( vStrTmp, --vIntCnt, vIntCnt  ));
       vStrTmp = llGetSubString( vStrTmp, 0, vIntCnt );
   }
   jump Errors;
   @Err9; ++vIntErr;
   @Err7; @Err8; ++vIntErr;
   @Err6; ++vIntErr;
   @Err5; ++vIntErr;
   @Err4; ++vIntErr;
   @Err3; ++vIntErr;
   @Err1; @Err2; ++vIntErr;
   @Err0;
   vStrTmp =
     "Error: " +
     llList2String( ["Unsupported Character(s)",
                     "Outside Operator(s)",
                     "Stacked Operator(s)",
                     "Missing Operator(s)",
                     "Divide By Zero",
                     "Empty Parenthesis",
                     "Missing Parenthesis",
                     "Catastrophic Failure"],
                    vIntErr ) +
     "\n" + llDumpList2String( vLstEqn, " " ) + "\n" + vStrTmp;
   @Errors;
   return vStrTmp;

} /*//-- License Text --//*/ /*// Free to copy, use, modify, distribute, or sell, with attribution. //*/ /*// (C)2010 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ] //*/ /*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/ /*// All usages must contain a plain text copy of the previous 2 lines. //*/ /*//-- --//*/</lsl>

Return to top

uListFindListLast

  • This function is a companion to llListFindList.
    • SPECIAL NOTE: this is only designed to work on string data that will NOT contain the "•" character(alt+7)... please use a different character to suit your needs.

Get Last Index of List Test in List Source <lsl>integer uListFindListLast( list vLstSrc, list vLstTst ){

   integer vIdxFnd =
     (vLstSrc != []) +
     ([] != vLstTst) +
     ([] != llParseString2List(
              llList2String(
                llParseStringKeepNulls(
                  llDumpList2String( vLstSrc, "•" ),
                  (list)llDumpList2String( vLstTst, "•" ),
                  [] ),
                -1 ),
              (list)"•",
              [] ));
return (vIdxFnd

uListFindAny*

  • These functions are companions to llListFindList.
    • SPECIAL NOTE: this is only designed to work on string data that will NOT contain the "•" character(alt+7)... please use a different character to suit your needs.

uListFindAnyFirst

Get the First index in List Source of Any element in List Test

<lsl>integer uListFindAnyFirst( list vLstSrc, list vLstTst ){

 return ((llParseString2List( 
            llList2String(
              llParseStringKeepNulls(
                llDumpList2String( vLstSrc, "•" ),
                vLstTst, [] ),
              0 ),
            (list)"•", [] ) != []) + 1) %
        ((vLstSrc != []) + 1) - 1;

} /*//-- Anti-License Text --//*/ /*// Contributed Freely to the Public Domain without limitation. //*/ /*// 2009 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ] //*/ /*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/ /*//-- --//*/</lsl>

uListFindAnyLast

Get the Last index in List Source of Any element in List Test

<lsl>integer uListFindAnyLast( list vLstSrc, list vLstTst ){

 return (vLstSrc != []) -
   (llParseString2List(
      llList2String(
        llParseString2List( 
          llDumpList2String( vLstSrc, "•" ),
          vLstTst, [] ),
        -1 ),
      (list)"•",
      [] ) != []) - 1;

} /*//-- Anti-License Text --//*/ /*// Contributed Freely to the Public Domain without limitation. //*/ /*// 2009 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ] //*/ /*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/ /*//-- --//*/</lsl>

Return to top

Questions or Comments?

Feel free to leave me a note on my User Talk page.