Makopo/lslint

Add Mono mode

Closed this issue · 8 comments

This script runs fine in Mono but works wrong in LSO due to a gotcha:

default
{
    state_entry()
    {
        jump X;
        llOwnerSay("Still here!");
        jump X;
        llOwnerSay("You can't see me");
        @X;
        llOwnerSay("OK");
    }
}

Under Mono it displays:

OK

Under LSO it displays:

Still here!
OK

lslint catches and reports it:

 WARN:: (  7,  9): Multiple jumps for label `X' - only the last will execute.
TOTAL:: Errors: 0  Warnings: 1

However, as demonstrated above, that warning only applies to LSO. I think that lslint needs a Mono mode in order to skip that warning, possibly more.

Thank you for reporting, @Sei-Lisa ! I confirmed the issue. Any solution will be appreciated.

Suggested patch:

diff --git a/lslmini.cc b/lslmini.cc
index 6f82499..61b24fa 100644
--- a/lslmini.cc
+++ b/lslmini.cc
@@ -64,6 +64,7 @@ const char *DEPRECATED_FUNCTIONS[][2] = {
 };
 
 int walklevel = 0;
+int mono_mode = 0;
 
 void print_walk( char *str ) {
    int i;
@@ -628,7 +629,7 @@ void LLScriptJumpStatement::determine_type() {
    LLScriptIdentifier *id = (LLScriptIdentifier *) get_child(0);
    id->resolve_symbol( SYM_LABEL );
    type = id->get_type();
-   if ( id->get_symbol() != NULL && id->get_symbol()->get_references() == 2 ) {
+   if ( !mono_mode && id->get_symbol() != NULL && id->get_symbol()->get_references() == 2 ) {
       ERROR( HERE, W_MULTIPLE_JUMPS_FOR_LABEL, id->get_symbol()->get_name() );
    }
 }
@@ -738,6 +739,8 @@ void LLASTNode::check_symbols() {
 void usage(char *name) {
    printf("Usage: %s [options] [input]\n", name);
    printf("Options: \n");
+   printf("\t-m\t\t\tUse Mono rules for the analysis.\n");
+   printf("\t-M\t\t\tUse LSO rules for the analysis (default).\n");
    printf("\t-b <file>\tLoad builtin functions from file.\n");
    printf("\t-t\t\tShow tree structure.\n");
    printf("\t-l\t\tShow line/column information as range\n");
@@ -812,6 +815,8 @@ int main(int argc, char **argv) {
       if ( argv[i][0] == '-' ) {
          for ( j = 1 ; argv[i][j]; ++j ) {
             switch( argv[i][j] ) {
+               case 'm': mono_mode = 1; break;
+               case 'M': mono_mode = 0; break;
                case 'b': builtins_file = argv[++i]; goto nextarg;
                case 't': show_tree = true; break;
                case 'l': logger->set_show_end(true);  break;
diff --git a/lslmini.hh b/lslmini.hh
index ca0c534..ea7a1c1 100644
--- a/lslmini.hh
+++ b/lslmini.hh
@@ -16,6 +16,7 @@ typedef float F32;
 
 extern class LLScriptScript *script;
 extern int walklevel;
+extern int mono_mode;
 void print_walk(char *str);
 void do_walk(class LLASTNode *node);
 

Patched my local binary. I am interested in adding an option for my linter plugin if this cannot be automatically detected (when I figure how to add options)

No, obviously it can't be automatic. The same script can be compiled in LSO and in Mono, and the compiler doesn't know which one just by looking at the script.

For an editor, maybe you can change the extension (.lslm or .lslo) to make it explicit which one to compile for. Or allow a comment like //$pragma mono at the beginning of the script to let the user indicate an intention to compile it for Mono. I don't like either, to be honest.

I'm greenlighting this one, works as intended.

I wonder if I'd change mono mode as default since current LSL defaults to it. Can you share your thoughts?

It may be a good idea. I have a hard time trying to imagine a scenario where that could break something.