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