Difference between revisions of "User:Void Singer/Functions"
Jump to navigation
Jump to search
Get the First index in List Source of Any element in List Test
Get the Last index in List Source of Any element in List Test
How to incorporate into llDialog calls:
How to detect and handle responses:
Void Singer (talk | contribs) m (+uDlgBtnPagList) |
m (<lsl> tag to <source>) |
||
Line 28: | Line 28: | ||
** Empty/Missing Parenthesis | ** Empty/Missing Parenthesis | ||
** Ignores spaces | ** Ignores spaces | ||
< | <source lang="lsl2">string uParseEquation( string vStrTmp ){ | ||
list lst_OPS = ["+", "-", "*", "/", "^"]; | list lst_OPS = ["+", "-", "*", "/", "^"]; | ||
list vLstEqn; | list vLstEqn; | ||
Line 166: | Line 166: | ||
/*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/ | /*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/ | ||
/*// All usages must contain a plain text copy of the previous 2 lines. //*/ | /*// All usages must contain a plain text copy of the previous 2 lines. //*/ | ||
/*//-- --//*/</ | /*//-- --//*/</source> | ||
:[[User:Void_Singer/Functions#Return_to_Void_Singers_user_page|Return to top]] | :[[User:Void_Singer/Functions#Return_to_Void_Singers_user_page|Return to top]] | ||
}} | }} | ||
Line 179: | Line 179: | ||
** '''SPECIAL NOTE''': data should NOT contain the "•" character(alt+7)... please use a different character if this one is expected. | ** '''SPECIAL NOTE''': data should NOT contain the "•" character(alt+7)... please use a different character if this one is expected. | ||
'''Get Last Index of List Test in List Source''' | '''Get Last Index of List Test in List Source''' | ||
< | <source lang="lsl2">integer uListFindListLast( list vLstSrc, list vLstTst ){ | ||
integer vIdxFnd = | integer vIdxFnd = | ||
(vLstSrc != | (vLstSrc != | ||
Line 198: | Line 198: | ||
/*// 2012 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ] //*/ | /*// 2012 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ] //*/ | ||
/*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/ | /*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/ | ||
/*//-- --//*/</ | /*//-- --//*/</source> | ||
:[[User:Void_Singer/Functions#Return_to_Void_Singers_user_page|Return to top]] | :[[User:Void_Singer/Functions#Return_to_Void_Singers_user_page|Return to top]] | ||
}} | }} | ||
Line 211: | Line 211: | ||
<br/><div style="display:none"><h3>uListFindAnyFirst</h3></div>'''Get the First index in List Source of Any element in List Test''' | <br/><div style="display:none"><h3>uListFindAnyFirst</h3></div>'''Get the First index in List Source of Any element in List Test''' | ||
< | <source lang="lsl2">integer uListFindAnyFirst( list vLstSrc, list vLstTst ){ | ||
return ~(~( | return ~(~( | ||
llParseString2List( | llParseString2List( | ||
Line 226: | Line 226: | ||
/*// 2012 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ] //*/ | /*// 2012 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ] //*/ | ||
/*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/ | /*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/ | ||
/*//-- --//*/</ | /*//-- --//*/</source> | ||
<div style="display:none"><h3>uListFindAnyLast</h3></div>'''Get the Last index in List Source of Any element in List Test''' | <div style="display:none"><h3>uListFindAnyLast</h3></div>'''Get the Last index in List Source of Any element in List Test''' | ||
< | <source lang="lsl2">integer uListFindAnyLast( list vLstSrc, list vLstTst ){ | ||
return ~( | return ~( | ||
llParseString2List( | llParseString2List( | ||
Line 244: | Line 244: | ||
/*// 2012 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ] //*/ | /*// 2012 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ] //*/ | ||
/*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/ | /*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/ | ||
/*//-- --//*/</ | /*//-- --//*/</source> | ||
:[[User:Void_Singer/Functions#Return_to_Void_Singers_user_page|Return to top]] | :[[User:Void_Singer/Functions#Return_to_Void_Singers_user_page|Return to top]] | ||
}} | }} | ||
Line 260: | Line 260: | ||
** this function does NOT check that button text is valid (0 < button_text_length < 25), that's your job | ** this function does NOT check that button text is valid (0 < button_text_length < 25), that's your job | ||
* Individual button texts ''cannot''' start with a non-breaking space (alt+255). | * Individual button texts ''cannot''' start with a non-breaking space (alt+255). | ||
< | <source lang="lsl2">list uDlgBtnPagLst( integer vIdxPag ){ | ||
list vLstRtn; | list vLstRtn; | ||
if ((gLstMnu != []) > 12){ //-- we have more than one possible page | if ((gLstMnu != []) > 12){ //-- we have more than one possible page | ||
Line 280: | Line 280: | ||
/*// 2012 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ] //*/ | /*// 2012 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ] //*/ | ||
/*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/ | /*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/ | ||
/*//-- --//*/</ | /*//-- --//*/</source> | ||
<div style="display:none"><h3>Example Usage</h3></div>'''How to incorporate into [[llDialog]] calls:''' | <div style="display:none"><h3>Example Usage</h3></div>'''How to incorporate into [[llDialog]] calls:''' | ||
< | <source lang="lsl2">llDialog( Target_avatar_key, text_for_dialog_header, uDlgBtnLst( 0 ), chat_channel_to_use );</source> | ||
<div style="display:none"><h3>Response Detection</h3></div>'''How to detect and handle responses:''' | <div style="display:none"><h3>Response Detection</h3></div>'''How to detect and handle responses:''' | ||
< | <source lang="lsl2"> listen( integer vIntChn, string vStrNom, key vKeySpk, string vStrMsg ){ | ||
if (!llSubStringIndex( vStrMsg, " " )){ //-- detects (hidden) leading non-breaking space of page change buttons | if (!llSubStringIndex( vStrMsg, " " )){ //-- detects (hidden) leading non-breaking space of page change buttons | ||
llDialog( vKeySpk, | llDialog( vKeySpk, | ||
Line 296: | Line 296: | ||
//-- use (llListFindList( gLstMnu, (list)vStrMsg ) / 10) for remenu command if present | //-- use (llListFindList( gLstMnu, (list)vStrMsg ) / 10) for remenu command if present | ||
} | } | ||
}</ | }</source> | ||
:[[User:Void_Singer/Functions#Return_to_Void_Singers_user_page|Return to top]] | :[[User:Void_Singer/Functions#Return_to_Void_Singers_user_page|Return to top]] | ||
}} | }} |
Revision as of 22:33, 24 January 2015
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
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. //*/
/*//-- --//*/
uListFindListLast
- This function is a companion to llListFindList.
- designed for string data only.
- Can not handle empty string elements
- Returns 0 if list test is empty, but list source is not; just like llListFindList
- SPECIAL NOTE: data should NOT contain the "•" character(alt+7)... please use a different character if this one is expected.
Get Last Index of List Test in List Source
integer uListFindListLast( list vLstSrc, list vLstTst ){
integer vIdxFnd =
(vLstSrc !=
(vLstTst +
llParseString2List(
llList2String(
llParseStringKeepNulls(
llDumpList2String( vLstSrc, "•" ),
(list)llDumpList2String( vLstTst, "•" ),
[] ),
0xFFFFFFFF ),
["•"],
[] )));
return (vIdxFnd | (vIdxFnd >> 31));
}
/*//-- Anti-License Text --//*/
/*// Contributed Freely to the Public Domain without limitation. //*/
/*// 2012 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ] //*/
/*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/
/*//-- --//*/
uListFindAny*
- These functions are companions to llListFindList.
- designed for string data only.
- Can not handle empty string elements
- SPECIAL NOTE: data should NOT contain the "•" character(alt+7)... please use a different character if this one is expected.
Get the First index in List Source of Any element in List Test
integer uListFindAnyFirst( list vLstSrc, list vLstTst ){
return ~(~(
llParseString2List(
llList2String(
llParseStringKeepNulls(
llDumpList2String( vLstSrc, "•" ),
vLstTst, [] ),
0 ),
["•"], [] ) != []) %
~(vLstSrc != []));
}
/*//-- Anti-License Text --//*/
/*// Contributed Freely to the Public Domain without limitation. //*/
/*// 2012 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ] //*/
/*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/
/*//-- --//*/
integer uListFindAnyLast( list vLstSrc, list vLstTst ){
return ~(
llParseString2List(
llList2String(
llParseStringKeepNulls(
llDumpList2String( vLstSrc, "•" ),
vLstTst, [] ),
0xFFFFFFFF ),
["•"], [] )
!= vLstSrc);
}
/*//-- Anti-License Text --//*/
/*// Contributed Freely to the Public Domain without limitation. //*/
/*// 2012 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ] //*/
/*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/
/*//-- --//*/
uDlgBtnPagList
- Effectively allows more than 12 button on a dialog by breaking them up into pages and adding page change buttons as needed
- Corrects the button order to [left to right, top to bottom] (AKA English Order]
- Automatically wraps around from the last and first pages
- Supports up to 22 pages safely (220 items in the list)
- Supports multiple simultaneous users
- Support Re-menuing
- Requires the button text(s) to be in a global list named gLstMnu (which you can fill however you like)
- this function does NOT check that button text is valid (0 < button_text_length < 25), that's your job
- Individual button texts cannot' start with a non-breaking space (alt+255).
list uDlgBtnPagLst( integer vIdxPag ){
list vLstRtn;
if ((gLstMnu != []) > 12){ //-- we have more than one possible page
integer vIntTtl = -~((~([] != gLstMnu)) / 10); //-- Total possible pages
integer vIdxBgn = (vIdxPag = (vIntTtl + vIdxPag) % vIntTtl) * 10; //-- first menu index
string vStrPag = llGetSubString( " ", 21 - vIdxPag, 21 ); //-- encode page number as spaces
//-- get ten (or less for the last page) entries from the list and insert back/fwd buttons
vLstRtn = llListInsertList( llList2List( gLstMnu, vIdxBgn, vIdxBgn + 9 ), (list)(" «" + vStrPag), 0xFFFFFFFF ) +
(list)(" »" + vStrPag);
}else{ //-- we only have 1 page
vLstRtn = gLstMnu; //-- just use the list as is
}
return //-- fix the order for [L2R,T2B] and send it out
llList2List( vLstRtn, -3, -1 ) + llList2List( vLstRtn, -6, -4 ) +
llList2List( vLstRtn, -9, -7 ) + llList2List( vLstRtn, -12, -10 );
}
/*//-- Anti-License Text --//*/
/*// Contributed Freely to the Public Domain without limitation. //*/
/*// 2012 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ] //*/
/*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/
/*//-- --//*/
llDialog( Target_avatar_key, text_for_dialog_header, uDlgBtnLst( 0 ), chat_channel_to_use );
listen( integer vIntChn, string vStrNom, key vKeySpk, string vStrMsg ){
if (!llSubStringIndex( vStrMsg, " " )){ //-- detects (hidden) leading non-breaking space of page change buttons
llDialog( vKeySpk,
"your dialog text goes here",
uDlgBtnLst( llStringLength( vStrMsg ) + llSubStringIndex( vStrMsg, "»" ) - 2 ),
vIntChn );
}else{
//-- button was not a page button, your code goes here,
//-- use (llListFindList( gLstMnu, (list)vStrMsg ) / 10) for remenu command if present
}
}
Questions or Comments?
Feel free to leave me a note on my User Talk page.