00001 00002 #ifndef SYMTABLE_H 00003 #define SYMTABLE_H 00004 00005 00006 /*===============================<o>===================================== 00007 00008 Copyright 1996, 1997, 2004 Ian Kaplan, Bear Products International, 00009 www.bearcave.com. 00010 00011 All Rights Reserved 00012 00013 You may use this software in software components for which you do 00014 not collect money (e.g., non-commercial software). All commercial 00015 use is reserved. 00016 00017 ===============================<o>=====================================*/ 00018 00019 00020 /* 00021 include dependencies: 00022 00023 <string.h> -- strlen(), strcmp(), etc... 00024 <stdio.h> -- for printf and FILE (needed by str.h) 00025 stdtypes.h 00026 blockpool.h 00027 pools.h 00028 str.h 00029 list.h 00030 hash_serv.h 00031 sparse.h 00032 strtable.h 00033 sym.h 00034 type.h 00035 dsym.h 00036 00037 00038 */ 00039 00040 #include "list.h" 00041 #include "sparse.h" 00042 #include "hash_serv.h" 00043 00045 const uint SQRT_SYMTAB = 512; 00046 00059 class symtable : public hash_services 00060 { 00061 private: 00062 00064 class chain_elem { 00065 public: 00066 LIST<sym *> list; 00067 private: 00068 chain_elem(const chain_elem &) {} 00069 public: 00070 chain_elem(void) { list = LIST<sym *>(); } 00071 ~chain_elem(void) { list.dealloc(); } 00072 00073 sym *search_list( STRING item ); 00074 00075 unsigned int list_len(void) 00076 { 00077 LIST<sym *>::handle h; 00078 int len = 0;; 00079 00080 for (h = list.first(); h != NULL; h = list.next(h)) { 00081 len++; 00082 } // for 00083 return len; 00084 } // list_len 00085 00086 }; // class chain_elem 00087 00088 unsigned int table_size; 00089 unsigned int hash_slot; // used in iterating through the hash table 00090 LIST<sym *>::handle list_handle; 00091 00092 sparse_array<chain_elem> *hash; 00093 pool *alloc_pool; 00094 // the symbol that contains "owns" this symbol table. 00095 sym *owner; 00096 00097 private: 00098 // allocate a new symbol 00099 sym *new_sym( STRING str, uint kind ); 00100 00101 private: 00102 // outlaw the copy constructor, since we don't want to call 00103 // the destructor which will deallocate the sparse array 00104 symtable( const symtable &st ) { assert( FALSE ); } 00105 00106 public: 00107 void init(uint size = SQRT_SYMTAB) 00108 { 00109 hash = new sparse_array<chain_elem>( (const unsigned int)size ); 00110 table_size = hash->get_total_size(); 00111 } 00112 00113 symtable( unsigned int size = SQRT_SYMTAB, pool *p = NULL ) 00114 { 00115 00116 owner = NULL; 00117 alloc_pool = p; 00118 init( size ); 00119 } 00120 void dealloc() 00121 { 00122 hash->dealloc(); 00123 00124 delete hash; 00125 } 00126 ~symtable() 00127 { 00128 dealloc_sub_tables(); // Deallocate all the "child" symbol tables. 00129 dealloc(); // Deallocate the sparse array and list memory for 00130 // this symbol table. 00131 } 00132 00133 void set_pool( pool *p ) 00134 { 00135 alloc_pool = p; 00136 } 00137 00138 void set_owner( sym *parent ) { owner = parent; } 00139 00140 // The global scope is the only scope without an owner. 00141 // Only components (and, perhaps, processes) are entered in the 00142 // global scope. The get_owner function should not be called 00143 // for these. So owner should never be NULL. 00144 sym *get_owner(void) 00145 { 00146 assert( owner != NULL ); 00147 return owner; 00148 } 00149 00150 00151 // enter_sym: enter a symbol into the symbol table. 00152 // This function will allocate the space for the 00153 // symbol in the memory pool associated with the 00154 // symbol table. The enter_sym function will also 00155 // enter the STRING in the string table if necessary. 00156 sym *enter_sym( STRING str, uint kind ); 00157 00158 sym *enter_sym( const char *pChar, uint kind ) 00159 { 00160 STRING str; 00161 00162 str.SetText( pChar ); 00163 return enter_sym( str, kind ); 00164 } // enter_sym 00165 00166 // find_sym: search for a symbol. Returns the symbol if found, 00167 // NULL otherwise. 00168 sym *find_sym( STRING name ); 00169 00170 sym *find_sym( const char *pChar ) 00171 { 00172 STRING str; 00173 00174 str.SetText( pChar ); 00175 return find_sym( str ); 00176 00177 } // find_sym with a char * argument 00178 00179 // note that hash can never be NULL, since it is initialized in the constructor 00180 unsigned int get_percent_alloced(void) { return hash->get_percent_alloced(); } 00181 00182 unsigned int get_max_list(void) 00183 { 00184 uint i; 00185 uint max, len; 00186 00187 max = 0; 00188 for (i = 0; i < table_size; i++) { 00189 if (hash->probe( i )) { 00190 len = (*hash)[i].list_len(); 00191 if (len > max) { 00192 max = len; 00193 } 00194 } 00195 } 00196 return max; 00197 } // get_max_list 00198 00199 void pr(FILE *fp = stdout); 00200 00206 void dealloc_sub_tables(); 00207 00220 sym *first(void) 00221 { 00222 hash_slot = 0; 00223 list_handle = NULL; 00224 return get_sym(); 00225 } 00226 00227 sym *get_sym(void); 00228 00229 }; // class symtable 00230 00231 00232 extern symtable glob_symtab; 00233 00234 #endif