00001 #define TRACE_NAME "SymbolTable"
00002
00003 #include "Symbol.h"
00004
00005
00006 #include <hash_set>
00007 #include <hash_map>
00008
00009
00010
00012
00013
00014
00016
00017 size_t SymbolTable::nextTableNumber = 0;
00018
00019 SymbolTable::SymbolTable()
00020 : first_hole(0), count(0)
00021 {
00022 tableNumber = nextTableNumber++;
00023 }
00024
00025 #if 0
00026
00027 SymbolTable::SymbolTable(const SymbolTable& other)
00028 {
00029 NOT_IMPLEMENTED
00030 }
00031
00032 const SymbolTable& SymbolTable::operator=(const SymbolTable& other)
00033 {
00034 NOT_IMPLEMENTED
00035 }
00036
00037 bool SymbolTable::operator==(const SymbolTable& other) const
00038 {
00039 NOT_IMPLEMENTED
00040 }
00041
00042 bool SymbolTable::operator<(const SymbolTable& other) const
00043 {
00044 NOT_IMPLEMENTED
00045 }
00046
00047 size_t SymbolTable::hash() const
00048 {
00049 NOT_IMPLEMENTED
00050 }
00051
00052 std::ostream& SymbolTable::print_to(std::ostream& stream) const
00053 {
00054 NOT_IMPLEMENTED
00055 }
00056
00057 #endif
00058
00059 SymbolTable::~SymbolTable()
00060 {
00061
00062
00063 for (unsigned int i = 0; i<records.size(); i++) {
00064 reclaim(i);
00065 }
00066 }
00067
00069
00070
00071
00073
00074 SymbolTable::Index SymbolTable::lookupOrAdd(SymbolTable::Type type,
00075 const char* text,
00076 bool* added_ptr)
00077 {
00078 Index index;
00079
00080
00081
00082
00083
00084 TRACE "looking for symbol type=" << type << " text=" << text << std::endl;
00085 Iter iter;
00086
00087 if (type >= map.size()) {
00088 TRACE "vector of maps (by type) being expanded from " <<
00089 map.size() << " to " << type+1 << std::endl;
00090 map.resize(type+1);
00091 }
00092
00093
00094
00095
00096 if (text) {
00097 iter = map[type].find( const_cast<char *> (text) );
00098 if (iter != map[type].end()) {
00099 index = (*iter).second;
00100 records[index].refCount++;
00101 TRACE " found it, index=" << index << std::endl;
00102 return index;
00103 }
00104 TRACE " not found" << std::endl;
00105 }
00106
00107 if (added_ptr) *added_ptr = true;
00108
00109
00110 if (first_hole) {
00111 TRACE " using hole" << std::endl;
00112 index = first_hole;
00113
00114
00115 first_hole = records[first_hole].nextHole;
00116 } else {
00117
00118 TRACE " expanding vector" << std::endl;
00119 index = records.size();
00120 records.push_back(Record());
00121 assert(records.size() == index+1);
00122 }
00123
00124 ++count;
00125 records[index].type = type;
00126 records[index].refCount = 1;
00127 records[index].boundTo = Symbol(0,0);
00128 TRACE " created as index " << index << std::endl;
00129
00130 if (text) {
00131 char *key = strdup(text);
00132 records[index].text = key;
00133 map[type][key] = index;
00134 iter = map[type].find( const_cast<char *> (text) );
00135 if (iter != map[type].end()) {
00136 TRACE " and it's present now" << std::endl;
00137 } else {
00138 TRACE " BUT IT'S MISSING" << std::endl;
00139 TRACE const_cast<char *> (text) << "<>" << key << std::endl;
00140 }
00141 } else {
00142 records[index].text = 0;
00143 }
00144
00145 return index;
00146 }
00147
00148
00149
00151
00152
00153
00155
00156
00157 void SymbolTable::reclaim(Index index)
00158 {
00159
00160 #ifdef DO_RECLAIM
00161 turn this off for an urgent demo; theres some bug
00162
00163 TRACE "reclaiming Symbol " << index << std::endl;
00164
00165 map[records[index].type].erase(records[index].text);
00166 delete records[index].text;
00167
00168 records[index].nextHole = first_hole;
00169 first_hole = index;
00170
00171 count--;
00172 #endif
00173
00174 #if DO_TRACE
00175 TRACE "Holes: ";
00176 int i = first_hole;
00177 while (i) {
00178 TRACE i << " ";
00179 i = records[i].nextHole;
00180 }
00181 TRACE std::endl;
00182 #endif
00183 }
00184 #undef TRACE_NAME