User:Void Singer/Functions: Difference between revisions
Void Singer (talk | contribs) m clean up |
Void Singer (talk | contribs) 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:
- "e" (Euler's Number: 2.7182817)
- "pi" (Archimedes' Constant: 3.1415927)
- "phi" (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>
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 (vIdxFnduListFindAny*
- 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.
<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>
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>