--- source: src/main.rs expression: compiled input_file: test-data/lua5.1-tests/calls.lua --- print("testing functions and calls"); assert(type(1 < 2) == 'boolean'); assert(type(true) == 'boolean' && type(false) == 'boolean'); assert(type(nil) == 'nil' && type(-3) == 'number' && type('x') == 'string' && type({}) == 'table' && type(type) == 'function'); assert(type(assert) == type(print)); f = nil global fn f(x) { return a::x(x) } assert(type(f) == 'function'); fact = false { local res = 1 local fn fact(n) { if n == 0 { return res } else { return n * fact(n - 1) } } assert(fact(5) == 120); } assert(fact == false); a = { i = 10 } self = 20 method a::x(x) { return x + self.i } method a.y(x) { return x + self } assert(a::x(1) + 10 == a.y(1)); a.t = { i = -100 } a[("t")].x = fn (self, a, b) { return self.i + a + b } assert(a.t::x(2, 3) == -95); { local a = { x = 0 } method a::add(x) { self.x, a.y = self.x + x, 20 return self } assert(a::add(10)::add(20)::add(30).x == 60 && a.y == 20); } local a = { b = { c = {} } } method a.b.c.f1(x) { return x + 1 } method a.b.c::f2(x, y) { self[(x)] = y } assert(a.b.c.f1(4) == 5); a.b.c::f2('k', 12); assert(a.b.c.k == 12); print('+'); t = nil global fn f(a, b, c) { local d = 'a' t = { a, b, c, d } } f(1, 2); assert(t[(1)] == 1 && t[(2)] == 2 && t[(3)] == nil && t[(4)] == 'a'); f(1, 2, 3, 4); assert(t[(1)] == 1 && t[(2)] == 2 && t[(3)] == 3 && t[(4)] == 'a'); global fn fat(x) { if x <= 1 { return 1 } else { return x * loadstring("return fat(" .. x - 1 .. ")")() } } assert(loadstring("loadstring 'assert(fat(6)==720)' () "))(); a = loadstring('return fat(5), 3') a, b = a() assert(a == 120 && b == 3); print('+'); global fn err_on_n(n) { if n == 0 { error(); exit(1); } else { err_on_n(n - 1); exit(1); } } { global fn dummy(n) { if n > 0 { assert(!pcall(err_on_n, n)); dummy(n - 1); } } } dummy(10); global fn deep(n) { if n > 0 { deep(n - 1); } } deep(10); deep(200); global fn deep(n) { if n > 0 { return deep(n - 1) } else { return 101 } } assert(deep(30000) == 101); a = {} method a::deep(n) { if n > 0 { return self::deep(n - 1) } else { return 101 } } assert(a::deep(30000) == 101); print('+'); a = nil(fn (x) { a = x })(23) assert(a == 23 && (fn (x) { return x * 2 })(20) == 40); local x, y, z, a a = {} lim = 2000 for i = 1, lim { a[(i)] = i } assert(select(lim, unpack(a)) == lim && select('#', unpack(a)) == lim); x = unpack(a) assert(x == 1); x = { unpack(a) } assert(table.getn(x) == lim && x[(1)] == 1 && x[(lim)] == lim); x = { unpack(a, lim - 2) } assert(table.getn(x) == 3 && x[(1)] == lim - 2 && x[(3)] == lim); x = { unpack(a, 10, 6) } assert(next(x) == nil); x = { unpack(a, 11, 10) } assert(next(x) == nil); x, y = unpack(a, 10, 10) assert(x == 10 && y == nil); x, y, z = unpack(a, 10, 11) assert(x == 10 && y == 11 && z == nil); a, x = unpack({ 1 }) assert(a == 1 && x == nil); a, x = unpack({ 1, 2 }, 1, 1) assert(a == 1 && x == nil); Y = fn (le) { local fn a(f) { return le(fn (x) { return f(f)(x) }) } return a(a) } F = fn (f) { return fn (n) { if n == 0 { return 1 } else { return n * f(n - 1) } } } fat = Y(F) assert(fat(0) == 1 && fat(4) == 24 && Y(F)(5) == 5 * Y(F)(4)); local fn g(z) { local fn f(a, b, c, d) { return fn (x, y) { return a + b + c + d + a + x + y + z } } return f(z, z + 1, z + 2, z + 3) } f = g(10) assert(f(9, 16) == 10 + 11 + 12 + 13 + 10 + 9 + 16 + 10); Y, F, f = nil print('+'); global fn unlpack(t, i) { i = i || 1 if (i <= table.getn(t)) { return t[(i)], unlpack(t, i + 1) } } global fn equaltab(t1, t2) { assert(table.getn(t1) == table.getn(t2)); for i, v1 with ipairs(t1) { assert(v1 == t2[(i)]); } } local fn pack(...) { local x = { ... } x.n = select('#', ...) return x } global fn f() { return 1, 2, 30, 4 } global fn ret2(a, b) { return a, b } local a, b, c, d = unlpack({ 1, 2, 3 }) assert(a == 1 && b == 2 && c == 3 && d == nil); a = { 1, 2, 3, 4, false, 10, 'alo', false, assert } equaltab(pack(unlpack(a)), a); equaltab(pack(unlpack(a), -1), { 1, -1 }); a, b, c, d = ret2(f()), ret2(f()) assert(a == 1 && b == 1 && c == 2 && d == nil); a, b, c, d = unlpack(pack(ret2(f()), ret2(f()))) assert(a == 1 && b == 1 && c == 2 && d == nil); a, b, c, d = unlpack(pack(ret2(f()), (ret2(f())))) assert(a == 1 && b == 1 && c == nil && d == nil); a = ret2({ unlpack({ 1, 2, 3 }), unlpack({ 3, 2, 1 }), unlpack({ "a", "b" }) }) assert(a[(1)] == 1 && a[(2)] == 3 && a[(3)] == "a" && a[(4)] == "b"); rawget({}, "x", 1); rawset({}, "x", 1, 2); assert(math.sin(1, 2) == math.sin(1)); table.sort({ 10, 9, 8, 4, 19, 23, 0, 0 }, fn (a, b) { return a < b }, "extra arg"); x = "-- a comment\0\0\0\n x = 10 + \n23; \ local a = function () x = 'hi' end; \ return '\0'" local i = 0 global fn read1(x) { return fn () { collectgarbage(); i = i + 1 return string.sub(x, i, i) } } a = assert(load(read1(x), "modname")) assert(a() == "\0" && _G.x == 33); assert(debug.getinfo(a).source == "modname"); x = string.dump(loadstring("x = 1; return x")) i = 0 a = assert(load(read1(x))) assert(a() == 1 && _G.x == 1); i = 0 local a, b = load(read1("*a = 123")) assert(!a && type(b) == "string" && i == 2); a, b = load(fn () { error("hhi"); }) assert(!a && string.find(b, "hhi")); x = ` return function (x) return function (y) return function (z) return x+y+z end end end ` a = assert(load(read1(x))) assert(a()(2)(3)(10) == 15); local a, b = 20, 30 x = loadstring(string.dump(fn (x) { if x == "set" { a = 10 + b b = b + 1 } else { return a } })) assert(x() == nil); assert(debug.setupvalue(x, 1, "hi") == "a"); assert(x() == "hi"); assert(debug.setupvalue(x, 2, 13) == "b"); assert(!debug.setupvalue(x, 3, 10)); x("set"); assert(x() == 23); x("set"); assert(x() == 24); assert((fn () { return nil })(4) == nil); assert((fn () { local a return a })(4) == nil); assert((fn (a) { return a })() == nil); print('OK'); return deep