|
|
1.1 ! root 1: /*ident "@(#)ctrans:src/table.c 1.3" */ ! 2: /************************************************************************** ! 3: ! 4: C++ source for cfront, the C++ compiler front-end ! 5: written in the computer science research center of Bell Labs ! 6: ! 7: Copyright (c) 1984 AT&T, Inc. All Rights Reserved ! 8: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC. ! 9: ! 10: table.c: ! 11: ! 12: *****************************************************************************/ ! 13: ! 14: #include "cfront.h" ! 15: #include "size.h" ! 16: ! 17: #ifdef DBG ! 18: extern long node_id; ! 19: #define DBCHECK() if(node::allocated) error('i',"allocated node (id %d, base%k) on free list! (src: \"%s\", %d",node::id,node::base,__FILE__,__LINE__); ! 20: #else ! 21: #define DBCHECK() /**/ ! 22: #endif ! 23: ! 24: table::table(short sz, Ptable nx, Pname n) ! 25: /* ! 26: create a symbol table with "size" entries ! 27: the scope of table is enclosed in the scope of "nx" ! 28: ! 29: both the vector of class name pointers and the hash table ! 30: are initialized containing all zeroes ! 31: ! 32: to simplify hashed lookup entries[0] is never used ! 33: so the size of "entries" must be "size+1" to hold "size" entries ! 34: */ ! 35: { ! 36: DBCHECK(); ! 37: base = TABLE; ! 38: t_name = n; ! 39: size = sz = (sz<=0) ? 2 : sz+1; ! 40: //fprintf(stderr,"table::table %d %s %d (%d %d)\n", this, (n)?n->string:"?", sz,(sz*3)/2); ! 41: entries = new Pname[sz]; ! 42: hashsize = sz = (sz*3)/2; ! 43: hashtbl = new short[sz]; ! 44: next = nx; ! 45: free_slot = 1; ! 46: DBID(); ! 47: } ! 48: ! 49: table::~table() ! 50: { ! 51: delete entries; ! 52: delete hashtbl; ! 53: } ! 54: ! 55: Pname table::look(char* s, TOK k) ! 56: /* ! 57: look for "s" in table, ignore entries which are not of "k" type ! 58: look and insert MUST be the same lookup algorithm ! 59: */ ! 60: { ! 61: Ptable t; ! 62: register char * p; ! 63: register char * q; ! 64: register int i; ! 65: Pname n; ! 66: int rr; ! 67: ! 68: // if (s == 0) error('i',"%d->look(0)",this); ! 69: // if (this == 0) error('i',"0->look(%s)",s); ! 70: // if (base != TABLE) error('i',"(%d,%d)->look(%s)",this,base,s); ! 71: ! 72: /* use simple hashing with linear search for overflow */ ! 73: ! 74: p = s; ! 75: i = 0; ! 76: while (*p) i += (i + *p++); /* i<<1 ^ *p++ better?*/ ! 77: rr = (0<=i) ? i : -i; ! 78: ! 79: for (t=this; t; t=t->next) { ! 80: /* in this and all enclosing scopes look for name "s" */ ! 81: Pname* np = t->entries; ! 82: int mx = t->hashsize; ! 83: short* hash = t->hashtbl; ! 84: int firsti = i = rr%mx; ! 85: ! 86: do { ! 87: if (hash[i] == 0) goto not_found; ! 88: n = np[hash[i]]; ! 89: if (n == 0) error('i',"hashed lookup"); ! 90: p = n->string; /* strcmp(n->n_string,s) */ ! 91: q = s; ! 92: while (*p && *q) ! 93: if (*p++ != *q++) goto nxt; ! 94: if (*p == *q) goto found; ! 95: nxt: ! 96: if (mx <= ++i) i = 0; /* wrap around */ ! 97: } while (i != firsti); ! 98: ! 99: found: ! 100: for (; n; n=n->n_tbl_list){ /* for all name "s"s look for a key match */ ! 101: if (n->n_key == k) return n; ! 102: } ! 103: ! 104: not_found:; ! 105: } ! 106: ! 107: return 0; /* not found && no enclosing scope */ ! 108: } ! 109: ! 110: bit Nold; /* non-zero if last insert() failed */ ! 111: ! 112: Pname table::insert(Pname nx, TOK k) ! 113: /* ! 114: the lookup algorithm MUST be the same as look ! 115: if nx is found return the older entry otherwise a copy of nx; ! 116: Nold = (nx found) ? 1 : 0; ! 117: */ ! 118: { ! 119: register char * p; ! 120: register int i; ! 121: Pname n; ! 122: Pname* np = entries; ! 123: Pname* link; ! 124: int firsti; ! 125: int mx = hashsize; ! 126: short* hash = hashtbl; ! 127: char* s = nx->string; ! 128: ! 129: if (s==0) error('i',"%p->insert(0,%k)",this,k); ! 130: nx->n_key = k; ! 131: if (nx->n_tbl_list || nx->n_table) error('i',"%n in two tables",nx); ! 132: /* use simple hashing with linear search for overflow */ ! 133: ! 134: p = s; ! 135: i = 0; ! 136: while (*p) i += (i + *p++); ! 137: if (i<0) i = -i; ! 138: firsti = i = i%mx; ! 139: ! 140: do { /* look for name "s" */ ! 141: if (hash[i] == 0) { ! 142: hash[i] = free_slot; ! 143: goto add_np; ! 144: } ! 145: n = np[hash[i]]; ! 146: if (n == 0) error('i',"hashed lookup"); ! 147: if (strcmp(n->string,s) == 0) goto found; ! 148: /* ! 149: p = n->string; ! 150: q = s; ! 151: while (*p && *q) if (*p++ != *q++) goto nxt; ! 152: if (*p == *q) goto found; ! 153: nxt: ! 154: */ ! 155: if (mx <= ++i) i = 0; /* wrap around */ ! 156: } while (i != firsti); ! 157: ! 158: error("N table full"); ! 159: ! 160: found: ! 161: ! 162: ! 163: for(;;) { ! 164: if ( k!=NESTED && n->n_key==k) { Nold = 1; return n; } ! 165: ! 166: if (n->n_tbl_list) ! 167: n = n->n_tbl_list; ! 168: else { ! 169: link = &(n->n_tbl_list); ! 170: goto re_allocate; ! 171: } ! 172: } ! 173: ! 174: add_np: ! 175: if (size <= free_slot) { ! 176: grow(2*size); ! 177: return insert(nx,k); ! 178: } ! 179: ! 180: link = &(np[free_slot++]); ! 181: ! 182: re_allocate: ! 183: { ! 184: Pname nw = new name; ! 185: *nw = *nx; ! 186: char* ps = new char[strlen(s)+1]; // copy string to safer store ! 187: strcpy(ps,s); ! 188: // Nstr++; ! 189: nw->string = ps; ! 190: nw->n_table = this; ! 191: *link = nw; ! 192: Nold = 0; ! 193: // Nname++; ! 194: return nw; ! 195: } ! 196: } ! 197: ! 198: void table::grow(int g) ! 199: { ! 200: short* hash; ! 201: register int j; ! 202: int mx; ! 203: register Pname* np; ! 204: Pname n; ! 205: ! 206: if (g <= free_slot) error('i',"table.grow(%d,%d)",g,free_slot); ! 207: if (g <= size) return; ! 208: //error('d',"grow %d %s %d->%d", this, (t_name)?t_name->string:"?", size, g+1); ! 209: size = mx = g+1; ! 210: ! 211: np = new Pname[mx]; ! 212: for (j=0; j<free_slot; j++) np[j] = entries[j]; ! 213: delete entries; ! 214: entries = np; ! 215: ! 216: delete hashtbl; ! 217: hashsize = mx = (g*3)/2; ! 218: hash = hashtbl = new short[mx]; ! 219: ! 220: for (j=1; j<free_slot; j++) { /* rehash(np[j]); */ ! 221: char * s = np[j]->string; ! 222: register char * p; ! 223: char * q; ! 224: register int i; ! 225: int firsti; ! 226: ! 227: p = s; ! 228: i = 0; ! 229: while (*p) i += (i + *p++); ! 230: if (i<0) i = -i; ! 231: firsti = i = i%mx; ! 232: ! 233: do { /* look for name "s" */ ! 234: if (hash[i] == 0) { ! 235: hash[i] = j; ! 236: goto add_np; ! 237: } ! 238: n = np[hash[i]]; ! 239: if (n == 0) error('i',"hashed lookup"); ! 240: p = n->string; /* strcmp(n->n_string,s) */ ! 241: q = s; ! 242: while (*p && *q) if (*p++ != *q++) goto nxt; ! 243: if (*p == *q) goto found; ! 244: nxt: ! 245: if (mx <= ++i) i = 0; /* wrap around */ ! 246: } while (i != firsti); ! 247: ! 248: error('i',"rehash??"); ! 249: ! 250: found: ! 251: error('i',"rehash failed"); ! 252: ! 253: add_np:; ! 254: } ! 255: } ! 256: ! 257: Pname table::get_mem(int i) ! 258: /* ! 259: return a pointer to the i'th entry, or 0 if it does not exist ! 260: */ ! 261: { ! 262: return (i<=0 || free_slot<=i) ? 0 : entries[i]; ! 263: } ! 264: ! 265: void table_delete(char* s, TOK k, int ll ) ! 266: /* ! 267: deletes local class entry from keyword table ! 268: adjusts pointers if multiple entries ! 269: uses same lookup as table::look and table::insert ! 270: */ ! 271: { ! 272: Ptable t = ktbl; ! 273: register char * p; ! 274: register char * q; ! 275: register int i; ! 276: Pname n; ! 277: int rr; ! 278: ! 279: p = s; ! 280: i = 0; ! 281: while (*p) i += (i + *p++); /* i<<1 ^ *p++ better?*/ ! 282: rr = (0<=i) ? i : -i; ! 283: ! 284: // error ('d', "table_delete: %s ll: %d", s, ll ); ! 285: ! 286: Pname* np = t->entries; ! 287: int mx = t->hashsize; ! 288: short* hash = t->hashtbl; ! 289: int firsti = i = rr%mx; ! 290: ! 291: do { ! 292: if (hash[i] == 0) error('i',"table delete: not found: %s", s ); ! 293: n = np[hash[i]]; ! 294: if (n == 0) error('i',"table delete: hashed lookup"); ! 295: p = n->string; /* strcmp(n->n_string,s) */ ! 296: q = s; ! 297: // error( 'd', "table_delete: %s", p ); ! 298: while (*p && *q) ! 299: if (*p++ != *q++) goto nxt; ! 300: if (*p == *q) goto found; ! 301: nxt: ! 302: if (mx <= ++i) i = 0; /* wrap around */ ! 303: } while (i != firsti); ! 304: ! 305: found: ! 306: for (Pname prev = n; n; prev = n, n=n->n_tbl_list){ ! 307: // error( 'd', "table_delete: found: %s %k lex: %d", n->string, n->n_key, n->lex_level ); ! 308: if (n->n_key == k && n->lex_level == ll ) { ! 309: // error( 'd', "table_delete: prev: %d n: %d n->tbl_list: %d", prev, n, n->n_tbl_list); ! 310: if ( prev == n && n->n_tbl_list == 0 ) ! 311: hash[i] = 0; ! 312: else ! 313: prev->n_tbl_list = n->n_tbl_list; ! 314: return; ! 315: } ! 316: } ! 317: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.