|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.