Skip to content

Fix the resolution of names when variable and jump label names coincide #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
mewore opened this issue May 24, 2023 · 3 comments
Open

Comments

@mewore
Copy link
Contributor

mewore commented May 24, 2023

I never use jump and I never assign the same name to multiple things, so this is the most cornery of all corner cases.

What makes this even more undesirable to fix is that jumps are weird. This LSL script should explain how labels behave:

integer mew(integer mew) {
    integer mewtwo = 0;

    mew = 1; // This should be VALID code 
    
    jump mew;
    mewtwo = 3;
    mew = 100; // This should be VALID code 
    
    // Above this statement, the 'mew' variable should be resolved
    @mew; // Below this statement and in inner scopes, the 'mew' variable is unresolved - this is correct
    {
        integer mew = (mewtwo++);
        llOwnerSay("Mew = " + (string)mew);
        if (mew < 3) {
            jump mew; // This should be VALID code
        }
        return mew;
    }
}

...and not to mention labels with the same name being redeclared in inner scopes. ("If multiple jump sites are declared for the same target label within scope, then only the first (top to bottom, left to right) will function as expected, all others will silently fail." - https://wiki.secondlife.com/wiki/Jump). For the sake of simplicity, I'm not including this aspect of labels in this issue.

By the way, calling mew(0) prints:

[03:08] Object: Mew = 0
[03:08] Object: Mew = 1
[03:08] Object: Mew = 2
[03:08] Object: Mew = 3
@mewore
Copy link
Contributor Author

mewore commented May 24, 2023

I've been trying to wrap my mind around this whole thing. Maybe it's simpler to think of it - when resolving a symbol, how to look for its corresponding declaration.

LValue - needs to find variable/parameter

Start at the parent and keep going upwards, keeping track of the previous element (i.e., initially the LValue, and later - the last parent element we've come out of while traversing). If there's element with the required name:

  • If the element is a label declaration - return it ONLY if its index in the current parent child list is lower than the index of the previous element
  • If the element is a variable - well, actually, it turns out variables behave the same way - it only matters if its index is lower. I swear I had noticed some hoisting going on before, weird... Maybe I mixed my memories up with the jump statements.

Jump statement value - needs to find @label

Start at the parent and keep going upwards, keeping track of the previous element like last time. If there's element with the required name:

  • If the element is a label declaration - ALWAYS return it regardless of its position!
  • If the element is a variable - only return it if it's been declared before the jump statement and ONLY if no label declaration has been found.

What makes this a whole lot simpler is the fact that there can't be a variable and a label defined in the same scope.

I'm still tempted to look into the case of labels having the same name too, but instead, I accidentally found this one-liner that causes the whole script to not run at all despite compiling successfully:

default
{
    state_entry()
    {
        llOwnerSay("Running...");
        @label; if (FALSE) jump label; else { @label; }
        llOwnerSay("Done...");
    }
}

It must be SVC-6712:

If you attempt this, the script will silently fail to compile.

I had some other cases where it didn't silently fail despite having multiple labels with the same name (in a function, I think). I'm confused.

I think re-declarations of labels should just be forbidden altogether, or at least there should be a warning about it.

@riej
Copy link
Owner

riej commented Jun 3, 2023

I really wonder why LSL allows such code... And how it can work at allO.o Will try to figure out how to make this code be valid in the plugin too!

@riej
Copy link
Owner

riej commented Sep 29, 2023

I guess I fixed the first case. What about SVC-6712 - I have to write inspection for such cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants