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

Defined functions

alcfhead defined in line 351; used 2 times
alcfrec defined in line 372; used 5 times
alcglob defined in line 328; used 2 times
alcident defined in line 108; used 3 times
flocate defined in line 314; used 4 times
glocate defined in line 300; used 10 times
instalid defined in line 20; used 2 times
lexeq defined in line 94; used 1 times
  • in line 72
locinit defined in line 127; used 1 times
putconst defined in line 218; used 4 times
putfield defined in line 262; used 1 times
putglob defined in line 195; used 7 times
putident defined in line 45; used 6 times
putloc defined in line 139; used 1 times

Defined variables

argoff defined in line 8; used 4 times
dynoff defined in line 7; used 7 times
nconst defined in line 13; used 6 times
nfields defined in line 14; used 2 times
nlocal defined in line 12; used 9 times
static1 defined in line 9; used 4 times
statics defined in line 10; used 9 times
Last modified: 1984-11-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1714
Valid CSS Valid XHTML 1.0 Strict