Script preprocessing

As you may know if you’ve read my “About Blue” page, I love writing scripts to get objects to do things in-world.  It’s one of the reasons I joined SL, to discover what I could do with a new and interesting programming language.  So, you get the occasional technical article on the blog.  Feel free to skip this if you have no interesting in scripting 🙂

LSL is limited is a number of ways.  One of them that it lacks a preprocessor.  Preprocessors allow you to do things like:


#define CONSTANT value

and wherever the word CONSTANT appears in the script, the preprocessor will substitute value before it compiles the resulting code.  This is great for things like debugging scripts, and many other uses.

If you are using Firestorm however, you can switch on a preprocessor for LSL built into the viewer!

Other than doing substitutions such as the example above, there are a number of things you can use defined constants for, such as conditional compilation. Also, the preprocessor implements a number of other functions such as code inclusion.

The feature I want to talk about though is the switch statement.  LSL lacks this common feature of other C and Java-like languages.  So the Firestorm developers included a way to have the preprocessor do it.

In their basic form, switch statements look like:


switch (expression) {
    case value1: {
        do something;
    }
    case value2: {
        do something else;
    }
}

And here is the point.  We know that expression is something that can return an integer.  The first time I used a switch statement in LSL, I coded what any C or Java programmer would and said:


switch (llListFindList (list1, list2)) {

knowing that llListFindList () would return an integer result.  But on looking at the resultant code (you can see this in the preprocessor window in Firestorm after your code is preprocessed), I noted that the switch statement is translated into multiple if statements with jumps, but the preprocessor is not smart enough to evaluate the expression once and use the result!  So if you have 40 case statements, the resulting code will have 40 calls to llListFindList () !  This is terrible for performance!

If you are using switch statements in your LSL, please evaluate your expression before handing it to the preprocessor.  For example:


integer result = llListFindList (list1, list2);
switch (result) {

This will ensure expression is only evaluated once.

You can read more about the Firestorm preprocessor here.