diff --git a/client/space_lua/context_errors.test.ts b/client/space_lua/context_errors.test.ts index 5c421fb9..e9343b0d 100644 --- a/client/space_lua/context_errors.test.ts +++ b/client/space_lua/context_errors.test.ts @@ -45,18 +45,6 @@ Deno.test("Context error: indexing nil value includes message and ref", async () assertCtxErrorContains(e, code, ref, "attempt to index a nil value"); }); -Deno.test("Context error: indexing with nil key includes message and ref", async () => { - const { e, code, ref } = await runAndCatch( - ` - local t = {} - local k = nil - local x = t[k] - `, - "nil_key.lua", - ); - assertCtxErrorContains(e, code, ref, "attempt to index with a nil key"); -}); - Deno.test("Context error: calling nil includes message and ref", async () => { const { e, code, ref } = await runAndCatch( ` diff --git a/client/space_lua/lua.test.ts b/client/space_lua/lua.test.ts index ef443744..56275712 100644 --- a/client/space_lua/lua.test.ts +++ b/client/space_lua/lua.test.ts @@ -33,6 +33,10 @@ Deno.test("[Lua] Load tests", async () => { await runLuaTest("./stdlib/load_test.lua"); }); +Deno.test("[Lua] Core language (truthiness)", async () => { + await runLuaTest("./stdlib/table_test.lua"); +}); + Deno.test("[Lua] Core language (length)", async () => { await runLuaTest("./len_test.lua"); }); diff --git a/client/space_lua/runtime.ts b/client/space_lua/runtime.ts index 55ac2f08..3410d446 100644 --- a/client/space_lua/runtime.ts +++ b/client/space_lua/runtime.ts @@ -1257,11 +1257,10 @@ export function luaGet( errSf, ); } + + // In Lua reading with a nil key returns nil silently if (key === null || key === undefined) { - throw new LuaRuntimeError( - `attempt to index with a nil key`, - errSf, - ); + return null; } if (obj instanceof LuaTable || obj instanceof LuaEnv) { diff --git a/client/space_lua/stdlib/table_test.lua b/client/space_lua/stdlib/table_test.lua index 8ef17920..aea581d4 100644 --- a/client/space_lua/stdlib/table_test.lua +++ b/client/space_lua/stdlib/table_test.lua @@ -63,7 +63,7 @@ do assertError(function() table.remove(t, #t + 2) end) end --- nil and NaN keys are forbidden +-- nil and NaN keys are forbidden on write do -- nil key at assignment assertError(function() @@ -88,11 +88,9 @@ do local _ = { [0/0] = "bar" } end) - -- reading with nil key is also an error - assertError(function() - local t = {} - return t[nil] - end) + -- reading with nil key returns nil silently + local t = {} + assertEqual(t[nil], nil) end -- Reference semantics / aliasing (tables are mutable references) @@ -218,7 +216,7 @@ do assertEqual(t, { 3, 2, 1 }) table.sort(t, function(a, b) return a < b end) - assertEqual(t, { 3, 2, 1 }) + assertEqual(t, { 1, 2, 3 }) local data = { { name = "John", age = 30 }, { name = "Jane", age = 25 } } table.sort(data, function(a, b) return a.age < b.age end)