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  ```