Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

SymbolTable.cpp

00001 #define TRACE_NAME "SymbolTable"
00002 
00003 #include "Symbol.h"      // Not SymbolTable.h, to avoid loop
00004 // $Id: SymbolTable_8cpp-source.html,v 1.5 2001/10/10 20:40:58 sandro Exp $
00005 
00006 #include <hash_set>
00007 #include <hash_map>
00008 
00009 
00010 
00012 //
00013 //  Standard Member Functions
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  /* omit definitions until they are implemented */
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 /* omit definitions until they are implemented */
00058     
00059 SymbolTable::~SymbolTable()
00060 {
00061     // Um -- what if people still have references?  Might just be loops...
00062     // let's just free the char*
00063     for (unsigned int i = 0; i<records.size(); i++) {
00064     reclaim(i);
00065     }
00066 }
00067 
00069 //
00070 //  Additional Public Member Functions
00071 //
00073 
00074 SymbolTable::Index SymbolTable::lookupOrAdd(SymbolTable::Type type, 
00075                         const char* text,
00076                         bool* added_ptr)
00077 {
00078     Index index;
00079     /*
00080       Look up this type/text combintion in our tables; if it's
00081       not found, then copy the information and add it.
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     // we can't just use [] because if it's not found, we'll be
00094     // making the entry in the hash_map use a copy of this char* 
00095     // at a different address.
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     // find a slot in the table and use it, add to table
00110     if (first_hole) {
00111     TRACE "  using hole" << std::endl;
00112     index = first_hole;
00113     // in the blank record spot, the refCount there should the index of
00114     // the next hole (or zero if no more)
00115     first_hole = records[first_hole].nextHole;
00116     } else {
00117     // no holes
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 //  Additional Private Member Functions
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

Home to blindfold. This page generated via doxygen 1.2.11.1 Wed Oct 10 16:40:33 2001.