Annotation of 43BSD/contrib/icon/link/lsym.c, revision 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.