github.com/arnodel/golua@v0.0.0-20230215163904-e0b5347eaaa1/notes/numeric-for.md (about) 1 In Lua 5.4 the docs specify numeric for loops as working as follows 2 3 >The loop starts by evaluating once the three control expressions. Their values 4 >are called respectively the initial value, the limit, and the step. If the step 5 >is absent, it defaults to 1. 6 7 >If both the initial value and the step are integers, the loop is done with 8 >integers; note that the limit may not be an integer. Otherwise, the three 9 >values are converted to floats and the loop is done with floats. Beware of 10 >floating-point accuracy in this case. 11 12 >After that initialization, the loop body is repeated with the value of the 13 >control variable going through an arithmetic progression, starting at the 14 >initial value, with a common difference given by the step. A negative step 15 >makes a decreasing sequence; a step equal to zero raises an error. The loop 16 >continues while the value is less than or equal to the limit (greater than or 17 >equal to for a negative step). If the initial value is already greater than the 18 >limit (or less than, if the step is negative), the body is not executed. 19 20 >For integer loops, the control variable never wraps around; instead, the loop 21 >ends in case of an overflow. 22 23 This means that if a loop variable is an integer and this integer overflows / 24 underflows when it is incremented / decremented then the loops stops 25 immediately. E.g. the following loop will stop after one iteration instead of i 26 wrapping around and the loop carrying on forever. 27 28 ```lua 29 for i = math.maxinteger, 1e100 do end 30 ``` 31 32 It isn't practical to try to implement the semantics of the for loop as 33 described above in terms of existing opcodes. 34 35 Instead two new opcodes are introduced: 36 - `prepfor rStart, rStop, rStep`: makes sure `rStart`, `rStep`, `rStop` are all 37 numbers and converts `rStart` and `rStep` to the same numeric type. If the for 38 loop should already stop then `rStart` is set to nil. 39 - `advfor rStart, rStop, rStep`: increments `rStart` by `rStep`, making sure 40 that it doesn't wrap around if it is an integer. If it wraps around then the 41 loop should stop. If the loop should stop, `rStart` is set to nil. 42 43 With these two new opcodes it becomes easy to compile a numeric for loop. 44 Assuming `r1`, `r2`, `r3` contain the start, stop and step initial values: 45 46 ``` 47 prepfor r1, r2, r3 48 if not r1 jump END 49 LOOP: 50 r4 <- r1 51 [compiled body of loop where the loop variable is r4] 52 advfor r1, r2, r3 53 if r1 jump LOOP 54 END: 55 ```