1: /* 2: * Routines for symbol table management. 3: */ 4: 5: #include "itran.h" 6: #include "token.h" 7: #include "sym.h" 8: #include "char.h" 9: #include "lfile.h" 10: 11: int alclflg = 0; /* flag (counter) for local table overflow */ 12: int alcgflg = 0; /* flag (counter) for global table overflow */ 13: int alccflg = 0; /* flag (counter) for constant table overflow */ 14: 15: /* 16: * instalid - copy the string s to the start of the string free space 17: * and call putident with the length of the string. 18: */ 19: char *instalid(s) 20: char *s; 21: { 22: register int l; 23: register char *p1, *p2; 24: extern char *putident(); 25: 26: p1 = sfree; 27: p2 = s; 28: l = 1; 29: while (*p1++ = *p2++) { 30: if (p1 >= send) 31: syserr("out of string space"); 32: l++; 33: } 34: return (putident(l)); 35: } 36: 37: /* 38: * putident - install the identifier named by the string starting at sfree 39: * and extending for len bytes. The installation entails making an 40: * entry in the identifier hash table and then making an identifier 41: * table entry for it with alcident. A side effect of installation 42: * is the incrementing of sfree by the length of the string, thus 43: * "saving" it. 44: * 45: * Nothing is changed if the identifier has already been installed. 46: */ 47: char *putident(len) 48: int len; 49: { 50: register int hash; 51: register char *s; 52: register struct ientry *ip; 53: int l; 54: extern struct ientry *alcident(); 55: 56: /* 57: * Compute hash value by adding bytes and masking result with imask. 58: * (Recall that imask is ihsize-1.) 59: */ 60: s = sfree; 61: hash = 0; 62: l = len; 63: while (l--) 64: hash += *s++ & 0377; 65: s = sfree; 66: l = len; 67: hash &= imask; 68: /* 69: * If the identifier hasn't been installed, install it. 70: */ 71: if ((ip = ihash[hash]) != NULL) { /* collision */ 72: for (;;) { /* work down i_blink chain until id is found or the 73: end of the chain is reached */ 74: if (l == ip->i_length && streq(l, s, ip->i_name)) 75: return (ip->i_name); /* id is already installed */ 76: if (ip->i_blink == NULL) { /* end of chain */ 77: ip->i_blink = alcident(NULL, s, l); 78: sfree += l; 79: return (s); 80: } 81: ip = ip->i_blink; 82: } 83: } 84: /* 85: * Hashed to an empty slot. 86: */ 87: ihash[hash] = alcident(NULL, s, l); 88: sfree += l; 89: return (s); 90: } 91: 92: /* 93: * streq - compare s1 with s2 for len bytes, and return 1 for equal, 94: * 0 for not equal. 95: */ 96: streq(len, s1, s2) 97: register int len; 98: register char *s1, *s2; 99: { 100: while (len--) 101: if (*s1++ != *s2++) 102: return (0); 103: return (1); 104: } 105: /* 106: * alcident - get the next free identifier table entry, and fill it in with 107: * the specified values. 108: */ 109: struct ientry *alcident(blink, nam, len) 110: struct ientry *blink; 111: char *nam; 112: int len; 113: { 114: register struct ientry *ip; 115: 116: ip = ifree++; 117: ip->i_blink = blink; 118: ip->i_name = nam; 119: ip->i_length = len; 120: return (ip); 121: } 122: 123: /* 124: * loc_init - clear the local symbol table. 125: */ 126: 127: loc_init() 128: { 129: register *p; 130: static int maxlfree = 0; 131: static int maxcfree = 0; 132: /* clear local table */ 133: maxlfree = (maxlfree > lfree-ltable) ? maxlfree : lfree-ltable; 134: if (alclflg) { 135: fprintf(stderr, " %d more entries needed in local symbol table\n", 136: alclflg); 137: alclflg = 0; 138: } 139: for (p = (int *) lhash; p < (int *) &lhash[lhsize]; p++) 140: *p = NULL; 141: lfree = ltable; 142: /* clear constant table */ 143: maxcfree = (maxcfree > ctfree-ctable) ? maxcfree : ctfree-ctable; 144: if (alccflg) { 145: fprintf(stderr, " %d more entries needed in literal symbol table\n", 146: alccflg); 147: alccflg = 0; 148: } 149: for (p = (int *) chash; p < (int *) &chash[chsize]; p++) 150: *p = NULL; 151: ctfree = ctable; 152: } 153: 154: /* 155: * install - put an identifier into the global or local symbol table. 156: * The basic idea here is to look in the right table and install 157: * the identifier if it isn't already there. Some semantic checks 158: * are performed. 159: */ 160: install(name, flag, argcnt) 161: char *name; 162: int flag, argcnt; 163: { 164: register union { 165: struct gentry *gp; 166: struct lentry *lp; 167: } p; 168: extern struct gentry *glocate(); 169: extern struct lentry *llocate(); 170: 171: switch (flag) { 172: case F_GLOBAL: /* a variable in a global declaration */ 173: if ((p.gp = glocate(name)) == NULL) 174: putglob(name, flag, argcnt); 175: else 176: p.gp->g_flag |= flag; 177: break; 178: 179: case F_PROC|F_GLOBAL: /* procedure declaration */ 180: case F_RECORD|F_GLOBAL: /* record declaration */ 181: case F_BUILTIN|F_GLOBAL: /* external declaration */ 182: if ((p.gp = glocate(name)) == NULL) 183: putglob(name, flag, argcnt); 184: else if ((p.gp->g_flag & (~F_GLOBAL)) == 0) { /* superfluous global 185: declaration for 186: record or proc */ 187: p.gp->g_flag |= flag; 188: p.gp->g_nargs = argcnt; 189: } 190: else /* the user can't make up his mind */ 191: err("inconsistent redeclaration", name); 192: break; 193: 194: case F_STATIC: /* static declaration */ 195: case F_DYNAMIC: /* local declaration (possibly implicit?) */ 196: case F_ARGUMENT: /* formal parameter */ 197: if ((p.lp = llocate(name)) == NULL) 198: putloc(name,flag); 199: else if (p.lp->l_flag == flag) /* previously declared as same type */ 200: warn("redeclared identifier", name); 201: else /* previously declared as different type */ 202: err("inconsistent redeclaration", name); 203: break; 204: 205: default: 206: syserr("install: unrecognized symbol table flag."); 207: } 208: } 209: 210: /* 211: * putloc - make a local symbol table entry and return the index 212: * of the entry in lhash. alcloc does the work if there is a collision. 213: */ 214: int putloc(id,id_type) 215: char *id; 216: int id_type; 217: { 218: register struct lentry *ptr; 219: extern struct lentry *llocate(), *alcloc(); 220: 221: if ((ptr = llocate(id)) == NULL) { /* add to head of hash chain */ 222: ptr = lhash[lhasher(id)]; 223: lhash[lhasher(id)] = alcloc(ptr, id, id_type); 224: return (lhash[lhasher(id)] - ltable); 225: } 226: return (ptr - ltable); 227: } 228: 229: /* 230: * putglob makes a global symbol table entry and returns the index 231: * of the entry in ghash. alcglob does the work if there is a collision. 232: */ 233: 234: int putglob(id, id_type, n_args) 235: char *id; 236: int id_type, n_args; 237: { 238: register struct gentry *ptr; 239: extern struct gentry *glocate(), *alcglob(); 240: 241: if ((ptr = glocate(id)) == NULL) { /* add to head of hash chain */ 242: ptr = ghash[ghasher(id)]; 243: ghash[ghasher(id)] = alcglob(ptr, id, id_type, n_args); 244: return (ghash[ghasher(id)] - gtable); 245: } 246: return (ptr - gtable); 247: } 248: 249: /* 250: * putlit makes a constant symbol table entry and returns the index 251: * of the entry in chash. alclit does the work if there is a collision. 252: */ 253: int putlit(id, idtype, len) 254: char *id; 255: int len, idtype; 256: { 257: register struct centry *ptr; 258: extern struct centry *clocate(), *alclit(); 259: 260: if ((ptr = clocate(id,idtype)) == NULL) { /* add to head of hash chain */ 261: ptr = chash[chasher(id)]; 262: chash[chasher(id)] = alclit(ptr, id, len, idtype); 263: return (chash[chasher(id)] - ctable); 264: } 265: return (ptr - ctable); 266: } 267: 268: /* 269: * llocate looks up id in local symbol table and returns pointer to 270: * to it if found or NULL if not present. 271: */ 272: 273: struct lentry *llocate(id) 274: char *id; 275: { 276: register struct lentry *ptr; 277: 278: ptr = lhash[lhasher(id)]; 279: while (ptr != NULL && ptr->l_name != id) 280: ptr = ptr->l_blink; 281: return (ptr); 282: } 283: 284: /* 285: * glocate looks up id in global symbol table and returns pointer to 286: * to it if found or NULL if not present. 287: */ 288: struct gentry *glocate(id) 289: char *id; 290: { 291: register struct gentry *ptr; 292: 293: ptr = ghash[ghasher(id)]; 294: while (ptr != NULL && ptr->g_name != id) { 295: ptr = ptr->g_blink; 296: } 297: return (ptr); 298: } 299: 300: /* 301: * clocate looks up id in constant symbol table and returns pointer to 302: * to it if found or NULL if not present. 303: */ 304: struct centry *clocate(id,flag) 305: char *id; 306: int flag; 307: { 308: register struct centry *ptr; 309: 310: ptr = chash[chasher(id)]; 311: while (ptr != NULL && (ptr->c_name != id || ptr->c_flag != flag)) 312: ptr = ptr->c_blink; 313: 314: return (ptr); 315: } 316: 317: /* 318: * klocate looks up keyword named by id in keyword table and returns 319: * its number (keyid). 320: */ 321: klocate(id) 322: register int id; 323: { 324: register struct keyent *kp; 325: 326: for (kp = keytab; kp->keyid >= 0; kp++) 327: if (strcmp(kp->keyname,id) == 0) 328: return (kp->keyid); 329: 330: return (NULL); 331: } 332: 333: /* 334: * ldump displays local symbol table to stdout. 335: */ 336: 337: ldump() 338: { 339: register int i; 340: register struct lentry *lptr; 341: 342: printf("Dump of local symbol table (%d entries)\n",lfree-ltable); 343: printf(" loc blink id (name) flags\n"); 344: for (i = 0; i < lhsize; i++) 345: for (lptr = lhash[i]; lptr != NULL; lptr = lptr->l_blink) 346: printf("%5d %5d %5d %20s %7o\n", lptr-ltable, 347: lptr->l_blink, lptr->l_name, lptr->l_name, lptr->l_flag); 348: 349: } 350: 351: /* 352: * gdump displays global symbol table to stdout. 353: */ 354: 355: gdump() 356: { 357: register int i; 358: register struct gentry *gptr; 359: 360: printf("Dump of global symbol table (%d entries)\n",gfree-gtable); 361: printf(" loc blink id (name) flags nargs\n"); 362: for (i = 0; i < ghsize; i++) 363: for (gptr = ghash[i]; gptr != NULL; gptr = gptr->g_blink) 364: printf("%5d %5d %5d %20s %7o %8d\n", gptr-gtable, 365: gptr->g_blink, gptr->g_name, gptr->g_name, 366: gptr->g_flag, gptr->g_nargs); 367: } 368: 369: /* 370: * cdump displays constant symbol table to stdout. 371: */ 372: 373: cdump() 374: { 375: register int i; 376: register struct centry *cptr; 377: 378: printf("Dump of constant symbol table (%d entries)\n",ctfree-ctable); 379: printf(" loc blink id (name) flags\n"); 380: for (i = 0; i < chsize; i++) 381: for (cptr = chash[i]; cptr != NULL; cptr = cptr->c_blink) 382: printf("%5d %5d %5d %20s %7o\n", cptr-ctable, 383: cptr->c_blink, cptr->c_name, cptr->c_name, cptr->c_flag); 384: } 385: 386: /* 387: * alcloc allocates a local symbol table entry, fills in fields with 388: * specified values and returns offset of new entry. 389: */ 390: struct lentry *alcloc(blink, name, flag) 391: struct lentry *blink; 392: char *name; 393: int flag; 394: { 395: register struct lentry *lp; 396: 397: if (lfree >= <able[lsize]) { /* need more room */ 398: if (alclflg == 0) 399: syserr("out of local symbol table space"); 400: alclflg++; 401: return (NULL); 402: } 403: lp = lfree++; 404: lp->l_blink = blink; 405: lp->l_name = name; 406: lp->l_flag = flag; 407: return (lp); 408: } 409: 410: /* 411: * alcglob allocates a global symbol table entry, fills in fields with 412: * specified values and returns offset of new entry. 413: */ 414: struct gentry *alcglob(blink, name, flag, nargs) 415: struct gentry *blink; 416: char *name; 417: int flag, nargs; 418: { 419: register struct gentry *gp; 420: 421: if (gfree >= >able[gsize]) { /* need more room */ 422: if (alcgflg == 0) 423: syserr("out of global symbol table space"); 424: alcgflg++; 425: return (NULL); 426: } 427: gp = gfree++; 428: gp->g_blink = blink; 429: gp->g_name = name; 430: gp->g_flag = flag; 431: gp->g_nargs = nargs; 432: return (gp); 433: } 434: 435: /* 436: * alclit allocates a constant symbol table entry, fills in fields with 437: * specified values and returns offset of new entry. 438: */ 439: struct centry *alclit(blink, name, len, flag) 440: struct centry *blink; 441: char *name; 442: int len, flag; 443: { 444: register struct centry *cp; 445: 446: if (ctfree >= &ctable[csize]) { /* need more room */ 447: if (alccflg == 0) 448: syserr("out of constant table space"); 449: alccflg++; 450: return (NULL); 451: } 452: cp = ctfree++; 453: cp->c_blink = blink; 454: cp->c_name = name; 455: cp->c_length = len; 456: cp->c_flag = flag; 457: return (cp); 458: } 459: 460: /* 461: * lout dumps local symbol table to fd, which is a .u1 file. 462: */ 463: lout(fd) 464: FILE *fd; 465: { 466: register int i; 467: register struct lentry *lp; 468: 469: i = 0; 470: for (lp = ltable; lp < lfree; lp++) 471: fprintf(fd, "\tlocal\t%d,%06o,%s\n", 472: i++, lp->l_flag, lp->l_name); 473: } 474: 475: 476: /* 477: * cout dumps constant symbol table to fd, which is a .u1 file. 478: */ 479: cout(fd) 480: FILE *fd; 481: { 482: register int l; 483: register char *c; 484: register struct centry *cp; 485: int i; 486: 487: i = 0; 488: for (cp = ctable; cp < ctfree; cp++) { 489: fprintf(fd, "\tcon\t%d,%06o", i++, cp->c_flag); 490: if (cp->c_flag & (F_INTLIT|F_REALLIT)) 491: fprintf(fd, ",%s\n", cp->c_name); 492: else { 493: c = cp->c_name; 494: l = cp->c_length - 1; 495: fprintf(fd, ",%d", l); 496: while (l--) 497: fprintf(fd, ",%03o", *c++ & 0377); 498: putc('\n', fd); 499: } 500: } 501: } 502: 503: 504: /* 505: * rout dumps a record declaration for name to file fd, which is a .u2 file. 506: */ 507: rout(fd,name) 508: FILE *fd; 509: char *name; 510: { 511: register int i; 512: register struct lentry *lp; 513: 514: fprintf(fd, "record\t%s,%d\n", name, lfree-ltable); 515: i = 0; 516: for (lp = ltable; lp < lfree; lp++) 517: fprintf(fd, "\t%d,%s\n", i++, lp->l_name); 518: } 519: 520: 521: /* 522: * gout writes various items to fd, which is a .u2 file. These items 523: * include: implicit status, tracing activation, link directives, 524: * and the global table. 525: */ 526: gout(fd) 527: FILE *fd; 528: { 529: register int i; 530: register char *name; 531: register struct gentry *gp; 532: struct lfile *lfl; 533: 534: if (implicit == LOCAL) 535: name = "local"; 536: else 537: name = "error"; 538: fprintf(fd, "impl\t%s\n", name); 539: if (trace) 540: fprintf(fd, "trace\n"); 541: 542: lfl = lfiles; 543: while (lfl) { 544: fprintf(fd,"link\t%s.u1\n",lfl->lf_name); 545: lfl = lfl->lf_link; 546: } 547: lfiles = 0; 548: fprintf(fd, "global\t%d\n", gfree-gtable); 549: i = 0; 550: for (gp = gtable; gp < gfree; gp++) 551: fprintf(fd, "\t%d,%06o,%s,%d\n", i++, gp->g_flag, 552: gp->g_name, gp->g_nargs); 553: }