00001
00002 #include <assert.h>
00003 #include <string.h>
00004 #include <stdio.h>
00005 #include "stdtypes.h"
00006 #include "blockpool.h"
00007 #include "pools.h"
00008 #include "str.h"
00009 #include "list.h"
00010 #include "fifo_list.h"
00011 #include "hash_serv.h"
00012 #include "sparse.h"
00013 #include "strtable.h"
00014 #include "sym.h"
00015 #include "type.h"
00016 #include "const.h"
00017 #include "symtable.h"
00018 #include "typetable.h"
00019 #include "dsym.h"
00020
00021
00033 sym *symtable::chain_elem::search_list( STRING item )
00034 {
00035 LIST<sym *>::handle h;
00036 sym *list_sym, *sym;
00037
00038 sym = NULL;
00039 for (h = list.first(); h != NULL; h = list.next(h)) {
00040 list_sym = list.get_item( h );
00041 if ( list_sym->get_name().GetText() == item.GetText() ) {
00042 sym = list_sym;
00043 break;
00044 }
00045 }
00046
00047 return sym;
00048 }
00049
00050
00051
00059 sym *symtable::new_sym( STRING str, uint kind )
00060 {
00061 sym *pNewSym;
00062
00063 assert( alloc_pool != NULL );
00064
00065 switch ( kind ) {
00066
00067 case sy_ident:
00068 pNewSym = new( alloc_pool ) sym_ident( str );
00069 pNewSym->set_scope( get_owner() );
00070 break;
00071
00072 case sy_type:
00073 pNewSym = new( alloc_pool ) sym_type( str );
00074 break;
00075
00076 case sy_const:
00077 pNewSym = new( alloc_pool ) sym_const( str );
00078 break;
00079
00080
00081 case sy_subprog:
00082 pNewSym = new( alloc_pool ) sym_subprog( str );
00083
00084
00085 pNewSym->set_scope( get_owner() );
00086
00087
00088
00089
00090
00091 pNewSym->get_symtab()->set_pool( alloc_pool );
00092
00093 pNewSym->get_typtab()->set_pool( alloc_pool );
00094
00095 pNewSym->get_symtab()->set_owner( pNewSym );
00096 break;
00097
00098
00099 case sy_component:
00100 pNewSym = new( alloc_pool ) sym_component( str );
00101
00102
00103 pNewSym->get_symtab()->set_owner( pNewSym );
00104 break;
00105
00106
00107 case sy_process:
00108 pNewSym = new( alloc_pool ) sym_process( str );
00109
00110
00111 pNewSym->set_scope( get_owner() );
00112
00113 pNewSym->get_symtab()->set_pool( alloc_pool );
00114
00115 pNewSym->get_typtab()->set_pool( alloc_pool );
00116
00117 pNewSym->get_symtab()->set_owner( pNewSym );
00118 break;
00119 case sy_package:
00120 case sy_block_label:
00121 case bad_symbol:
00122 default:
00123
00124 assert( FALSE );
00125 break;
00126 }
00127
00128 assert( pNewSym != NULL );
00129
00130 return pNewSym;
00131 }
00132
00133
00139 sym *symtable::find_sym( STRING name )
00140 {
00141 STRING str;
00142 sym *retsym;
00143
00144 retsym = NULL;
00145 if (name.GetText() != NULL) {
00146
00147
00148
00149
00150 str = strtab.find_string( name, FALSE );
00151 if (str.GetText() != NULL) {
00152 unsigned int ix, val;
00153
00154 val = hash_value( str.GetText() );
00155
00156
00157 ix = val % (table_size - 1);
00158 if (hash->probe( ix )) {
00159 retsym = (*hash)[ ix ].search_list( str );
00160 }
00161 }
00162 }
00163
00164 return retsym;
00165 }
00166
00167
00168
00174 sym *symtable::enter_sym( STRING name, uint kind )
00175 {
00176 unsigned int ix, val;
00177 sym *retsym;
00178 STRING str;
00179
00180 retsym = NULL;
00181
00182 if (kind == sy_process) {
00183
00184
00185
00186
00187
00188
00189 retsym = new_sym( name, kind);
00190 }
00191 else {
00192
00193 assert( name.GetText() != NULL );
00194
00195 val = hash_value( name.GetText() );
00196 str = strtab.find_string( name, TRUE );
00197
00198
00199 ix = val % (table_size - 1);
00200 if (! hash->probe( ix ) ) {
00201
00202 hash->insert( chain_elem(), ix );
00203
00204 retsym = new_sym( str, kind );
00205 (*hash)[ix].list.add( retsym );
00206 }
00207 else {
00208 retsym = (*hash)[ix].search_list( str );
00209 if ( retsym == NULL) {
00210 retsym = new_sym( str, kind );
00211 (*hash)[ix].list.add( retsym );
00212 }
00213 }
00214 }
00215
00216 return retsym;
00217 }
00218
00219
00227 void symtable::dealloc_sub_tables(void)
00228 {
00229 uint i;
00230
00231 for (i = 0; i < table_size; i++) {
00232 if (hash->probe( i )) {
00233 LIST<sym *>::handle h;
00234 sym * pListSym;
00235
00236 for (h = (*hash)[i].list.first(); h != NULL; h = (*hash)[i].list.next(h)) {
00237 pListSym = (*hash)[i].list.get_item( h );
00238 if (pListSym->has_scope()) {
00239 pListSym->get_symtab()->dealloc_sub_tables();
00240 pListSym->dealloc();
00241 }
00242 }
00243 }
00244 }
00245 }
00246
00250 void symtable::pr(FILE *fp)
00251 {
00252 uint i;
00253
00254 for (i = 0; i < table_size; i++) {
00255 if (hash->probe( i )) {
00256 LIST<sym *>::handle h;
00257 sym * pListSym;
00258
00259 for (h = (*hash)[i].list.first(); h != NULL; h = (*hash)[i].list.next(h)) {
00260
00261 pListSym = (*hash)[i].list.get_item( h );
00262 pListSym->get_name().pr(fp);
00263 fprintf(fp, "\n");
00264 }
00265 }
00266 }
00267 }
00268
00269
00270
00275 sym *symtable::get_sym(void)
00276 {
00277 sym * pHashSym;
00278
00279 pHashSym = NULL;
00280
00281 while (list_handle == NULL && hash_slot < table_size) {
00282 if (hash->probe( hash_slot )) {
00283 list_handle = (*hash)[hash_slot].list.first();
00284 }
00285 if (list_handle == NULL) {
00286 hash_slot++;
00287 }
00288 }
00289
00290 if (list_handle != NULL && hash_slot < table_size) {
00291
00292 pHashSym = (*hash)[hash_slot].list.get_item( list_handle );
00293
00294 list_handle = (*hash)[hash_slot].list.next(list_handle);
00295
00296
00297
00298 if (list_handle == NULL)
00299 hash_slot++;
00300 }
00301
00302 return pHashSym;
00303 }
00304