lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

Le jeu. 15 nov. 2018 à 12:54, Philippe Verdy <> a écrit :
Writing  "for x = (a),(b) do (...) end" is only syntaxic sugar for: "do local x = (a); while x < (b) do (...); x = x + 1 end end"
More exactly it is the equivalent of:  "do local x, __end__ = (a), (b); while x <=   __end__   do (...); x = x + 1 end end"
because (b) is evaluated only once before the first checking of the condition and then entering the first loop (there was also a missing "=" in the condition)

A compiler may check the type of the value (a) assigned to the control variable (x), if it is known (constant), but then it must:
* coerce the value (b) assigned to "__end__" to the same datatype using ceiling (not floor);
* check that the coercion of (b) in "local x,__end__ = (a),coerce(b)" does not cause an overflow (if this occurs, the loop cannot be optimized using integers, it has to use a double floatting point for the control variable...);
* coerce the incrementation "x = x + 1", as "x =  successor(coerce(x))", if (a) was an integer type, so that the condition "x <= __end__" remains correct;
* check the possible integer overflow of this incrementation (if overflow occurs, this must break the loop immediately: an overflow can occur here only if "successor(__end__)" cannot be warrantied to be inside the valid range of the chosen datatype, or if the current value of "x" which was changed in the middle of the loop is outside the inclusive integer range from (a) to (b));
* compile the code inside the loop so that any reference to "x" will "uncoerce" its chosen integer type to the full range of "number" when needed (notably when using the value of "x" in function calls, but as well in simple expressions like "x*x"...)

A compiler may also want to unwind such loops if the code inside the loop is small, and if the difference between (a) and (b) is known (both (a) and (b) are constants) and small (generally not more than 4, but this may depend on the code size inside the loop; this is complex to do if that Lua code inside the loop contains other execution controls, requiring the generation of labels for generated jumps into the generated opcodes, or if the compiler makes special optimizations for exception handling, i.e. to optimize invokations in Lua code to "pcall(function,...)").