Annotation of researchv10no/cmd/cfront/optcfront/table.c, revision 1.1.1.1

1.1       root        1: /*ident        "@(#)ctrans:src/table.c 1.3" */
                      2: /**************************************************************************
                      3: 
                      4:         C++ source for cfront, the C++ compiler front-end
                      5:         written in the computer science research center of Bell Labs
                      6: 
                      7:         Copyright (c) 1984 AT&T, Inc. All Rights Reserved
                      8:         THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC.
                      9: 
                     10: table.c:
                     11: 
                     12: *****************************************************************************/
                     13: 
                     14: #include "cfront.h"
                     15: #include "size.h"
                     16: 
                     17: #ifdef DBG
                     18: extern long node_id;
                     19: #define DBCHECK() if(node::allocated) error('i',"allocated node (id %d, base%k) on free list! (src: \"%s\", %d",node::id,node::base,__FILE__,__LINE__);
                     20: #else
                     21: #define DBCHECK() /**/
                     22: #endif
                     23: 
                     24: table::table(short sz, Ptable nx, Pname n)
                     25: /*
                     26:        create a symbol table with "size" entries
                     27:        the scope of table is enclosed in the scope of "nx"
                     28: 
                     29:        both the vector of class name pointers and the hash table
                     30:        are initialized containing all zeroes
                     31:        
                     32:        to simplify hashed lookup entries[0] is never used
                     33:        so the size of "entries" must be "size+1" to hold "size" entries
                     34: */
                     35: {
                     36:        DBCHECK();
                     37:        base = TABLE;
                     38:        t_name = n;
                     39:        size = sz = (sz<=0) ? 2 : sz+1;
                     40: //fprintf(stderr,"table::table %d %s %d (%d %d)\n", this, (n)?n->string:"?", sz,(sz*3)/2);
                     41:        entries = new Pname[sz];
                     42:        hashsize = sz = (sz*3)/2;
                     43:        hashtbl = new short[sz];
                     44:        next = nx;
                     45:        free_slot = 1;
                     46:        DBID();
                     47: }
                     48: 
                     49: table::~table()
                     50: {
                     51:        delete entries;
                     52:        delete hashtbl;
                     53: }
                     54: 
                     55: Pname table::look(char* s, TOK k)
                     56: /*
                     57:        look for "s" in table, ignore entries which are not of "k" type
                     58:        look and insert MUST be the same lookup algorithm
                     59: */
                     60: {
                     61:        Ptable t;
                     62:        register char * p;
                     63:        register char * q;
                     64:        register int i;
                     65:        Pname n;
                     66:        int rr;
                     67: 
                     68: //     if (s == 0) error('i',"%d->look(0)",this);
                     69: //     if (this == 0) error('i',"0->look(%s)",s);
                     70: //     if (base != TABLE) error('i',"(%d,%d)->look(%s)",this,base,s);
                     71: 
                     72:        /* use simple hashing with linear search for overflow */
                     73: 
                     74:        p = s;
                     75:        i = 0;
                     76:        while (*p) i += (i + *p++); /* i<<1 ^ *p++ better?*/
                     77:        rr = (0<=i) ? i : -i;
                     78: 
                     79:        for (t=this; t; t=t->next) {    
                     80:                /* in this and all enclosing scopes look for name "s" */
                     81:                Pname* np = t->entries;
                     82:                int mx = t->hashsize;
                     83:                short* hash = t->hashtbl;
                     84:                int firsti = i = rr%mx;
                     85: 
                     86:                do {                    
                     87:                        if (hash[i] == 0) goto not_found;
                     88:                        n = np[hash[i]];
                     89:                        if (n == 0) error('i',"hashed lookup");
                     90:                        p = n->string;          /* strcmp(n->n_string,s) */
                     91:                        q = s;
                     92:                        while (*p && *q)
                     93:                                if (*p++ != *q++) goto nxt;
                     94:                        if (*p == *q) goto found;
                     95:                nxt:
                     96:                        if (mx <= ++i) i = 0;           /* wrap around */
                     97:                } while (i != firsti);
                     98: 
                     99:        found:
                    100:                for (; n; n=n->n_tbl_list){     /* for  all name "s"s look for a key match */
                    101:                        if (n->n_key == k) return n;
                    102:                }
                    103: 
                    104:        not_found:;
                    105:        }
                    106: 
                    107:        return 0;       /* not found && no enclosing scope */
                    108: }
                    109: 
                    110: bit Nold;      /* non-zero if last insert() failed */
                    111: 
                    112: Pname table::insert(Pname nx, TOK k)
                    113: /*
                    114:        the lookup algorithm MUST be the same as look
                    115:        if nx is found return the older entry otherwise a copy of nx;
                    116:        Nold = (nx found) ? 1 : 0;
                    117: */
                    118: {
                    119:        register char * p;
                    120:        register int i;
                    121:        Pname n;
                    122:        Pname* np = entries;
                    123:        Pname* link;
                    124:        int firsti;
                    125:        int mx = hashsize;
                    126:        short* hash = hashtbl;
                    127:        char* s = nx->string;
                    128: 
                    129:        if (s==0) error('i',"%p->insert(0,%k)",this,k);
                    130:        nx->n_key = k;
                    131:        if (nx->n_tbl_list || nx->n_table) error('i',"%n in two tables",nx);
                    132:        /* use simple hashing with linear search for overflow */
                    133: 
                    134:        p = s;
                    135:        i = 0;
                    136:        while (*p) i += (i + *p++);
                    137:        if (i<0) i = -i;
                    138:        firsti = i = i%mx;
                    139: 
                    140:        do {    /* look for name "s" */
                    141:                if (hash[i] == 0) {
                    142:                        hash[i] = free_slot;
                    143:                        goto add_np;
                    144:                }
                    145:                n = np[hash[i]];
                    146:                if (n == 0) error('i',"hashed lookup");
                    147:                if (strcmp(n->string,s) == 0) goto found;
                    148: /*
                    149:                p = n->string;
                    150:                q = s;
                    151:                while (*p && *q) if (*p++ != *q++) goto nxt;
                    152:                if (*p == *q) goto found;
                    153:        nxt:
                    154: */
                    155:                if (mx <= ++i) i = 0;   /* wrap around */
                    156:        } while (i != firsti);
                    157: 
                    158:        error("N table full");
                    159: 
                    160: found: 
                    161: 
                    162: 
                    163:        for(;;) {
                    164:                if ( k!=NESTED && n->n_key==k) { Nold = 1; return n; }
                    165: 
                    166:                if (n->n_tbl_list)
                    167:                        n = n->n_tbl_list;
                    168:                else {
                    169:                        link = &(n->n_tbl_list);
                    170:                        goto re_allocate;
                    171:                }
                    172:        }
                    173: 
                    174: add_np:
                    175:        if (size <= free_slot) {
                    176:                grow(2*size);
                    177:                return insert(nx,k);
                    178:        }
                    179: 
                    180:        link = &(np[free_slot++]);
                    181: 
                    182: re_allocate:
                    183:        {       
                    184:                Pname nw = new name;
                    185:                *nw = *nx;
                    186:                char* ps = new char[strlen(s)+1]; // copy string to safer store
                    187:                strcpy(ps,s);
                    188: //             Nstr++;
                    189:                nw->string = ps;
                    190:                nw->n_table = this;
                    191:                *link = nw;
                    192:                Nold = 0;
                    193: //             Nname++;
                    194:                return nw;
                    195:        }
                    196: }
                    197: 
                    198: void table::grow(int g)
                    199: {
                    200:        short* hash;
                    201:        register int j;
                    202:        int mx; 
                    203:        register Pname* np;
                    204:        Pname n;
                    205: 
                    206:        if (g <= free_slot) error('i',"table.grow(%d,%d)",g,free_slot);
                    207:        if (g <= size) return;
                    208: //error('d',"grow %d %s %d->%d", this, (t_name)?t_name->string:"?", size, g+1);
                    209:        size = mx = g+1;
                    210: 
                    211:        np = new Pname[mx];
                    212:        for (j=0; j<free_slot; j++) np[j] = entries[j];
                    213:        delete entries;
                    214:        entries = np;
                    215: 
                    216:        delete hashtbl;
                    217:        hashsize = mx = (g*3)/2;
                    218:        hash = hashtbl = new short[mx];
                    219: 
                    220:        for (j=1; j<free_slot; j++) {   /* rehash(np[j]); */
                    221:                char * s = np[j]->string;
                    222:                register char * p;
                    223:                char * q;
                    224:                register int i;
                    225:                int firsti;
                    226: 
                    227:                p = s;
                    228:                i = 0;
                    229:                while (*p) i += (i + *p++);
                    230:                if (i<0) i = -i;
                    231:                firsti = i = i%mx;
                    232: 
                    233:                do {    /* look for name "s" */
                    234:                        if (hash[i] == 0) {
                    235:                                hash[i] = j;
                    236:                                goto add_np;
                    237:                        }
                    238:                        n = np[hash[i]];
                    239:                        if (n == 0) error('i',"hashed lookup");
                    240:                        p = n->string;  /* strcmp(n->n_string,s) */
                    241:                        q = s;
                    242:                        while (*p && *q) if (*p++ != *q++) goto nxt;
                    243:                        if (*p == *q) goto found;
                    244:                nxt:
                    245:                        if (mx <= ++i) i = 0;   /* wrap around */
                    246:                } while (i != firsti);
                    247: 
                    248:                error('i',"rehash??");
                    249: 
                    250:        found:
                    251:                error('i',"rehash failed");
                    252: 
                    253:        add_np:;
                    254:        }
                    255: }
                    256: 
                    257: Pname table::get_mem(int i)
                    258: /*
                    259:        return a pointer to the i'th entry, or 0 if it does not exist
                    260: */
                    261: {
                    262:        return (i<=0 || free_slot<=i) ? 0 : entries[i];
                    263: }
                    264: 
                    265: void table_delete(char* s, TOK k, int ll )
                    266: /*
                    267:        deletes local class entry from keyword table
                    268:        adjusts pointers if multiple entries
                    269:        uses same lookup as table::look and table::insert
                    270: */
                    271: {
                    272:        Ptable t = ktbl;
                    273:        register char * p;
                    274:        register char * q;
                    275:        register int i;
                    276:        Pname n;
                    277:        int rr;
                    278: 
                    279:        p = s;
                    280:        i = 0;
                    281:        while (*p) i += (i + *p++); /* i<<1 ^ *p++ better?*/
                    282:        rr = (0<=i) ? i : -i;
                    283: 
                    284: // error ('d', "table_delete: %s ll: %d", s, ll );
                    285: 
                    286:                Pname* np = t->entries;
                    287:                int mx = t->hashsize;
                    288:                short* hash = t->hashtbl;
                    289:                int firsti = i = rr%mx;
                    290: 
                    291:                do {                    
                    292:                        if (hash[i] == 0) error('i',"table delete: not found: %s", s );
                    293:                        n = np[hash[i]];
                    294:                        if (n == 0) error('i',"table delete: hashed lookup");
                    295:                        p = n->string;          /* strcmp(n->n_string,s) */
                    296:                        q = s;
                    297: // error( 'd', "table_delete: %s", p );
                    298:                        while (*p && *q)
                    299:                                if (*p++ != *q++) goto nxt;
                    300:                        if (*p == *q) goto found;
                    301:                nxt:
                    302:                        if (mx <= ++i) i = 0;           /* wrap around */
                    303:                } while (i != firsti);
                    304: 
                    305:        found:
                    306:                for (Pname prev = n; n; prev = n, n=n->n_tbl_list){     
                    307: // error( 'd', "table_delete: found: %s %k lex: %d", n->string, n->n_key, n->lex_level );
                    308:                        if (n->n_key == k && n->lex_level == ll ) {
                    309: // error( 'd', "table_delete: prev: %d n: %d n->tbl_list: %d", prev, n, n->n_tbl_list);
                    310:                                if ( prev == n && n->n_tbl_list == 0 )
                    311:                                        hash[i] = 0;
                    312:                                else
                    313:                                        prev->n_tbl_list = n->n_tbl_list;
                    314:                                return;
                    315:                        }
                    316:                }
                    317: }

unix.superglobalmegacorp.com

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