Annotation of 43BSD/contrib/icon/link/lsym.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Routines for symbol table manipulation.
                      3:  */
                      4: 
                      5: #include "ilink.h"
                      6: 
                      7: int dynoff;                    /* stack offset counter for locals */
                      8: int argoff;                    /* stack offset counter for arguments */
                      9: int static1;                   /* first static in procedure */
                     10: int statics = 0;               /* static variable counter */
                     11: 
                     12: int nlocal;                    /* number of locals in local table */
                     13: int nconst;                    /* number of constants in constant table */
                     14: int nfields = 0;               /* number of fields in field table */
                     15: 
                     16: /*
                     17:  * instalid - copy the string s to the start of the string free space
                     18:  *  and call putident with the length of the string.
                     19:  */
                     20: char *instalid(s)
                     21: char *s;
                     22:    {
                     23:    register int l;
                     24:    register char *p1, *p2;
                     25:    extern char *putident();
                     26: 
                     27:    p1 = sfree;
                     28:    p2 = s;
                     29:    l = 1;
                     30:    while (*p1++ = *p2++)
                     31:       l++;
                     32:    return (putident(l));
                     33:    }
                     34: 
                     35: /*
                     36:  * putident - install the identifier named by the string starting at sfree
                     37:  *  and extending for len bytes.  The installation entails making an
                     38:  *  entry in the identifier hash table and then making an identifier
                     39:  *  table entry for it with alcident.  A side effect of installation
                     40:  *  is the incrementing of sfree by the length of the string, thus
                     41:  *  "saving" it.
                     42:  *
                     43:  * Nothing is changed if the identifier has already been installed.
                     44:  */
                     45: char *putident(len)
                     46: int len;
                     47:    {
                     48:    register int hash;
                     49:    register char *s;
                     50:    register struct ientry *ip;
                     51:    int l;
                     52:    extern struct ientry *alcident();
                     53: 
                     54:    /*
                     55:     * Compute hash value by adding bytes and masking result with imask.
                     56:     *  (Recall that imask is ihsize-1.)
                     57:     */
                     58:    s = sfree;
                     59:    hash = 0;
                     60:    l = len;
                     61:    while (l--)
                     62:       hash += *s++;
                     63:    l = len;
                     64:    s = sfree;
                     65:    hash &= imask;
                     66:    /*
                     67:     * If the identifier hasn't been installed, install it.
                     68:     */
                     69:    if ((ip = ihash[hash]) != NULL) {    /* collision */
                     70:       for (;;) { /* work down i_blink chain until id is found or the
                     71:                      end of the chain is reached */
                     72:          if (l == ip->i_length && lexeq(l, s, ip->i_name))
                     73:             return (ip->i_name); /* id is already installed, return it */
                     74:          if (ip->i_blink == NULL) { /* end of chain */
                     75:             ip->i_blink = alcident(NULL, s, l);
                     76:             sfree += l;
                     77:             return (s);
                     78:             }
                     79:          ip = ip->i_blink;
                     80:          }
                     81:       }
                     82:    /*
                     83:     * Hashed to an empty slot.
                     84:     */
                     85:    ihash[hash] = alcident(NULL, s, l);
                     86:    sfree += l;
                     87:    return (s);
                     88:    }
                     89: 
                     90: /*
                     91:  * lexeq - compare two strings of given length.  Returns non-zero if
                     92:  *  equal, zero if not equal.
                     93:  */
                     94: lexeq(l, s1, s2)
                     95: register int l;
                     96: register char *s1, *s2;
                     97:    {
                     98:    while (l--)
                     99:       if (*s1++ != *s2++)
                    100:          return (0);
                    101:    return (1);
                    102:    }
                    103: 
                    104: /*
                    105:  * alcident - get the next free identifier table entry, and fill it in with
                    106:  *  the specified values.
                    107:  */
                    108: struct ientry *alcident(blink, nam, len)
                    109: struct ientry *blink;
                    110: char *nam;
                    111: int len;
                    112:    {
                    113:    register struct ientry *ip;
                    114: 
                    115:    if (ifree >= &itable[isize])
                    116:       syserr("out of identifier table space");
                    117:    ip = ifree++;
                    118:    ip->i_blink = blink;
                    119:    ip->i_name = nam;
                    120:    ip->i_length = len;
                    121:    return (ip);
                    122:    }
                    123: 
                    124: /*
                    125:  * locinit -  clear local symbol table.
                    126:  */
                    127: locinit()
                    128:    {
                    129:    dynoff = 0;
                    130:    argoff = 0;
                    131:    nlocal = -1;
                    132:    nconst = -1;
                    133:    static1 = statics;
                    134:    }
                    135: 
                    136: /*
                    137:  * putloc - make a local symbol table entry.
                    138:  */
                    139: struct lentry *putloc(n, id, flags, imperror, procname)
                    140: int n;
                    141: char *id;
                    142: register int flags;
                    143: int imperror;
                    144: char *procname;
                    145:    {
                    146:    register struct lentry *lp;
                    147:    register union {
                    148:       struct gentry *gp;
                    149:       int bn;
                    150:       } p;
                    151:    extern struct gentry *glocate(), *putglob();
                    152: 
                    153:    if (n >= lsize)
                    154:       syserr("out of local symbol table space.");
                    155:    if (n > nlocal)
                    156:       nlocal = n;
                    157:    lp = &ltable[n];
                    158:    lp->l_name = id;
                    159:    lp->l_flag = flags;
                    160:    if (flags == 0) {                           /* undeclared */
                    161:       if ((p.gp = glocate(id)) != NULL) {      /* check global */
                    162:          lp->l_flag = F_GLOBAL;
                    163:          lp->l_val.global = p.gp;
                    164:          }
                    165:       else if ((p.bn = blocate(id)) != 0) {    /* check builtin */
                    166:          lp->l_flag = F_BUILTIN;
                    167:          lp->l_val.global = putglob(id, F_BUILTIN | F_PROC, -1, p.bn);
                    168:          }
                    169:       else {                                   /* implicit local */
                    170:          if (imperror)
                    171:             warn(id, "undeclared identifier, procedure ", procname);
                    172:          lp->l_flag = F_DYNAMIC;
                    173:          lp->l_val.offset = ++dynoff;
                    174:          }
                    175:       }
                    176:    else if (flags & F_GLOBAL) {                        /* global variable */
                    177:       if ((p.gp = glocate(id)) == NULL)
                    178:          syserr("putloc: global not in global table");
                    179:       lp->l_val.global = p.gp;
                    180:       }
                    181:    else if (flags & F_ARGUMENT)                        /* procedure argument */
                    182:       lp->l_val.offset = ++argoff;
                    183:    else if (flags & F_DYNAMIC)                 /* local dynamic */
                    184:       lp->l_val.offset = ++dynoff;
                    185:    else if (flags & F_STATIC)                  /* local static */
                    186:       lp->l_val.staticid = ++statics;
                    187:    else
                    188:       syserr("putloc: unknown flags");
                    189:    return (lp);
                    190:    }
                    191: 
                    192: /*
                    193:  * putglob - make a global symbol table entry.
                    194:  */
                    195: struct gentry *putglob(id, flags, nargs, procid)
                    196: char *id;
                    197: int flags;
                    198: int nargs;
                    199: int procid;
                    200:    {
                    201:    register struct gentry *p;
                    202:    extern struct gentry *glocate(), *alcglob();
                    203: 
                    204:    if ((p = glocate(id)) == NULL) {    /* add to head of hash chain */
                    205:       p = ghash[ghasher(id)];
                    206:       ghash[ghasher(id)] = alcglob(p, id, flags, nargs, procid);
                    207:       return (ghash[ghasher(id)]);
                    208:       }
                    209:    p->g_flag |= flags;
                    210:    p->g_nargs = nargs;
                    211:    p->g_procid = procid;
                    212:    return (p);
                    213:    }
                    214: 
                    215: /*
                    216:  * putconst - make a constant symbol table entry.
                    217:  */
                    218: struct centry *putconst(n, flags, len, pc, val)
                    219: int n;
                    220: int flags, len;
                    221: int pc;
                    222: union {
                    223:    long  ival;
                    224:    double rval;
                    225:    char *sval;
                    226:    } val;
                    227:    {
                    228:    register struct centry *p;
                    229: 
                    230:    if (n >= csize)
                    231:       syserr("out of constant table space");
                    232:    if (nconst < n)
                    233:       nconst = n;
                    234:    p = &ctable[n];
                    235:    p->c_flag = flags;
                    236:    p->c_pc = pc;
                    237:    if (flags & F_INTLIT) {
                    238:       p->c_val.ival = val.ival;
                    239: #ifdef LONGS
                    240:       if (val.ival < (long)(short)MINSHORT | val.ival > (long)(short)MAXSHORT)
                    241:          p->c_flag |= F_LONGLIT;
                    242: #endif LONGS
                    243:       }
                    244:    else if (flags & F_STRLIT) {
                    245:       p->c_val.sval = val.sval;
                    246:       p->c_length = len;
                    247:       }
                    248:    else if (flags & F_CSETLIT) {
                    249:       p->c_val.sval = val.sval;
                    250:       p->c_length = len;
                    251:       }
                    252:    else        if (flags & F_REALLIT)
                    253:       p->c_val.rval = val.rval;
                    254:    else
                    255:       fprintf(stderr, "putconst: bad flags: %06o %011o\n", flags, val.ival);
                    256:    return (p);
                    257:    }
                    258: 
                    259: /*
                    260:  * putfield - make a record/field table entry.
                    261:  */
                    262: putfield(fname, rnum, fnum)
                    263: char *fname;
                    264: int rnum, fnum;
                    265:    {
                    266:    register struct fentry *fp;
                    267:    register struct rentry *rp, *rp2;
                    268:    int hash;
                    269:    extern struct fentry *flocate(), *alcfhead();
                    270:    extern struct rentry *alcfrec();
                    271: 
                    272:    fp = flocate(fname);
                    273:    if (fp == NULL) {           /* create a field entry */
                    274:       nfields++;
                    275:       hash = fhasher(fname);
                    276:       fp = fhash[hash];
                    277:       fhash[hash] = alcfhead(fp, fname, nfields, alcfrec(NULL, rnum, fnum));
                    278:       return;
                    279:       }
                    280:    rp = fp->f_rlist;           /* found field entry, look for */
                    281:    if (rp->r_recid > rnum) {   /*   spot in record list */
                    282:       fp->f_rlist = alcfrec(rp, rnum, fnum);
                    283:       return;
                    284:       }
                    285:    while (rp->r_recid < rnum) {        /* keep record list ascending */
                    286:       if (rp->r_link == NULL) {
                    287:          rp->r_link = alcfrec(NULL, rnum, fnum);
                    288:          return;
                    289:          }
                    290:       rp2 = rp;
                    291:       rp = rp->r_link;
                    292:       }
                    293:    rp2->r_link = alcfrec(rp, rnum, fnum);
                    294:    }
                    295: 
                    296: /*
                    297:  * glocate - lookup identifier in global symbol table, return NULL
                    298:  *  if not present.
                    299:  */
                    300: struct gentry *glocate(id)
                    301: char *id;
                    302:    {
                    303:    register struct gentry *p;
                    304: 
                    305:    p = ghash[ghasher(id)];
                    306:    while (p != NULL && p->g_name != id)
                    307:       p = p->g_blink;
                    308:    return (p);
                    309:    }
                    310: 
                    311: /*
                    312:  * flocate - lookup identifier in field table.
                    313:  */
                    314: struct fentry *flocate(id)
                    315: char *id;
                    316:    {
                    317:    register struct fentry *p;
                    318: 
                    319:    p = fhash[fhasher(id)];
                    320:    while (p != NULL && p->f_name != id)
                    321:       p = p->f_blink;
                    322:    return (p);
                    323:    }
                    324: 
                    325: /*
                    326:  * alcglob - create a new global symbol table entry.
                    327:  */
                    328: struct gentry *alcglob(blink, name, flag, nargs, procid)
                    329: struct gentry *blink;
                    330: char *name;
                    331: int flag;
                    332: int nargs;
                    333: int procid;
                    334:    {
                    335:    register struct gentry *gp;
                    336: 
                    337:    if (gfree >= &gtable[gsize])
                    338:       syserr("out of global symbol table space");
                    339:    gp = gfree++;
                    340:    gp->g_blink = blink;
                    341:    gp->g_name = name;
                    342:    gp->g_flag = flag;
                    343:    gp->g_nargs = nargs;
                    344:    gp->g_procid = procid;
                    345:    return (gp);
                    346:    }
                    347: 
                    348: /*
                    349:  * alcfhead - allocate a field table header.
                    350:  */
                    351: struct fentry *alcfhead(blink, name, fid, rlist)
                    352: struct fentry *blink;
                    353: char *name;
                    354: int fid;
                    355: struct rentry *rlist;
                    356:    {
                    357:    register struct fentry *fp;
                    358: 
                    359:    if (ffree >= &ftable[fsize])
                    360:       syserr("out of field table space");
                    361:    fp = ffree++;
                    362:    fp->f_blink = blink;
                    363:    fp->f_name = name;
                    364:    fp->f_fid = fid;
                    365:    fp->f_rlist = rlist;
                    366:    return (fp);
                    367:    }
                    368: 
                    369: /*
                    370:  * alcfrec - allocate a field table record list element.
                    371:  */
                    372: struct rentry *alcfrec(link, rnum, fnum)
                    373: struct rentry *link;
                    374: int rnum, fnum;
                    375:    {
                    376:    register struct rentry *rp;
                    377: 
                    378:    if (rfree >= &rtable[rsize])
                    379:       syserr("out of field table space for record lists");
                    380:    rp = rfree++;
                    381:    rp->r_link = link;
                    382:    rp->r_recid = rnum;
                    383:    rp->r_fnum = fnum;
                    384:    return (rp);
                    385:    }

unix.superglobalmegacorp.com

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