#drinc:util.g #toy.g #externs.g /* * symbol.d: routines for maintaining symbol tables. */ ulong SYMBOL_TABLE_SIZE = 1023; ulong EntryCount; [SYMBOL_TABLE_SIZE]SymbolEntry_t SymbolTable; /* * symbolInit - initialize the symbol table. */ proc symbolInit()void: register *SymbolEntry_t se; register uint i; se := &SymbolTable[0]; for i from 0 upto SYMBOL_TABLE_SIZE - 1 do se*.se_kind := sk_empty; se := se + sizeof(SymbolEntry_t); od; EntryCount := 0; corp; /* * symbolTerm - clean up the symbol table stuff. */ proc symbolTerm()void: register *SymbolEntry_t se; register uint i; se := &SymbolTable[0]; for i from 0 upto SYMBOL_TABLE_SIZE - 1 do if se*.se_kind ~= sk_empty then se*.se_kind := sk_empty; memFree(se*.se_name, se*.se_length * sizeof(char)); fi; se := se + sizeof(SymbolEntry_t); od; corp; /* * symbolPurge - purge all local symbols from the symbol table. */ proc symbolPurge()void: register *SymbolEntry_t se; register uint i; se := &SymbolTable[0]; for i from 0 upto SYMBOL_TABLE_SIZE - 1 do if se*.se_kind = sk_parameter or se*.se_kind = sk_localVariable then se*.se_kind := sk_empty; memFree(se*.se_name, se*.se_length * sizeof(char)); EntryCount := EntryCount - 1; fi; se := se + sizeof(SymbolEntry_t); od; corp; /* * enter - enter/lookup a symbol in the table. If the symbol is not found, * we enter it, but leave its entry type as sk_empty. When we enter * it, we copy the string over. */ proc enter(register *char name; register ulong length)*SymbolEntry_t: register *SymbolEntry_t se; se := &SymbolTable[0] + ((make(name* - '\e', uint) << 6) | make((name + (length - 2) * sizeof(char))* - '\e', uint)) % SYMBOL_TABLE_SIZE * sizeof(SymbolEntry_t); while se*.se_kind ~= sk_empty and (se*.se_length ~= length or not CharsEqual(se*.se_name, name)) do se := if se = &SymbolTable[0] then se + (SYMBOL_TABLE_SIZE - 1) * sizeof(SymbolEntry_t) else se - sizeof(SymbolEntry_t) fi od; if se*.se_kind = sk_empty then if EntryCount = SYMBOL_TABLE_SIZE - 1 then abort("symbol table overflow"); fi; EntryCount := EntryCount + 1; se*.se_name := memAlloc(length * sizeof(char)); BlockCopy(se*.se_name, name, length * sizeof(char)); se*.se_length := length; fi; se corp; /* * fixLocals - add an offset to all local symbols. */ proc fixLocals(int extraOffset)void: register *SymbolEntry_t se; register uint i; se := &SymbolTable[0]; for i from 0 upto SYMBOL_TABLE_SIZE - 1 do if se*.se_kind = sk_parameter or se*.se_kind = sk_localVariable then se*.se_value := se*.se_value + extraOffset; fi; se := se + sizeof(SymbolEntry_t); od; corp;