--- source: src/main.rs expression: compiled input_file: test-data/lua5.1-tests/nextvar.lua --- print('testing tables, next, and for'); local a = {} for i = 1, 100 { a[(i .. "+")] = true } for i = 1, 100 { a[(i .. "+")] = nil } for i = 1, 100 { a[(i)] = true assert(#a == i); } if T { local l2 = math.log(2) local fn log2(x) { return math.log(x) / l2 } local fn mp2(n) { local mp = 2 ^ math.ceil(log2(n)) assert(n == 0 || (mp / 2 < n && n <= mp)); return mp } local fn fb(n) { local r, nn = T.int2fb(n) assert(r < 256); return nn } local a = 1 local lim = 2 ^ 30 while a < lim { local n = fb(a) assert(a <= n && n <= a * 1.125); a = math.ceil(a * 1.3) } local fn check(t, na, nh) { local a, h = T.querytab(t) if a != na || h != nh { print(na, nh, a, h); assert(nil); } } local lim = 40 local s = 'return {' for i = 1, lim { s = s .. i .. ',' local s = s for k = 0, lim { local t = loadstring(s .. '}')() assert(#t == i); check(t, fb(i), mp2(k)); s = string.format('%sa%d=%d,', s, k, k) } } local a = {} for i = 1, lim { a[(i)] = i } for k = 0, lim { local a = { unpack(a, 1, k) } assert(#a == k); check(a, k, 0); a = { 1, 2, 3, unpack(a, 1, k) } check(a, k + 3, 0); assert(#a == k + 3); } print('+'); local lim = 130 local a = {} a[(2)] = 1 check(a, 0, 1); a = {} a[(0)] = 1 check(a, 0, 1); a[(2)] = 1 check(a, 0, 2); a = {} a[(0)] = 1 a[(1)] = 1 check(a, 1, 1); a = {} for i = 1, lim { a[(i)] = 1 assert(#a == i); check(a, mp2(i), 0); } a = {} for i = 1, lim { a[('a' .. i)] = 1 assert(#a == 0); check(a, 0, mp2(i)); } a = {} for i = 1, 16 { a[(i)] = i } check(a, 16, 0); for i = 1, 11 { a[(i)] = nil } for i = 30, 40 { a[(i)] = nil } check(a, 0, 8); a[(10)] = 1 for i = 30, 40 { a[(i)] = nil } check(a, 0, 8); for i = 1, 14 { a[(i)] = nil } for i = 30, 50 { a[(i)] = nil } check(a, 0, 4); for i = 1, lim { local a = {} for i = i, 1, -1 { a[(i)] = i } check(a, mp2(i), 0); } lim = 35 global fn foo(n, ...) { local arg = { ... } check(arg, n, 0); assert(select('#', ...) == n); arg[(n + 1)] = true check(arg, mp2(n + 1), 0); arg.x = true check(arg, mp2(n + 1), 1); } local a = {} for i = 1, lim { a[(i)] = true foo(i, unpack(a)); } } assert(#{} == 0); assert(#{ nil } == 0); assert(#{ nil, nil } == 0); assert(#{ nil, nil, nil } == 0); assert(#{ nil, nil, nil, nil } == 0); print('+'); local nofind = {} a, b, c = 1, 2, 3 a, b, c = nil local fn find(name) { local n, v while 1 { n, v = next(_G, n) if !n { return nofind } assert(v != nil); if n == name { return v } } } local fn find1(name) { for n, v with pairs(_G) { if n == name { return v } } return nil } { for i = 1, 10000 { _G[(i)] = i } } a = { x = 90, y = 8, z = 23 } assert(table.foreach(a, fn (i, v) { if i == 'x' { return v } }) == 90); assert(table.foreach(a, fn (i, v) { if i == 'a' { return v } }) == nil); table.foreach({}, error); table.foreachi({ x = 10, y = 20 }, error); local a = { n = 1 } table.foreachi({ n = 3 }, fn (i, v) { assert(a.n == i && !v); a.n = a.n + 1 }); a = { 10, 20, 30, nil, 50 } table.foreachi(a, fn (i, v) { assert(a[(i)] == v); }); assert(table.foreachi({ 'a', 'b', 'c' }, fn (i, v) { if i == 2 { return v } }) == 'b'); assert(print == find("print") && print == find1("print")); assert(_G[("print")] == find("print")); assert(assert == find1("assert")); assert(nofind == find("return")); assert(!find1("return")); _G[("ret" .. "urn")] = nil assert(nofind == find("return")); _G[("xxx")] = 1 assert(xxx == find("xxx")); print('+'); a = {} for i = 0, 10000 { if math.mod(i, 10) != 0 { a[('x' .. i)] = i } } n = { n = 0 } for i, v with pairs(a) { n.n = n.n + 1 assert(i && v && a[(i)] == v); } assert(n.n == 9000); a = nil for i = 1, 10000 { _G[(i)] = nil } { local a = {} local preserve = { io = 1, string = 1, debug = 1, os = 1, coroutine = 1, table = 1, math = 1 } for n, v with pairs(_G) { a[(n)] = v } for n, v with pairs(a) { if !preserve[(n)] && type(v) != "function" && !string.find(n, "^[%u_]") { _G[(n)] = nil } collectgarbage(); } } local fn foo() { local getfenv, setfenv, assert, next = getfenv, setfenv, assert, next local n = { gl1 = 3 } setfenv(foo, n); assert(getfenv(foo) == getfenv(1)); assert(getfenv(foo) == n); assert(print == nil && gl1 == 3); gl1 = nil gl = 1 assert(n.gl == 1 && next(n, 'gl') == nil); } foo(); print('+'); local fn checknext(a) { local b = {} table.foreach(a, fn (k, v) { b[(k)] = v }); for k, v with pairs(b) { assert(a[(k)] == v); } for k, v with pairs(a) { assert(b[(k)] == v); } b = {} { local k, v = next(a) while k { b[(k)] = v k, v = next(a, k) } } for k, v with pairs(b) { assert(a[(k)] == v); } for k, v with pairs(a) { assert(b[(k)] == v); } } checknext({ 1, x = 1, y = 2, z = 3 }); checknext({ 1, 2, x = 1, y = 2, z = 3 }); checknext({ 1, 2, 3, x = 1, y = 2, z = 3 }); checknext({ 1, 2, 3, 4, x = 1, y = 2, z = 3 }); checknext({ 1, 2, 3, 4, 5, x = 1, y = 2, z = 3 }); assert(table.getn({}) == 0); assert(table.getn({ -1 = 2 }) == 0); assert(table.getn({ 1, 2, 3, nil, nil }) == 3); for i = 0, 40 { local a = {} for j = 1, i { a[(j)] = j } assert(table.getn(a) == i); } assert(table.maxn({}) == 0); assert(table.maxn({ "1000" = true }) == 0); assert(table.maxn({ "1000" = true, 24.5 = 3 }) == 24.5); assert(table.maxn({ 1000 = true }) == 1000); assert(table.maxn({ 10 = true, 100 * math.pi = print }) == 100 * math.pi); a = {} for i = 0, 50 { a[(math.pow(2, i))] = true } assert(a[(table.getn(a))]); print("+"); local t = { { 1 } = 1, { 2 } = 2, string.rep("x ", 4) = 3, 100.3 = 4, 4 = 5 } local n = 0 for k, v with pairs(t) { n = n + 1 assert(t[(k)] == v); t[(k)] = nil collectgarbage(); assert(t[(k)] == nil); } assert(n == 5); local fn test(a) { table.insert(a, 10); table.insert(a, 2, 20); table.insert(a, 1, -1); table.insert(a, 40); table.insert(a, table.getn(a) + 1, 50); table.insert(a, 2, -2); assert(table.remove(a, 1) == -1); assert(table.remove(a, 1) == -2); assert(table.remove(a, 1) == 10); assert(table.remove(a, 1) == 20); assert(table.remove(a, 1) == 40); assert(table.remove(a, 1) == 50); assert(table.remove(a, 1) == nil); } a = { n = 0, -7 = "ban" } test(a); assert(a.n == 0 && a[(-7)] == "ban"); a = { -7 = "ban" } test(a); assert(a.n == nil && table.getn(a) == 0 && a[(-7)] == "ban"); table.insert(a, 1, 10); table.insert(a, 1, 20); table.insert(a, 1, -1); assert(table.remove(a) == 10); assert(table.remove(a) == 20); assert(table.remove(a) == -1); a = { 'c', 'd' } table.insert(a, 3, 'a'); table.insert(a, 'b'); assert(table.remove(a, 1) == 'c'); assert(table.remove(a, 1) == 'd'); assert(table.remove(a, 1) == 'a'); assert(table.remove(a, 1) == 'b'); assert(table.getn(a) == 0 && a.n == nil); print("+"); a = {} for i = 1, 1000 { a[(i)] = i a[(i - 1)] = nil } assert(next(a, nil) == 1000 && next(a, 1000) == nil); assert(next({}) == nil); assert(next({}, nil) == nil); for a, b with pairs({}) { error("not here"); } for i = 1, 0 { error('not here'); } for i = 0, 1, -1 { error('not here'); } a = nil for i = 1, 1 { assert(!a); a = 1 } assert(a); a = nil for i = 1, 1, -1 { assert(!a); a = 1 } assert(a); a = 0 for i = 0, 1, 0.1 { a = a + 1 } assert(a == 11); a = 0 for i = 0, 0.999999999, 0.1 { a = a + 1 } assert(a == 10); a = 0 for i = 1, 1, 1 { a = a + 1 } assert(a == 1); a = 0 for i = 1e10, 1e10, -1 { a = a + 1 } assert(a == 1); a = 0 for i = 1, 0.99999, 1 { a = a + 1 } assert(a == 0); a = 0 for i = 99999, 1e5, -1 { a = a + 1 } assert(a == 0); a = 0 for i = 1, 0.99999, -1 { a = a + 1 } assert(a == 1); a = 0 for i = "10", "1", "-2" { a = a + 1 } assert(a == 5); collectgarbage(); local fn f(n, p) { local t = {} for i = 1, p { t[(i)] = i * 10 } return fn (_, n) { if n > 0 { n = n - 1 return n, unpack(t) } }, nil, n } local x = 0 for n, a, b, c, d with f(5, 3) { x = x + 1 assert(a == 10 && b == 20 && c == 30 && d == nil); } assert(x == 5); print("OK");