Assembly Programming Language
(http://www.gnu.org/copyleft/fdl.html) in the spirit of which this script is GPL'd. Copyright (C) 2008 Xaviar Czervik
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
This compiles an assembly-like programming language, and runs it. Unlike most assembly code, which is fast, this is very, very, slow. You can't do anything you couldn't do in a tenth the number of lines of LSL, so there are no advantages to using it (besides having fun).
Most of the things I did are really bizarre, and I did it for the sole reason of trying to do something amusing.
I'll try to explain quickly...
There are three registers, 0, 1, and 2. You can save values to 0 and 1. After functions are ran, they put the result into registry 2.
Below are a list of functions.
st0 - Stores the value to registry 0. st1 - Stores the value to registry 1. ty0 - Sets the type of registry 0, "str", "int" or "flo". ty1 - Sets the type of registry 1, "str", "int" or "flo". sv0 - Saves registry 0 to the memory address specified. sv1 - Saves registry 0 to the memory address specified. sv2 - Saves registry 0 to the memory address specified. ld0 - Load the data from the memory address into registry 0. ld1 - Load the data from the memory address into registry 1. jmp - Jump to a line number. jil - Jump to a line number if registry 0 is less than registry 1. jle - Jump to a line number if registry 0 is less than or equal to registry 1. jie - Jump to a line number if registry 0 is equal to registry 1. add - Adds registry 0 and 1, and stores the value into registry 2. sub - Subtracts registry 0 and 1, and stores the value into registry 2. say - Says registry 1 out loud. inp - Waits for user input (chat). rnd - Generates a random number between registry 0 and 1 (inclusive). rem - Comment.
<lsl>
list memory;
integer lastProgLine;
string reg0; string type0; string reg1; string type1; string reg2; string type2;
integer lstn;
integer i;
err(integer li, string s) {
llOwnerSay("Error on line " + (string)li + ": " + s); llResetScript();
}
save(string val, integer loc) {
integer add = lastProgLine + (integer)loc; if (add < llGetListLength(memory)) { memory = llListReplaceList(memory, [val], add, add); } else { integer i = 0; while (i < add-llGetListLength(memory)) { memory += ""; i++; } memory += val; }
}
default {
touch_start(integer a) { llGetNotecardLine("Prog", lastProgLine); } changed(integer a) { if (a & CHANGED_INVENTORY) { llResetScript(); } } dataserver(key qid, string data) { if (data == EOF) { state run; } memory += data; llGetNotecardLine("Prog", (lastProgLine += 1)); }
}
state run {
changed(integer a) { if (a & CHANGED_INVENTORY) { llResetScript(); } } state_entry() { i = 0; llSetTimerEvent(.001); } timer() { if (i >= lastProgLine) { llResetScript(); } string l = llList2String(memory, i); string command; string action; if (llSubStringIndex(l, " ") != -1) { list line = [llGetSubString(l, 0, llSubStringIndex(l, " ")-1), llGetSubString(l, llSubStringIndex(l, " ")+1, -1)]; command = llList2String(line, 0); action = llList2String(line, 1); } else { command = l; } if (command == "ty0") { if (!(action == "str" || action == "int" || action == "flo")) { err(i, "Invalid registry type."); } type0 = action; } else if (command == "ty1") { if (!(action == "str" || action == "int")) { err(i, "Invalid registry type."); } type1 = action; } else if (command == "ty2") { err(i, "Registry two can not be set."); } else if (command == "st0") { if (type0 == "") { err(i, "Registry type has not been defined."); } reg0 = action; } else if (command == "st1") { if (type1 == "") { err(i, "Registry type has not been defined."); } reg1 = action; } else if (command == "st2") { err(i, "Registry two can not be set."); } else if (command == "jmp") { i = (integer)action - 1; } else if (command == "jil") { if (type0 == "str" || type1 == "str") { err(i, "Registries may not be of type str to compare."); } if ((float)reg0 < (float)reg1) i = (integer)action - 1; } else if (command == "jle") { if (type0 == "str" || type1 == "str") { err(i, "Registries may not be of type str to compare."); } if ((float)reg0 <= (float)reg1) i = (integer)action - 1; } else if (command == "jie") { if (type0 == type1) { if (reg0 == reg1) i = (integer)action - 1; } } else if (command == "add") { if (type0 == "str" || type1 == "str") { type2 = "str"; reg2 = reg0 + reg1; } else if (type0 == "int" && type1 == "int") { type2 = "int"; reg2 = (string)((integer)reg0 + (integer)reg1); } else if (type0 == "flo" && type1 == "flo") { type2 = "int"; reg2 = (string)((float)reg0 + (float)reg1); } else if (type0 == "flo" && type1 == "int") { type2 = "int"; reg2 = (string)((float)reg0 + (integer)reg1); } else if (type0 == "int" && type1 == "flo") { type2 = "int"; reg2 = (string)((integer)reg0 + (float)reg1); } else { err(i, "Registry type mismatch or invalid."); } } else if (command == "sub") { if (type0 == "int" && type1 == "int") { type2 = "int"; reg2 = (string)((integer)reg0 - (integer)reg1); } else { err(i, "Registry type mismatch or invalid."); } } else if (command == "ld0") { if (type0 == "") { err(i, "Registry type has not been defined."); } reg0 = llList2String(memory, lastProgLine + (integer)action); } else if (command == "ld1") { if (type1 == "") { err(i, "Registry type has not been defined."); } reg1 = llList2String(memory, lastProgLine + (integer)action); } else if (command == "ld2") { err(i, "Cannot load data into registry two."); } else if (command == "sv0") { save(reg0, (integer)action); } else if (command == "sv1") { save(reg1, (integer)action); } else if (command == "sv2") { save(reg2, (integer)action); } else if (command == "say") { llSay(0, reg0); } else if (command == "inp") { llSetTimerEvent(0); lstn = llListen(0, "", "", ""); } else if (command == "rnd") { if (type0 == "float" || type1 == "float") { type2 = "flo"; reg2 = (string)(llFrand((float)reg1-(float)reg0)+(float)reg0); } else if (type1 == "int" && type0 == "int") { type2 = "int"; reg2 = (string)((integer)llFrand((float)reg1-(float)reg0+1)+(integer)reg0); } } else if (command == "rem") { } else { err(i, "Invalid command '" + command + "'."); } i++; } listen(integer i, string n, key id, string m) { llListenRemove(lstn); type2 = "str"; reg2 = m; llSetTimerEvent(.0001); }
} </lsl>