asar
asar copied to clipboard
easier way to repeat something N times and have access to a counter inside the loop
i often write some code like this:
!i = 0
while !i < N
; do some stuff here using !i (possibly multiline)
!i #= !i+1
endif
i think it'd be neat to have some shorter command for that which still exposes the loop counter. maybe something like
repeat !i from 0 to 15
; do the same stuff with !i
endrep
not a fan of that exact syntax though
brainstorming on discord got us to
for i from 0 to 15
; code using !i
endfor
which i'm personally pretty happy with
(upper and lower bounds can contain math, are evaluated only once, and i think should be both-ends-inclusive to best match with the syntax)
edit: okay right-exclusive is still superior (like ranges in any "real" programming language)
May I propose the following syntax:
for !i = 1 to 10 do
db !i
end
This syntax is inspired by Pascal. I kinda like having just our known assignment operator in the syntax, since that's a very common way to do for loops in programming languages. Although I can imagine that this might cause a few problems with the define processor, so an alternative would be
for i = 1 to 10 do
end
Or yet another alternative:
for i = 1, 10 do
end
This syntax is loosely inspired by Lua. In fact, Lua even allows specifying an increment for a loop, so we could do something like this:
for i = 10, 0, -2 do
db !i
end
This would write 10, 8, 6, 4, and 2 to the ROM (and also 0 if we used an inclusive end value, like Lua). I kinda like this idea.
i quite like the last 2 actually, though the do/end feels a bit out of place with existing if/while constructs. more consistent would be
for i = 1, 10
endfor
...or maybe we could drop the endif/endmacro/endwhatever silliness and rename all of those to just end (keeping aliases for backwards compat of course), it should be unambiguous anyways
also i already changed my mind about do, it looks pretty nice there
I'm in favor of going with just regular "end" everywhere. Really, the only reason I ever chose to use "endif" for while loops was because it allowed me to piggy-back their implementation off of existing if blocks, which made things a lot easier to process. Had that not been the case, I would have probably gone with a regular "end" right then. I prefer having a single consistent end keyword, as I think it simplifies a bunch of things. Just as an example, with mixed end keywords, the following could happen:
if !a == 0
for !i = 1, 10 do
endif
endfor
I'm not quite sure, but I think that code could even compile just fine, depending on the implementation of for loops. On the other hand, with just a single consistent end keyword (that is parsed for all types of blocks), that's no longer possible:
if !a == 0
for !i = 1, 10 do
end
end
So basically, my proposal is to keep "endif" as the end keyword for "everything", but to introduce "end" as an allias for it, so that we no longer have to use endif for constructs where it just doesn't make sense. Then, over time, we could move away from endif entirely and try to use end even for if blocks (though that last part is optional, it doesn't technically do any harm to keep using endif, aside from being inconsistent).
i still don't like using endif for anything that isn't an if, so i'd make end the only possible ending for for, and allow endif for if/while only for backwards compat.
Sounds fair for me. I still recommend processing them in a single common place, so that it will be easy to catch things like "trying to end a for block with an endif" or something like that.
implemented (on the asar_19 branch) in 1865cc7dc8e57691944c9cc29ec78b8dac019851. still need to port this to asar_2_beta aswell.
i apparently did port this to asar2 at some point, so done