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

Add "for each" loop and c-style for loop #76

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

Conversation

some100
Copy link

@some100 some100 commented Jan 30, 2025

The "for each" loop is a hidden block that basically acts as a repeat loop with a counter. It would set a variable to 1 and increment that variable each time the loop ran. This PR adds support for that kind of loop.
Additionally adds support for c-style for loop.

Syntax:
For Each

for x in n {
# code
}

C-style For

for x = 0; x > n; x++ {
#code
}

@aspizu
Copy link
Owner

aspizu commented Jan 30, 2025

Initially, my decision was to not add anything that generates hacked blocks, but it seems like the for block is popular demand due to its performance benefits. We will definitely use the in keyword in the implementation so need to think over the syntax. Come over to the discord to draft a RFC.

@aspizu
Copy link
Owner

aspizu commented Jan 30, 2025

I also have plans to add the C/JS/Java for(i = 0; i <10; i++) loop

@some100
Copy link
Author

some100 commented Jan 30, 2025

added "in" to for loop syntax. It might also be renamed "foreach" or "for each" to distinguish it from C-style loops should that be a future feature

@aspizu
Copy link
Owner

aspizu commented Jan 30, 2025

does this compile?

@some100
Copy link
Author

some100 commented Jan 30, 2025

yes (at least on my machine)

@FAReTek1
Copy link

FAReTek1 commented Jan 30, 2025

you can do this with a macro, although it isn't as efficient

# Loop through a list or string
# The warnings for the FOR macro probably apply here as well
%define FOREACH(var,lst,substack)                       \
    local _std_loops_foreach_macro_loop_i = 1;          \
    repeat length lst {                                 \
        var = lst[_std_loops_foreach_macro_loop_i];     \
        substack;                                       \
        _std_loops_foreach_macro_loop_i++;              \
    }

# Example usage:
# # list rand = python```
# import random
# for _ in range(10):
#     print(random.randint(1, 10))
# ```;
#
# FOREACH(local rnd, rand, 
#     add rnd to rand;
# )

you can also do c-style for loops

# For loop for goboscript.
# Has to be used inside a proc or func, as it uses a local variable.
%define FOR(substack_start,cond,substack_rep,substack_inr)  \
    substack_start;                                         \
    local _std_loops_for_macro_loop_cond = cond;            \ # These ridiculous names are to avoid name conflicts. (Macro local vars would be so nice. there are a lot of other things that would be nice. For now we have to make do. Goboscript is already really good)
    until not(_std_loops_for_macro_loop_cond) {             \
        substack_inr;                                       \ # Strange bug gets rid of seconds parameter in say block (not really sure how that happens) - but wrapping in a repeat seems to do the trick. That's your job though. Hopefully this gets fixed. Idk what causes it though...
        substack_rep;                                       \ # You should note that when using this :\\
        _std_loops_for_macro_loop_cond = cond;              \ # Goboscript doesn't handle until + functions returing properly (highly doubt this is intended)
    }

# Example usage:
# FOR(local i = 0, i <= 10, i++,
#     say i;
#     wait 0.4; # As said above, say for secs block doesn't work here unless it is in a repeat or something.
# )

@aspizu
Copy link
Owner

aspizu commented Feb 1, 2025

could you implement #77?

@some100
Copy link
Author

some100 commented Feb 3, 2025

Added c-style loops, however there are a few issues with it

  1. Statement 1 must be a variable assignment and it can't be a local or cloud. I couldn't find a good way to put in those two features.
  2. The output code ends up incrementing the variable before the loop runs rather than after the loop runs. So i=0 ends up becoming in effect i=1.
  3. Requires 3 semicolons, because the parser requires a semicolon in order to recognize something as a generic statement apparently

Syntax:

for x = 1; x > 10; x++; {
    #code
}

Output:

set x to 1
repeat until x > 10 {
    #code
    change x by 1
}

@aspizu
Copy link
Owner

aspizu commented Feb 3, 2025

  1. that's because the { of the for loop's body is ambiguous to the { of a struct literal.

@some100
Copy link
Author

some100 commented Feb 4, 2025

issue 2 fixed, now behavior of for loop should be more consistent with other programming languages by incrementing after the loop runs

@some100 some100 changed the title Add "for each" loop Add "for each" loop and c-style for loop Feb 4, 2025
@some100 some100 marked this pull request as draft February 4, 2025 16:08
@some100 some100 marked this pull request as ready for review February 4, 2025 16:26
@some100
Copy link
Author

some100 commented Feb 4, 2025

should be fully working as expected now

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.

None yet

3 participants