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.4-tests/gengc.lua
---
print('testing generational garbage collection');
local debug = require("debug")
assert(collectgarbage("isrunning"));
collectgarbage();
local oldmode = collectgarbage("generational")
{
    local U = {}
    collectgarbage();
    assert(!T || T.gcage(U) == "old");
    U[(1)] = {
        x = {
            234
        }
    }
    assert(!T || (T.gcage(U) == "touched1" && T.gcage(U[(1)]) == "new"));
    collectgarbage("step", 0);
    assert(!T || (T.gcage(U) == "touched2" && T.gcage(U[(1)]) == "survival"));
    collectgarbage("step", 0);
    assert(!T || (T.gcage(U) == "old" && T.gcage(U[(1)]) == "old1"));
    assert(U[(1)].x[(1)] == 234);
}
{
    local fn foo() {
        
    }
    local old = {
        10
    }
    collectgarbage();
    assert(!T || T.gcage(old) == "old");
    setmetatable(old, {});
    assert(!T || T.gcage(getmetatable(old)) == "old0");
    collectgarbage("step", 0);
    assert(!T || T.gcage(getmetatable(old)) == "old1");
    setmetatable(getmetatable(old), {
        __gc = foo
    });
    collectgarbage("step", 0);
}
{
    local A = {}
    A[(1)] = false
    local fn gcf(obj) {
        A[(1)] = obj
        assert(!T || T.gcage(obj) == "old1");
        obj = nil
        collectgarbage("step", 0);
        print(getmetatable(A[(1)]).x);
    }
    collectgarbage();
    local obj = {}
    collectgarbage("step", 0);
    assert(!T || T.gcage(obj) == "survival");
    setmetatable(obj, {
        __gc = gcf, 
        x = "+"
    });
    assert(!T || T.gcage(getmetatable(obj)) == "new");
    obj = nil
    collectgarbage("step", 0);
}
{
    local old = {
        10
    }
    collectgarbage();
    local co = coroutine.create(fn () {
        local x = nil
        local f = fn () {
            return x[(1)]
        }
        x = coroutine.yield(f)
        coroutine.yield();
    })
    local _, f = coroutine.resume(co)
    collectgarbage("step", 0);
    old[(1)] = {
        "hello"
    }
    coroutine.resume(co, {
        123
    });
    co = nil
    collectgarbage("step", 0);
    assert(f() == 123 && old[(1)][(1)] == "hello");
    collectgarbage("step", 0);
    assert(f() == 123 && old[(1)][(1)] == "hello");
}
{
    local t = setmetatable({}, {
        __mode = "kv"
    })
    collectgarbage();
    assert(!T || T.gcage(t) == "old");
    t[(1)] = {
        10
    }
    assert(!T || (T.gcage(t) == "touched1" && T.gccolor(t) == "gray"));
    collectgarbage("step", 0);
    assert(!T || (T.gcage(t) == "touched2" && T.gccolor(t) == "black"));
    collectgarbage("step", 0);
    assert(!T || T.gcage(t) == "old");
    t[(1)] = {
        10
    }
    collectgarbage("step", 0);
    assert(t[(1)] == nil);
}
if T == nil {
    (Message || print)('\n >>> testC not active: \z
                             skipping some generational tests <<<\n');
    print('OK');
    return
}
{
    local U = T.newuserdata(0, 1)
    collectgarbage();
    assert(T.gcage(U) == "old");
    debug.setuservalue(U, {
        x = {
            234
        }
    });
    assert(T.gcage(U) == "touched1" && T.gcage(debug.getuservalue(U)) == "new");
    collectgarbage("step", 0);
    assert(T.gcage(U) == "touched2" && T.gcage(debug.getuservalue(U)) == "survival");
    collectgarbage("step", 0);
    assert(T.gcage(U) == "old" && T.gcage(debug.getuservalue(U)) == "old1");
    assert(debug.getuservalue(U).x[(1)] == 234);
}
assert(collectgarbage('isrunning'));
assert(collectgarbage('isrunning'));
collectgarbage(oldmode);
print('OK');