///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3      //
//  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
//  rights of fair usage, the disclaimer and warranty conditions.        //
///////////////////////////////////////////////////////////////////////////
 
//////////////////////////////////////////////////////////
// The helper functions can be found at:
// http://grimore.org/fuss:lsl
//////////////////////////////////////////////////////////
 
//////////////////////////////////////////////////////////
// Returns a reversed list.
//////////////////////////////////////////////////////////
list wasListReverse(list lst) {
    if(llGetListLength(lst)<=1) return lst;
    return wasListReverse(llList2List(lst, 1, llGetListLength(lst))) + llList2List(lst,0,0);
}
 
//////////////////////////////////////////////////////////
// Deletes elements delete from list input.
//////////////////////////////////////////////////////////
list wasSubtractSubList(list input, list delete) {
    do {
        string tok = llList2String(delete, 0);
        list clean = input;
        do {
            if(llList2String(clean, 0) == tok) {
                integer idx = llListFindList(input, (list)tok);
                input = llDeleteSubList(input, idx, idx);
            }
        } while(clean = llDeleteSubList(clean, 0, 0));
    } while(delete = llDeleteSubList(delete, 0, 0));
    return input;
}
 
//////////////////////////////////////////////////////////
// Returns a list of operators and operands.
//////////////////////////////////////////////////////////
list wasInfixTokenize(string input) {
    list op = [ "+", "-", "(", ")", "%", "*", "/", "^", "sin", "asin", "cos", "acos", "tan", "sqrt", "ln" ];
    list result = llParseString2List(input, [], op);
    return wasSubtractSubList(result, [" "]);
}
 
//////////////////////////////////////////////////////////
// Transforms an infix expression to a postfix expression.
//////////////////////////////////////////////////////////
list wasInfixToPostfix(list infix) {
    list op = [  "+", "-", "%", "*", "/", "^", "sin", "asin", "cos", "acos", "tan", "sqrt", "ln" ];
    list opStack = [];
    list result = [];
    do {
        string t = llList2String(infix, 0);
        infix = llDeleteSubList(infix, 0, 0);
        if(t == "(") {
            opStack += "(";
            jump continue;
        }
        if(t == ")") {
            while(llGetListLength(opStack) != 0) {
                string topa = llList2String(opStack, llGetListLength(opStack)-1);
                opStack = llDeleteSubList(opStack, llGetListLength(opStack)-1, llGetListLength(opStack)-1);
                if(topa != "(" && topa != ")") result += topa;
            }
            opStack = llDeleteSubList(opStack, llGetListLength(opStack)-1, llGetListLength(opStack)-1);
            jump continue;
        }
        integer idx = llListFindList(op, (list)t);
        if(idx == -1) {
            result += t;
            jump continue;
        }
@repeat;
        string topb = llList2String(opStack, llGetListLength(opStack)-1);
        integer odx = llListFindList(op, (list)topb);
        if(odx >= idx) {
            opStack = llDeleteSubList(opStack, llGetListLength(opStack)-1, llGetListLength(opStack)-1);
            result += topb;
            if(llGetListLength(opStack) != 0) jump repeat;
        }
        opStack += t;
@continue;
    } while(llGetListLength(infix) != 0);
    result += wasListReverse(opStack);
    return result;   
}
 
//////////////////////////////////////////////////////////
// Evaluate a postfix expression.
//////////////////////////////////////////////////////////
float wasPostfixEval(list postfix) {
    list op = [ "+", "-", "%", "*", "/", "^", "sin", "asin", "cos", "acos", "tan", "sqrt", "ln" ];
    list orStack = [];
    do {
        string t = llList2String(postfix, 0);
        postfix = llDeleteSubList(postfix, 0, 0);
        integer idx = llListFindList(op, (list)t);
        if(idx == -1) {
            orStack += t;
            jump continue;
        }
        float a = llList2Float(orStack, llGetListLength(orStack)-1);
        orStack = llDeleteSubList(orStack, llGetListLength(orStack)-1, llGetListLength(orStack)-1);
        float b = llList2Float(orStack, llGetListLength(orStack)-1);
        float r = 0;
        if(t == "+") {
            orStack = llDeleteSubList(orStack, llGetListLength(orStack)-1, llGetListLength(orStack)-1);
            r = b + a;
            jump push;
        }
        if(t == "-") {
            orStack = llDeleteSubList(orStack, llGetListLength(orStack)-1, llGetListLength(orStack)-1);
            r = b - a;
            jump push;
        }
        if(t == "*") {
            orStack = llDeleteSubList(orStack, llGetListLength(orStack)-1, llGetListLength(orStack)-1);
            r = b * a;
            jump push;
        }
        if(t == "/") {
            orStack = llDeleteSubList(orStack, llGetListLength(orStack)-1, llGetListLength(orStack)-1);
            if(a == 0) {
                r = (float)"NaN";
                jump push;
            }
            r = b / a;
            jump push;
        }
        if(t == "^") {
            orStack = llDeleteSubList(orStack, llGetListLength(orStack)-1, llGetListLength(orStack)-1);
            r = llPow(b,a);
            jump push;
        }
        if(t == "%") {
            orStack = llDeleteSubList(orStack, llGetListLength(orStack)-1, llGetListLength(orStack)-1);
            r = (integer)b % (integer)a;
            jump push;
        }
        if(t == "sin") {
            r = llSin(a * DEG_TO_RAD);
            jump push;
        }
        if(t == "asin") {
            r = llAsin(a * DEG_TO_RAD);
            jump push;
        }
        if(t == "cos") {
            r = llCos(a * DEG_TO_RAD);
            jump push;
        }
        if(t == "acos") {
            r = llAcos(a * DEG_TO_RAD);
            jump push;
        }
        if(t == "tan") {
            r = llTan(a * DEG_TO_RAD);
            jump push;
        }
        if(t == "ln") {
            r = llLog(a);
            jump push;
        }
        if(t == "sqrt") {
            r = llSqrt(a);
        }
@push;
        orStack += r;
@continue;
    } while(llGetListLength(postfix) != 0);
    return llList2Float(orStack, 0);
}
 
list cmd = [];
 
default {
    link_message(integer sender_num, integer num, string str, key id) {
        cmd = llCSV2List(str);
        if(llList2String(cmd,1) != "calculate") return;
        llMessageLinked(LINK_THIS, 0, "glow:MAIN:HALT", NULL_KEY);
        state calculate;
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state calculate {
    state_entry() {
        llSay(0, "I evaluated that to: " + (string)wasPostfixEval(wasInfixToPostfix(wasInfixTokenize(llDumpList2String(llList2List(cmd, 2, -1),"")))));
        llMessageLinked(LINK_THIS, 0, "glow:MAIN:CONT", NULL_KEY);
        state default;
    }
    link_message(integer sender_num, integer num, string str, key id) {
        if(str != "glow:PLUG:HALT") return;
        state default;
    }
    on_rez(integer num) {
        llResetScript();
    }
}

secondlife/glow/plugin/calculator.txt ยท Last modified: 2022/11/24 07:45 by 127.0.0.1

Access website using Tor Access website using i2p Wizardry and Steamworks PGP Key


For the contact, copyright, license, warranty and privacy terms for the usage of this website please see the contact, license, privacy, copyright.