From ef7b128793ff0c3bd64086728a302e82f3d8e538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Jan=20Fialka?= Date: Fri, 20 Feb 2026 15:25:24 +0100 Subject: [PATCH] [Space Lua] Fix: `math.tointeger` coerces strings like Lua; fix test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matouš Jan Fialka --- client/space_lua/stdlib/math.ts | 21 +++++++++++---------- client/space_lua/stdlib/math_test.lua | 9 +++++++-- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/client/space_lua/stdlib/math.ts b/client/space_lua/stdlib/math.ts index bffaf8e5..eb949a68 100644 --- a/client/space_lua/stdlib/math.ts +++ b/client/space_lua/stdlib/math.ts @@ -42,22 +42,23 @@ export const mathApi = new LuaTable({ }), /** - * If the value x is representable as a Lua integer, returns an - * integer with that value. Otherwise returns nil. + * If the value x is representable as a Lua integer, returns an integer + * with that value. Otherwise returns nil. + * Strings are NOT accepted — only Lua number values. */ tointeger: new LuaBuiltinFunction((_sf, x?: any) => { - if (x === undefined || x === null) return null; if (typeof x === "number") { - // plain integer - if (Number.isInteger(x)) return x; - return null; + return Number.isInteger(x) && isFinite(x) ? x : null; } if (isTaggedFloat(x)) { - // float with integer value e.g. 3.0 - if (Number.isInteger(x.value)) return x.value; - return null; + const n = x.value; + return Number.isInteger(n) && isFinite(n) ? n : null; + } + if (typeof x === "string") { + const n = untagNumber(x); // Number(x) coerces the string + if (isNaN(n) || !isFinite(n) || !Number.isInteger(n)) return null; + return n; } - if (typeof x === "bigint") return x; return null; }), diff --git a/client/space_lua/stdlib/math_test.lua b/client/space_lua/stdlib/math_test.lua index 37a877f9..b6911337 100644 --- a/client/space_lua/stdlib/math_test.lua +++ b/client/space_lua/stdlib/math_test.lua @@ -189,8 +189,13 @@ do assertEquals(math.tointeger(3.5), nil, "tointeger(3.5)") assertEquals(math.tointeger(-0.1), nil, "tointeger(-0.1)") - -- non-numbers yields nil (no error) - assertEquals(math.tointeger("3"), nil, "tointeger(string)") + -- string coercion: integer-valued string yields integer + assertEquals(math.tointeger("3"), 3, "tointeger(string int)") + assertEquals(math.tointeger("3.0"), 3, "tointeger(string float whole)") + assertEquals(math.tointeger("3.5"), nil, "tointeger(string float frac)") + assertEquals(math.tointeger("x"), nil, "tointeger(non-numeric string)") + + -- nil yields nil assertEquals(math.tointeger(nil), nil, "tointeger(nil)") -- inf and nan yields nil