Annotation of researchv10no/cmd/cfront/ocfront/table.c, revision 1.1

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

unix.superglobalmegacorp.com

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