Annotation of researchv10no/cmd/cfront/xptcfront/table.c, revision 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.