Skip to content
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

scriptcomp: add initializers to for, while, switch statements #136

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

tinygiant98
Copy link
Contributor

@tinygiant98 tinygiant98 commented Oct 12, 2024

This change adds the ability to use initialization and arbitrary statements within for, while and switch statements. Any variables defined or initialized within a for, while or switch statement will be scoped within the associated compound statement and any child scopes.

All legacy constructs are supported. Initialization statements are optional in for, while or switch statements.

Testing

Simple initializer in for statement:

    for (int i = 0; i < 5; i++)
    {
        Debug(c("    > iteration " + _i(i), COLOR_GREEN_LIGHT));
    }

init

Initializer/declaration list and comma-separated increment statements in for statement:

    for (int x, y = 10, z = -1; y > z; y--, z++, x++)
    {
        Debug(c("    > iteration " + _i(x), COLOR_GREEN_LIGHT));
        Debug(c("      > x = " + _i(x) + ", y = " + _i(y) + ", z = " + _i(z), COLOR_RED_LIGHT));
    }

multiple_init

Function calls in initializer and increments statements in for statement:

    for (object o = GetFirstPC(); GetIsObjectValid(o); o = GetNextPC())
    {
        Debug(c("    > pc found -> " + GetName(o), COLOR_GREEN_LIGHT));
    }

function_calls

Function calls in nested for loops:

    for (object oArea = GetFirstArea(); GetIsObjectValid(oArea); oArea = GetNextArea())
    {
        Debug(c("    > area found -> " + GetName(oArea), COLOR_GREEN_LIGHT));
        for (object o = GetFirstObjectInArea(oArea); GetIsObjectValid(o); o = GetNextObjectInArea(oArea))
        {
            Debug(c("      > object found -> " + GetName(o) + " [" + GetTag(o) + "]", COLOR_ORANGE));
            if (GetObjectType(o) == OBJECT_TYPE_CREATURE)
            {
                for (effect e = GetFirstEffect(o); GetIsEffectValid(e); e = GetNextEffect(o))
                {
                    Debug(c("        > effect found -> " + _i(GetEffectType(e)), COLOR_RED_LIGHT));
                }
            }
        }
    }

nested_loops

Arbitrary statements in initializers and incrementers in for statement:

    int x, y;
    object o = GetFirstPC();
    for (SendMessageToPC(o, "    Loop Init"), y = 10; x < y; SendMessageToPC(o, "        Loop Iteration"), x++, y--)
    {
        SendMessageToPC(o, "      Loop Body");
        SendMessageToPC(o, "        x = " + _i(x) + ", y = " + _i(y));
    }

arbitrary_statements

Simple initializer in while statement:

    while (int x = 7; x > 0)
    {
        Debug(c("    > x = " + _i(x--), COLOR_GREEN_LIGHT));
    }

while_init

Function call in initializer for switch statement

    // SWITCH_INIT = 5
    switch (int x = GetLocalInt(GetFirstPC(), "SWITCH_INIT"); x)
    {
        case 0: Debug(c("    > 0")); break;
        case 1: Debug(c("    > 1")); break;
        case 2: Debug(c("    > 2")); break;
        case 3: Debug(c("    > 3")); break;
        case 4: Debug(c("    > 4")); break;
        case 5: Debug(c("    > 5")); break;
    }

switch_init

Changelog

Added

  • Added initializer statements to for, while and switch statements.
  • Added comma-separated increment statements to for statements.

Licence

  • I am licencing my change under the project's MIT licence, including all changes to GPL-3.0 licenced parts of the codebase.

@Daztek
Copy link
Contributor

Daztek commented Oct 12, 2024

How does it handle nested loops that use the same variable name? Are they scoped properly?

for (int x = 0; x < 100; x++)
{
    for (int x = 0; x < 10; x++)
    {
        
    }
}

Copy link
Collaborator

@mtijanic mtijanic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just leaving a few nits here while I actually make sense of the bigger change. This will take a while.

neverwinter/nwscript/native/scripterrors.h Outdated Show resolved Hide resolved
neverwinter/nwscript/native/scriptcompparsetree.cpp Outdated Show resolved Hide resolved
.gitignore Outdated Show resolved Hide resolved
@tinygiant98
Copy link
Contributor Author

tinygiant98 commented Oct 12, 2024

How does it handle nested loops that use the same variable name? Are they scoped properly?

for (int x = 0; x < 100; x++)
{
    for (int x = 0; x < 10; x++)
    {
        
    }
}

Ran a nested scope test. Results are on discord, but I'll put there here for record-keeping purposes.

Test code snippet:

for (int x = 0; x < 5; x++)
{
    Debug(c("  start outer loop -> x = " + _i(x), COLOR_ORANGE));
    for (int x = 3; x > 0; x--)
    {
        Debug(c("    inner loop -> x = " + _i(x), COLOR_RED_LIGHT));
    }
    Debug(c("  end outer loop -> x = " + _i(x), COLOR_GREEN_LIGHT));
}

image

I think it meets your intent, but if this test is too simple, let me know.

@tinygiant98 tinygiant98 reopened this Oct 12, 2024
@tinygiant98 tinygiant98 force-pushed the initializers-incrementers branch 2 times, most recently from 78f9f25 to a1f56c3 Compare October 12, 2024 23:26
…crementers to for statements

This change add the ability to use initialization and arbitrary
statements within for, while and switch statements.  Any variables
defined or initialized within a for, while or switch statement will be
scoped within the associated compound statement and any child scopes.

add

add comment back
@tinygiant98 tinygiant98 force-pushed the initializers-incrementers branch from a1f56c3 to 9e1cba8 Compare October 12, 2024 23:30
@tinygiant98
Copy link
Contributor Author

I've run all the tests I can think of here, but I also know how it's supposed to work, so I'm probably missing some ideas on how to break it. If you guys have any tests you'd like run against this PR, let me know and I'll run 'em.

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

Successfully merging this pull request may close these issues.

3 participants