Beispiel #1
0
SymEntry* SymFindAny (SymTable* Scope, const StrBuf* Name)
/* Find a symbol in the given or any of its parent scopes. The function will
** never create a new symbol, since this can only be done in one specific
** scope.
*/
{
    /* Generate the name hash */
    unsigned Hash = HashBuf (Name);

    /* Search for the symbol */
    SymEntry* Sym;
    do {
        /* Search in the current table. Ignore entries flagged with SF_UNUSED,
        ** because for such symbols there is a real entry in one of the parent
        ** scopes.
        */
        if (SymSearchTree (Scope->Table[Hash % Scope->TableSlots], Name, &Sym) == 0) {
            if (Sym->Flags & SF_UNUSED) {
                Sym = 0;
            } else {
                /* Found, return it */
                break;
            }
        } else {
            Sym = 0;
        }

        /* Not found, search in the parent scope, if we have one */
        Scope = Scope->Parent;

    } while (Sym == 0 && Scope != 0);

    /* Return the result */
    return Sym;
}
Beispiel #2
0
SymEntry* SymFind (SymTable* Scope, const StrBuf* Name, SymFindAction Action)
/* Find a new symbol table entry in the given table. If Action contains
** SYM_ALLOC_NEW and the entry is not found, create a new one. Return the
** entry found, or the new entry created, or - in case Action is
** SYM_FIND_EXISTING - return 0.
*/
{
    SymEntry* S;

    /* Global symbol: Get the hash value for the name */
    unsigned Hash = HashBuf (Name) % Scope->TableSlots;

    /* Search for the entry */
    int Cmp = SymSearchTree (Scope->Table[Hash], Name, &S);

    /* If we found an entry, return it */
    if (Cmp == 0) {
        if ((Action & SYM_CHECK_ONLY) == 0 && SymTabIsClosed (Scope)) {
            S->Flags |= SF_FIXED;
        }
        return S;
    }

    if (Action & SYM_ALLOC_NEW) {

        /* Otherwise create a new entry, insert and return it. If the scope is
        ** already closed, mark the symbol as fixed so it won't be resolved
        ** by a symbol in the enclosing scopes later.
        */
        SymEntry* N = NewSymEntry (Name, SF_NONE);
        if (SymTabIsClosed (Scope)) {
            N->Flags |= SF_FIXED;
        }
        N->Sym.Tab = Scope;
        if (S == 0) {
            Scope->Table[Hash] = N;
        } else if (Cmp < 0) {
            S->Left = N;
        } else {
            S->Right = N;
        }
        ++Scope->TableEntries;
        return N;

    }

    /* We did not find the entry and AllocNew is false. */
    return 0;
}
Beispiel #3
0
static unsigned HT_GenHash (const void* Key)
/* Generate the hash over a key. */
{
    return HashBuf (Key);
}