- Use a map for symbol tables instead of an array.

SVN r2258 (scripting)
This commit is contained in:
Randy Heit 2010-03-30 04:11:16 +00:00
parent e553f9a34f
commit d87d2c731f
4 changed files with 28 additions and 57 deletions

View file

@ -389,9 +389,12 @@ void DObject::SerializeUserVars(FArchive &arc)
// Write all user variables. // Write all user variables.
for (; symt != NULL; symt = symt->ParentSymbolTable) for (; symt != NULL; symt = symt->ParentSymbolTable)
{ {
for (unsigned i = 0; i < symt->Symbols.Size(); ++i) PSymbolTable::MapType::Iterator it(symt->Symbols);
PSymbolTable::MapType::Pair *pair;
while (it.NextPair(pair))
{ {
PSymbol *sym = symt->Symbols[i]; PSymbol *sym = pair->Value;
if (sym->SymbolType == SYM_Variable) if (sym->SymbolType == SYM_Variable)
{ {
PSymbolVariable *var = static_cast<PSymbolVariable *>(sym); PSymbolVariable *var = static_cast<PSymbolVariable *>(sym);

View file

@ -481,11 +481,16 @@ PSymbolTable::~PSymbolTable ()
size_t PSymbolTable::MarkSymbols() size_t PSymbolTable::MarkSymbols()
{ {
for (unsigned int i = 0; i < Symbols.Size(); ++i) size_t count = 0;
MapType::Iterator it(Symbols);
MapType::Pair *pair;
while (it.NextPair(pair))
{ {
GC::Mark(Symbols[i]); GC::Mark(pair->Value);
count++;
} }
return Symbols.Size() * sizeof(Symbols[0]); return count * sizeof(Symbols[0]);
} }
void PSymbolTable::ReleaseSymbols() void PSymbolTable::ReleaseSymbols()
@ -502,64 +507,21 @@ void PSymbolTable::SetParentTable (PSymbolTable *parent)
PSymbol *PSymbolTable::FindSymbol (FName symname, bool searchparents) const PSymbol *PSymbolTable::FindSymbol (FName symname, bool searchparents) const
{ {
int min, max; PSymbol * const *value = Symbols.CheckKey(symname);
if (value == NULL && searchparents && ParentSymbolTable != NULL)
min = 0;
max = (int)Symbols.Size() - 1;
while (min <= max)
{ {
unsigned int mid = (min + max) / 2; return ParentSymbolTable->FindSymbol(symname, searchparents);
PSymbol *sym = Symbols[mid];
if (sym->SymbolName == symname)
{
return sym;
} }
else if (sym->SymbolName < symname) return value != NULL ? *value : NULL;
{
min = mid + 1;
}
else
{
max = mid - 1;
}
}
if (searchparents && ParentSymbolTable != NULL)
{
return ParentSymbolTable->FindSymbol (symname, true);
}
return NULL;
} }
PSymbol *PSymbolTable::AddSymbol (PSymbol *sym) PSymbol *PSymbolTable::AddSymbol (PSymbol *sym)
{ {
// Insert it in sorted order. // Symbols that already exist are not inserted.
int min, max, mid; if (Symbols.CheckKey(sym->SymbolName) != NULL)
min = 0;
max = (int)Symbols.Size() - 1;
while (min <= max)
{ {
mid = (min + max) / 2;
PSymbol *tsym = Symbols[mid];
if (tsym->SymbolName == sym->SymbolName)
{ // A symbol with this name already exists in the table
return NULL; return NULL;
} }
else if (tsym->SymbolName < sym->SymbolName) Symbols.Insert(sym->SymbolName, sym);
{
min = mid + 1;
}
else
{
max = mid - 1;
}
}
// Good. The symbol is not in the table yet.
Symbols.Insert (MAX(min, max), sym);
return sym; return sym;
} }

View file

@ -141,8 +141,10 @@ struct PSymbolTable
void ReleaseSymbols(); void ReleaseSymbols();
private: private:
typedef TMap<FName, PSymbol *> MapType;
PSymbolTable *ParentSymbolTable; PSymbolTable *ParentSymbolTable;
TArray<PSymbol *> Symbols; MapType Symbols;
friend class DObject; friend class DObject;
}; };

View file

@ -241,8 +241,10 @@ static void DoParse(const char *filename)
parser = ZCCParseAlloc(malloc); parser = ZCCParseAlloc(malloc);
failed = false; failed = false;
#ifdef _DEBUG
FILE *f = fopen("trace.txt", "w"); FILE *f = fopen("trace.txt", "w");
ZCCParseTrace(f, ""); ZCCParseTrace(f, "");
#endif
while (sc.GetToken()) while (sc.GetToken())
{ {
if (sc.TokenType == TK_StringConst) if (sc.TokenType == TK_StringConst)
@ -294,10 +296,12 @@ static void DoParse(const char *filename)
ZCCParse(parser, ZCC_EOF, value, &sc); ZCCParse(parser, ZCC_EOF, value, &sc);
ZCCParse(parser, 0, value, &sc); ZCCParse(parser, 0, value, &sc);
ZCCParseFree(parser, free); ZCCParseFree(parser, free);
#ifdef _DEBUG
if (f != NULL) if (f != NULL)
{ {
fclose(f); fclose(f);
} }
#endif
} }
CCMD(parse) CCMD(parse)