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 >= &ltable[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 >= &gtable[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:    }

Defined functions

alcglob defined in line 414; used 2 times
alcident defined in line 109; used 3 times
alclit defined in line 439; used 2 times
alcloc defined in line 390; used 2 times
cdump defined in line 373; never used
clocate defined in line 304; used 2 times
cout defined in line 479; used 1 times
gdump defined in line 355; never used
glocate defined in line 288; used 5 times
gout defined in line 526; used 1 times
instalid defined in line 19; never used
install defined in line 160; used 4 times
klocate defined in line 321; used 1 times
ldump defined in line 337; never used
llocate defined in line 273; used 4 times
loc_init defined in line 127; used 2 times
lout defined in line 463; used 1 times
putglob defined in line 234; used 2 times
putident defined in line 47; used 10 times
putlit defined in line 253; used 4 times
putloc defined in line 214; used 2 times
rout defined in line 507; used 1 times
streq defined in line 96; used 1 times
  • in line 74

Defined variables

alccflg defined in line 13; used 11 times
alcgflg defined in line 12; used 5 times
alclflg defined in line 11; used 11 times
Last modified: 1984-11-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1575
Valid CSS Valid XHTML 1.0 Strict