Ejemplo n.º 1
0
void Scope::Adopt(Scope& child, const std::string& key, std::uint32_t index)
{
    if (key == std::string())
        throw std::exception("Key cannot be an empty string.");

    child.Orphan();
    child.mParent = this;

    // try to find entry first in this scope
    Datum* d = Find(key);
    if (d != nullptr)
    {
        if (d->GetType() != Datum::Table)
            throw std::exception("Found entry is not a table!");
        if (d->IsExternal())
            throw std::exception("Table is external. Cannot modify data owned by something else.");

        std::uint32_t originalDatumSize = d->Size();

        // if a scope is empty or not pointing to anything at the given index, we can just have it point to something else
        if (originalDatumSize <= index || d->GetTable(index) == nullptr || d->GetTable(index)->mOrder.Size() == 0)
            d->Set(&child, index);

        // otherwise, we add in the child scope and rearrange the datum array if necessary
        else
        {
            if (index < originalDatumSize)
            {
                d->SetSize(originalDatumSize + 1);
                for (std::uint32_t i = originalDatumSize; i > index; --i)
                {
                    d->Set(d->GetTable(i - 1), i);
                }
            }
            else if (index > originalDatumSize)
            {
                index = originalDatumSize;
            }
            d->Set(&child, index);
        }
    }
    else
    {
        Datum scopeDatum;
        scopeDatum = &child;

        std::pair<std::string, Datum> pair(key, scopeDatum);
        HashMap<std::string, Datum>::Iterator iterator = mTable.Insert(pair);
        mOrder.PushBack(&(*iterator));
    }
}
Ejemplo n.º 2
0
void Scope::Orphan()
{
    std::string scopeName;
    if (mParent != nullptr)
    {

#ifdef DEBUG
        assert(mParent->FindName(this, scopeName));
#else
        mParent->FindName(this, scopeName);
#endif

        Datum* d = mParent->Find(scopeName);

        std::uint32_t datumSize = d->Size();

        for (std::uint32_t i = 0; i < datumSize; ++i)
        {
            if (d->GetTable(i) == this)
            {
                d->Set((Scope*)nullptr, i);
                break;
            }
        }
    }
    mParent = nullptr;
}
Ejemplo n.º 3
0
Scope& Scope::AppendScope(const std::string& key)
{
    if (key == std::string())
        throw std::exception("Key cannot be an empty string.");

    Scope* newScope = new Scope();
    newScope->mParent = this;

    // try to find entry first in this scope
    Datum* d = Find(key);
    if (d != nullptr)
    {
        if (d->GetType() != Datum::Table && d->GetType() != Datum::Unknown)
        {
            delete newScope;
            throw std::exception("Found entry is not a table!");
        }
        if (d->IsExternal())
        {
            delete newScope;
            throw std::exception("Table entry is external. Cannot modify data owned by something else.");
        }

        // a new scope gets added into this table datum
        std::uint32_t datumSize = d->Size();
        d->Set(newScope, datumSize);
        return *d->GetTable(datumSize);
    }

    // if no entry is found, create new datum with this scope
    Datum scopeDatum;
    scopeDatum = newScope;
    std::pair<std::string, Datum> pair(key, scopeDatum);
    HashMap<std::string, Datum>::Iterator iterator = mTable.Insert(pair);
    mOrder.PushBack(&(*iterator));
    return *(iterator->second.GetTable());
}