Page 1 of 2 1 2 LastLast
Results 1 to 10 of 16

Thread: Java-style for loop

  1. #1
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    10,672

    Default Java-style for loop

    Revision 17460 says this:

    ---

    Add Java-style "for" loop:

    for (INIT [, INIT]* ; CONDITION ; ITERATE [, ITERATE]* ) BODY

    You can have 0 or more INIT statements, which can be of the form

    X = EXP (where X is declared already) or
    TYPE X = EXP (where X of type TYPE will be declared in the BODY scope).

    You can have 0 or more ITERATE statements, which can be of the form

    X++ or X--
    ++X or --X
    X OPER EXP (where OPER can be =, +=, -=, etc.

    BODY can be a single statement ending with a ; or a block enclosed in {}, with no ; at the end, just like any loop.

    break, continue, return, or exit are allowed within BODY, just like any loop.

    ---

    I just realized that I forgot to say that CONDITION is a boolean expression. I also realized that I probably did not allow you to omit it, which would default to "true". I'll fix that by and by.

    I did a fair amount of whackage elsewhere in the parser - mostly adding types to various collection objects - so it is possible I broke something. Let me know ASAP if you see any issues.

    And let me know if the new-style for loop works as you expect.
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

  2. #2
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    10,672

    Default

    OK. Revision 17461 lets you omit the CONDITION.

    Code:
    int i = 5;
    
    print( "test: ;;" );
    for( ;; ) {
        print( "i = " + i );
        if ( --i == 0 ) {
    	print( "time for a break!" );
    	break;
        }
    }
    
    print( "test: ;CONDITION;" );
    for ( ;i < 5; ) {
        print( "i = " + i++ );
    }
    
    print( "test: INIT;CONDITION;" );
    for ( i=1 ;i < 5; ) {
        print( "i = " + i++ );
    }
    
    print( "test: INIT;CONDITION;" );
    for (int j=6 ;j < 10; ) {
        print( "j = " + j++ );
    }
    
    print( "test: INIT;CONDITION;ITERATE" );
    for ( int j=12 ; j < 18 ; j++ ) {
        print( "j = " + j );
    }
    
    print( "test: INIT;CONDITION;ITERATE" );
    for ( int j=29 ; j > 25 ; --j ) {
        print( "j = " + j );
    }
    
    print( "nested for loops" );
    for ( int j = 1; j <= 5; j += 1 ) {
        for ( int k = 1; k <= 10; k += 2 ) {
    	print( j + " * " + k + " = " + ( j * k ) );
        }
    }
    
    print( "double iterators" );
    for ( int j = 1, int k = 10; j < k; ++j, --k ) {
        print( "j = " + j + " and k = " + k );
    }
    yields:

    Code:
    > test-java-for
    
    test: ;;
    i = 5
    i = 4
    i = 3
    i = 2
    i = 1
    time for a break!
    test: ;CONDITION;
    i = 0
    i = 1
    i = 2
    i = 3
    i = 4
    test: INIT;CONDITION;
    i = 1
    i = 2
    i = 3
    i = 4
    test: INIT;CONDITION;
    j = 6
    j = 7
    j = 8
    j = 9
    test: INIT;CONDITION;ITERATE
    j = 12
    j = 13
    j = 14
    j = 15
    j = 16
    j = 17
    test: INIT;CONDITION;ITERATE
    j = 29
    j = 28
    j = 27
    j = 26
    nested for loops
    1 * 1 = 1
    1 * 3 = 3
    1 * 5 = 5
    1 * 7 = 7
    1 * 9 = 9
    2 * 1 = 2
    2 * 3 = 6
    2 * 5 = 10
    2 * 7 = 14
    2 * 9 = 18
    3 * 1 = 3
    3 * 3 = 9
    3 * 5 = 15
    3 * 7 = 21
    3 * 9 = 27
    4 * 1 = 4
    4 * 3 = 12
    4 * 5 = 20
    4 * 7 = 28
    4 * 9 = 36
    5 * 1 = 5
    5 * 3 = 15
    5 * 5 = 25
    5 * 7 = 35
    5 * 9 = 45
    double iterators
    j = 1 and k = 10
    j = 2 and k = 9
    j = 3 and k = 8
    j = 4 and k = 7
    j = 5 and k = 6
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

  3. #3
    Minion Bale's Avatar
    Join Date
    Jun 2008
    Posts
    13,057

    Default

    Oh whoa. Seriously?! I can do that now?!!!!!

    Crimbo came 22 days early this year!

  4. #4
    Senior Member zarqon's Avatar
    Join Date
    Nov 2007
    Location
    Seoul, Korea
    Posts
    3,359

    Default

    Tres cool!

    for (int i=1; j < 12;) {
    print("Thank you!");
    }
    Sig by JakAtk
    My scripts: One-Click Wossname | Om******* (??) | Psychose-a-Matic | RandBot
    Combat suite: Best Between Battle | Me******** (?!) | SmartStasis | BatMan | BatMan RE
    For script authors: ASH Wiki | ZLib | BatBrain | CLI Links | CanAdv | Script Registry | Map Manager | About Bats
    If you appreciate my work, help me become BAT KING OF THE WORLD! Thanks to all donators!

  5. #5
    Minion Bale's Avatar
    Join Date
    Jun 2008
    Posts
    13,057

    Default

    I just discovered that this does not work:

    Code:
    ash for(int i = 1, string page; i < 590; i++, page = visit_url("inv_use.php?pwd&whichitem=9085&ajax=1")) {}
    To make it work I had to do this:

    Code:
    ash for(int i = 1, string page = ""; i < 590; i++, page = visit_url("inv_use.php?pwd&whichitem=9085&ajax=1")) {}

  6. #6
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    10,672

    Default

    It is true, I required an initializer. I'll look at it, by and by, to let you omit it to get the default.
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

  7. #7
    Developer
    Join Date
    Aug 2009
    Posts
    2,580

    Default

    Tres cool!

    for (int i=1; j < 12;) {
    print("Thank you!");
    }
    Originally Posted by zarqon View Post
    Unknown variable 'j' ()

  8. #8
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    10,672

    Default

    This:

    Code:
    print( "no assignment" );
    for ( int j, string str, int count = 5; count > 0; str += j++, --count ) {
        print( "count = " + count + " j = " + j + " str = \"" + str + "\"" );
    }
    yields:

    Code:
    no assignment
    count = 5 j = 0 str = ""
    count = 4 j = 1 str = "0"
    count = 3 j = 2 str = "01"
    count = 2 j = 3 str = "012"
    count = 1 j = 4 str = "0123"
    in revision 17496.

    Note that all variables mentioned in the initializer section get initialized, either to what you specify or to the default initial value for the data type. This includes already defined variables - which is an extension I coded for ASH's Java-style for loop:

    int a = 12; // new variable in the scope of the loop body, initialized to 12
    int a; // ditto, initialized to 0
    b = 12; // variable defined in the parent scope, initialized to 12
    b; // ditto, initialized to 0

    If you simply want to use a pre-defined variable and not initialize it, don't bother mentioning it in the initializer section of the for loop.
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

  9. #9
    Senior Member
    Join Date
    Apr 2009
    Posts
    1,642

    Default

    Unknown variable 'j' ()
    Originally Posted by heeheehee View Post
    Variable j is from elsewhere. It is an infiniloop.

    This includes already defined variables - which is an extension I coded for ASH's Java-style for loop:
    Originally Posted by Veracity View Post
    Do you mean that the already existing variables are reused but reinitialized, or that they get shadowed?

    Reused:
    Code:
    int a=-1;
    for (int a; a<0; a++) {} // no execution because 0 is not less than 0
    print(a); // zero, because the loop initialized it to default
    Shadowed:
    Code:
    int a=-1;
    for (int a; a<0; a++) {}
    print(a); // -1, because they are two different variables that just happen to share a name
    IIRC java resolves this ambiguity by making it a "duplicate variable" syntax error (but the variable is still only visible *inside* the loop).
    At a quick glance, C and C++, have it three ways, depending on standard, compiler, and compile-time options - either the initializer is effectively outside the loop (so it conflicts with preceding declarations of the same variable name, but the variable stays visible after the loop ends), or it's scoped entirely within the loop (shadowed), or it's like java (may not duplicate a previously declared variable, but goes out of scope at the end of the loop, and doesn't prevent a later-defined variable with the same name - obviously this one isn't possible in plain C)

  10. #10
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    10,672

    Default

    If you say "int a = 1" in the initializer section, "a" will shadow "a" from outside of the loop. It declares a new variable named "a" whose scope is the loop body. This is how ASH works in general:

    Code:
    int a = 2;
    if ( true )
    {
        int a = 1;
        print( "inner a = " + a );
    }
    print( "outer a = " + a );
    yields:

    Code:
    inner a = 1
    outer a = 2
    (As an aside, if I omit the "if (true)" - i.e., try to simply have a block - ASH says "Script parsing error (test-init.ash, line 2)". I don't like that. I'll look at it.)

    If you say "a = 2" - without the type - in the initializer section of the loop, "a" will look for an existing variable from the surrounding scope and will reuse it; it will initialize it as specified, and its value when the loop exits will be whatever it is after all the processing within the loop. If you omit that initializer, the loop can still use variables from outside the loop and manipulate them and change them that way. The only "extension" is allowing such variables to be put into the initializer section of the loop to be given an initial value, rather than requiring "a = 2;" to be placed in front of the loop.

    It would be simple to always require a type and not extend the syntax as described.

    In any case, "shadowing" variables without an error or warning is just how ASH works.
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •