cluna 1.1.0

Tool to convert Lua code into Clue code Made by MarkosTh09
Documentation
---
source: src/main.rs
expression: compiled
input_file: test-data/lua5.1-tests/gc.lua
---
print('testing garbage collection');
collectgarbage();
_G[("while")] = 234
limit = 5000
contCreate = 0
print('tables');
while contCreate <= limit {
    local a = {}
    a = nil
    contCreate = contCreate + 1
}
a = "a"
contCreate = 0
print('strings');
while contCreate <= limit {
    a = contCreate .. "b"
    a = string.gsub(a, '(%d%d*)', string.upper)
    a = "a"
    contCreate = contCreate + 1
}
contCreate = 0
a = {}
print('functions');
method a::test() {
    while contCreate <= limit {
        loadstring(string.format("function temp(a) return 'a%d' end", contCreate))();
        assert(temp() == string.format('a%d', contCreate));
        contCreate = contCreate + 1
    }
}
a::test();
{
    local f = fn () {
        
    }
}
print("functions with errors");
prog = `
do
  a = 10;
  function foo(x,y)
    a = sin(a+0.456-0.23e-12);
    return function (z) return sin(%x+z) end
  end
  local x = function (w) a=a+w; end
end
`
{
    local step = 1
    if rawget(_G, "_soft") {
        step = 13
    }
    for i = 1, string.len(prog), step {
        for j = i, string.len(prog), step {
            pcall(loadstring(string.sub(prog, i, j)));
        }
    }
}
print('long strings');
x = "01234567890123456789012345678901234567890123456789012345678901234567890123456789"
assert(string.len(x) == 80);
s = ''
n = 0
k = 300
while n < k {
    s = s .. x
    n = n + 1
    j = tostring(n)
}
assert(string.len(s) == k * 80);
s = string.sub(s, 1, 20000)
s, i = string.gsub(s, '(%d%d%d%d)', math.sin)
assert(i == 20000 / 4);
s = nil
x = nil
assert(_G[("while")] == 234);
local bytes = gcinfo()
while 1 {
    local nbytes = gcinfo()
    if nbytes < bytes {
        break
    }
    bytes = nbytes
    a = {}
}
local fn dosteps(siz) {
    collectgarbage();
    collectgarbage("stop");
    local a = {}
    for i = 1, 100 {
        a[(i)] = {
            {}
        }
        local b = {}
    }
    local x = gcinfo()
    local i = 0
    loop  {
        i = i + 1
    } until collectgarbage("step", siz)
    assert(gcinfo() < x);
    return i
}
assert(dosteps(0) > 10);
assert(dosteps(6) < dosteps(2));
assert(dosteps(10000) == 1);
assert(collectgarbage("step", 1000000) == true);
assert(collectgarbage("step", 1000000));
{
    local x = gcinfo()
    collectgarbage();
    collectgarbage("stop");
    loop  {
        local a = {}
    } until gcinfo() > 1000
    collectgarbage("restart");
    loop  {
        local a = {}
    } until gcinfo() < 1000
}
lim = 15
a = {}
for i = 1, lim {
    a[({})] = i
}
b = {}
for k, v with pairs(a) {
    b[(k)] = v
}
for n with pairs(b) {
    a[(n)] = nil
    assert(type(n) == 'table' && next(n) == nil);
    collectgarbage();
}
b = nil
collectgarbage();
for n with pairs(a) {
    error('cannot be here');
}
for i = 1, lim {
    a[(i)] = i
}
for i = 1, lim {
    assert(a[(i)] == i);
}
print('weak tables');
a = {}
setmetatable(a, {
    __mode = 'k'
});
for i = 1, lim {
    a[({})] = i
}
for i = 1, lim {
    local t = {}
    a[(t)] = t
}
for i = 1, lim {
    a[(i)] = i
}
for i = 1, lim {
    local s = string.rep('@', i)
    a[(s)] = s .. '#'
}
collectgarbage();
local i = 0
for k, v with pairs(a) {
    assert(k == v || k .. '#' == v);
    i = i + 1
}
assert(i == 3 * lim);
a = {}
setmetatable(a, {
    __mode = 'v'
});
a[(1)] = string.rep('b', 21)
collectgarbage();
assert(a[(1)]);
a[(1)] = nil
for i = 1, lim {
    a[(i)] = {}
}
for i = 1, lim {
    a[(i .. 'x')] = {}
}
for i = 1, lim {
    local t = {}
    a[(t)] = t
}
for i = 1, lim {
    a[(i + lim)] = i .. 'x'
}
collectgarbage();
local i = 0
for k, v with pairs(a) {
    assert(k == v || k - lim .. 'x' == v);
    i = i + 1
}
assert(i == 2 * lim);
a = {}
setmetatable(a, {
    __mode = 'vk'
});
local x, y, z = {}, {}, {}
a[(1)], a[(2)], a[(3)] = x, y, z
a[(string.rep('$', 11))] = string.rep('$', 11)
for i = 4, lim {
    a[(i)] = {}
}
for i = 1, lim {
    a[({})] = i
}
for i = 1, lim {
    local t = {}
    a[(t)] = t
}
collectgarbage();
assert(next(a) != nil);
local i = 0
for k, v with pairs(a) {
    assert((k == 1 && v == x) || (k == 2 && v == y) || (k == 3 && v == z) || k == v);
    i = i + 1
}
assert(i == 4);
x, y, z = nil
collectgarbage();
assert(next(a) == string.rep('$', 11));
collectgarbage("stop");
local u = newproxy(true)
local s = 0
local a = {
    u = 0
}
setmetatable(a, {
    __mode = 'vk'
});
for i = 1, 10 {
    a[(newproxy(u))] = i
}
for k with pairs(a) {
    assert(getmetatable(k) == getmetatable(u));
}
local a1 = {}
for k, v with pairs(a) {
    a1[(k)] = v
}
for k, v with pairs(a1) {
    a[(v)] = k
}
for i = 1, 10 {
    assert(a[(i)]);
}
getmetatable(u).a = a1
getmetatable(u).u = u
{
    local u = u
    getmetatable(u).__gc = fn (o) {
        assert(a[(o)] == 10 - s);
        assert(a[(10 - s)] == nil);
        assert(getmetatable(o) == getmetatable(u));
        assert(getmetatable(o).a[(o)] == 10 - s);
        s = s + 1
    }
}
a1, u = nil
assert(next(a) != nil);
collectgarbage();
assert(s == 11);
collectgarbage();
assert(next(a) == nil);
local u = newproxy(true)
setmetatable(getmetatable(u), {
    __mode = "v"
});
getmetatable(u).__gc = fn (o) {
    os.exit(1);
}
collectgarbage();
local u = newproxy(true)
local m = getmetatable(u)
m.x = {
    {
        0
    } = 1, 
    0 = {
        1
    }
}
setmetatable(m.x, {
    __mode = "kv"
});
m.__gc = fn (o) {
    assert(next(getmetatable(o).x) == nil);
    m = 10
}
u, m = nil
collectgarbage();
assert(m == 10);
u = newproxy(true)
getmetatable(u).__gc = fn () {
    error("!!!");
}
u = nil
assert(!pcall(collectgarbage));
if !rawget(_G, "_soft") {
    print("deep structures");
    local a = {}
    for i = 1, 200000 {
        a = {
            next = a
        }
    }
    collectgarbage();
}
local thread_id = 0
local threads = {}
global fn fn(thread) {
    local x = {}
    threads[(thread_id)] = fn () {
        thread = x
    }
    coroutine.yield();
}
while thread_id < 1000 {
    local thread = coroutine.create(fn)
    coroutine.resume(thread, thread);
    thread_id = thread_id + 1
}
{
    local newproxy, assert, type, print, getmetatable = newproxy, assert, type, print, getmetatable
    local u = newproxy(true)
    local tt = getmetatable(u)
    ___Glob = {
        u
    }
    tt.__gc = fn (o) {
        assert(getmetatable(o) == tt);
        local a = 'xuxu' .. (10 + 3) .. 'joao', {}
        ___Glob = o
        newproxy(o);
        print(">>> closing state " .. "<<<\n");
    }
}
{
    local u = newproxy(true)
    getmetatable(u).__gc = fn (o) {
        return o + 1
    }
    table.insert(___Glob, u);
    for i = 1, 10 {
        table.insert(___Glob, newproxy(u));
    }
}
print('OK');