gsc-tool/src/gsc/common/scope.cpp
2023-03-02 16:41:32 +01:00

184 lines
4.2 KiB
C++

// Copyright 2023 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#include "xsk/stdinc.hpp"
#include "xsk/gsc/common/scope.hpp"
namespace xsk::gsc
{
scope::scope() : abort{ scope::abort_none }, create_count{ 0 }, public_count{ 0 }, is_last{ false }
{
}
auto scope::transfer_dec(scope::ptr const& child) -> void
{
for (auto i = u32{ 0 }; i < vars.size(); i++)
{
child->vars.push_back(vars[i]);
}
child->public_count = static_cast<u32>(vars.size());
}
auto scope::transfer(scope::ptr const& child) -> void
{
child->abort = scope::abort_none;
child->loc_break = loc_break;
child->loc_cont = loc_cont;
for (auto i = u32{ 0 }; i < child->public_count || i < create_count; i++)
{
auto pos = child->find(i, vars[i].name);
if (pos < 0)
{
child->public_count++;
child->vars.insert(child->vars.begin() + i, vars[i]);
}
else
{
if (pos > static_cast<i32>(i))
std::rotate(child->vars.rend() - pos - 1, child->vars.rend() - pos, child->vars.rend() - i);
else
std::rotate(child->vars.begin() + pos, child->vars.begin() + pos + 1, child->vars.begin() + i + 1);
child->vars[i].init = vars[i].init;
if (child->public_count <= i)
child->public_count++;
}
}
child->create_count = create_count;
}
auto scope::copy(scope::ptr const& child) -> void
{
child->vars = vars;
child->create_count = create_count;
child->public_count = 0;
}
auto scope::append_dec(scope::ptr const& child) -> void
{
for (auto i = vars.size(); i < child->public_count; i++)
{
vars.push_back(child->vars[i]);
}
}
auto scope::append(std::vector<scope*> const& childs) -> void
{
auto glob = true;
if (childs.size() == 0) return;
for (auto i = usize{ 0 }; i < childs[0]->vars.size(); i++)
{
glob = true;
auto& var = childs[0]->vars[i];
if (find(0, var.name) < 0)
{
for (auto j = usize{ 1 }; j < childs.size(); j++)
{
if (childs[j]->find(0, var.name) < 0)
{
glob = false;
}
}
if (glob)
{
vars.push_back(var);
}
}
}
}
auto scope::merge(std::vector<scope*> const& childs) -> void
{
if (childs.size() == 0) return;
for (auto i = usize{ 0 }; i < childs.size(); i++)
{
auto child = childs[i];
child->public_count = static_cast<u32>(vars.size());
for (auto j = usize{ 0 }; j < vars.size(); j++)
{
auto pos = child->find(j, vars[j].name);
if (pos < 0)
{
child->vars.insert(child->vars.begin() + j, vars[j]);
}
else if (pos > static_cast<i32>(j))
{
auto& v = child->vars;
std::rotate(v.rend() - pos - 1, v.rend() - pos, v.rend() - j);
}
}
}
}
auto scope::init(scope::ptr const& child) -> void
{
create_count = child->create_count;
for (auto i = u32{ 0 }; i < create_count; i++)
{
if (!vars[i].init)
vars[i].init = true;
}
}
auto scope::init(std::vector<scope*> const& childs) -> void
{
if (childs.size() == 0) return;
auto count = childs[0]->public_count;
for (auto i = usize{ 1 }; i < childs.size(); i++)
{
if (childs[i]->public_count < count)
count = childs[i]->public_count;
}
create_count = count;
auto init = true;
for (auto i = u32{ 0 }; i < count; i++)
{
init = true;
if (!vars[i].init)
{
for (auto j = usize{ 0 }; j < childs.size(); j++)
{
if (!childs[j]->vars[i].init)
init = false;
}
if (init) vars[i].init = true;
}
}
}
auto scope::find(usize start, std::string const& name) -> i32
{
for (auto i = start; i < vars.size(); i++)
{
if (vars[i].name == name)
return static_cast<i32>(i);
}
return -1;
}
} // namespace xsk::gsc