Annotation of 43BSD/contrib/icon/tran/sym.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.