• Subject: Re: A tricky way to determine Lua version (updated)
• From: Egor Skriptunoff <egor.skriptunoff@...>
• Date: Fri, 24 Jul 2020 18:34:39 +0300

On Wed, Jul 22, 2020 at 10:06 PM Andrew Gierth wrote:
the 1/0 parts rely on the implementation using IEEE floats, or at
least some float implementation that has both +/- infinity and +/- 0,
and that for integers in 5.3/5.4 there is no separate -0; if you build
Lua with only integer support, the code will not work.

Thanks for pointing it out.
Fixed:

local x, y = 2/1, 4; while x < y do x, y = x*x, y*y end
local f, t = function()return function()end end, {1, [1] = 4,
[false] = {3, 'Lua 5.1', 'Lua 5.4', 'LuaJIT'},
[true]  = {2, 'Lua 5.2', 'Lua 5.3', 4}}
local version = t[f()==f()][t[x*x==y][t[1]]]

Lua 5.1/5.2 has a single numeric subtype (either float or int),
Lua 5.3/5.4 has both float and int.
The code tries to find two different subtypes of numbers.
x*x~=y means both subtypes have been found.

This code relies on the following two facts:
1) floats: for any positive integer k the value 2^k will be positive
2) integers: for some positive integer k the value 2^k will be non-positive
So, the code will work also with non-IEEE-754 FP implementations lacking
infinity and negative zero.

You may ask why the _expression_ 2/1 is used instead of the constant 2.0
The FP constant may raise a syntax error on Lua 5.1/5.2 built with integers
because strtol() would probably be invoked there instead of strtod().
At least I have built Lua 5.2 with int64 numbers and used strtol() there.
Is it the correct way to build Lua 5.2 with integers?
Or Lua implementation must accept all sorts of numeric literals
listed at the end of section 3.1 in the manual?
https://www.lua.org/manual/5.2/manual.html#3.1