Annotation of researchv10no/cmd/twig/sym.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Symbol manipulation routines
        !             3:  */
        !             4: #include "common.h"
        !             5: #include "code.h"
        !             6: #include "sym.h"
        !             7: #include "machine.h"
        !             8: #include "y.tab.h"
        !             9: #include "mem.h"
        !            10: 
        !            11: #define SAFE   1       /* generates code to do redundant checks */
        !            12: #define MAXSYMS        100
        !            13: #define MAX_UNIQUE 255
        !            14: 
        !            15: static void AppendToList();
        !            16: typedef
        !            17:        struct SymbolList {
        !            18:                        SymbolEntry *first, *last;
        !            19:                        int count;
        !            20:                }
        !            21:        SymbolList;
        !            22: 
        !            23: /*
        !            24:  * The range of the unique numbers assigned to each type of
        !            25:  * symbol is [min,max)
        !            26:  */
        !            27: struct ranges {
        !            28:        int min,max;
        !            29:        int limit;
        !            30: } uniques[] = {
        !            31:        {0, 0, MAX_UNIQUE},     /* A_UNDEFINED -- not used */
        !            32:        {0, 0, MAX_NODE_VALUE}, /* A_NODE */
        !            33:        {0, 0, MAX_UNIQUE},     /* A_LABEL */
        !            34:        {0, 0, MAX_UNIQUE},     /* A_COST */
        !            35:        {0, 0, MAX_UNIQUE},     /* A_ACTION */
        !            36: };
        !            37: 
        !            38: int treeIndex = 0;
        !            39: 
        !            40: static SymbolList lists[] = {
        !            41:        { NULL, NULL, 0},       /* A_UNDEFINED -- never used */
        !            42:        { NULL, NULL, 0}, /* A_NODE */
        !            43:        { NULL, NULL, 0}, /* A_LABEL */
        !            44:        { NULL, NULL, 0}, /* A_COST */
        !            45:        { NULL, NULL, 0}, /* A_ACTION */
        !            46:        { NULL, NULL, 0}, /* A_CONST */
        !            47: };
        !            48: 
        !            49: struct _mem sym_mem, lab_mem, tree_mem;
        !            50: SymbolEntry *hash_table[HASHSIZE];
        !            51: SymbolEntry *startSymbol;
        !            52: 
        !            53: static int
        !            54: RawHash(s)
        !            55:        register char *s;
        !            56: {
        !            57:        register int sum = 0;
        !            58:        register int i = 0;
        !            59:        while(*s)
        !            60:                sum += (++i)*(0377&*s++);
        !            61:        return(sum);
        !            62: }
        !            63: 
        !            64: 
        !            65: /*
        !            66:  * Allocate a new symbol_entry structure for the given structure and
        !            67:  * return it.  There is no check of whether the symbol is already defined or
        !            68:  * not.  The caller is expected to fill in the uninitialized fields.
        !            69:  */
        !            70: SymbolEntry *
        !            71: SymbolAllocate(s)
        !            72:        char *s;
        !            73: {
        !            74:        SymbolEntry *sp;
        !            75:        sp = (SymbolEntry *) mem_get(&sym_mem);
        !            76:        assert(sp!=NULL);
        !            77: 
        !            78: #ifdef SAFE
        !            79:        assert (SymbolLookup(s) == NULL);
        !            80: #endif
        !            81: 
        !            82:        sp->name = malloc(strlen(s)+1);
        !            83:        assert(sp->name!=NULL);
        !            84:        strcpy (sp->name, s);
        !            85:        sp->hash = RawHash(s);
        !            86:        sp->next = NULL;
        !            87:        sp->attr = A_UNDEFINED;
        !            88:        sp->unique = -1;
        !            89:        return(sp);
        !            90: }
        !            91: 
        !            92: void
        !            93: SymbolFree (symp)
        !            94:        SymbolEntry *symp;
        !            95: {
        !            96:        assert (symp->next == NULL);
        !            97:        free(symp);
        !            98: }
        !            99: 
        !           100: SymbolEntry *
        !           101: SymbolLookup(s)
        !           102:        char *s;
        !           103: {
        !           104:        int hash_value = RawHash(s);
        !           105:        register SymbolEntry * hp = hash_table[hash_value%HASHSIZE];
        !           106: 
        !           107:        while(hp!=NULL) {
        !           108:                if(hp->hash == hash_value &&
        !           109:                                strcmp (s, hp->name)==0) break;
        !           110:                hp = hp->next;
        !           111:        }
        !           112:        return(hp);
        !           113: }
        !           114: 
        !           115: /*
        !           116:  * enter the symbol into the symbol table.  It believes everything in the
        !           117:  * symp argument.
        !           118:  */
        !           119: void
        !           120: SymbolEnter (symp, attr)
        !           121:        SymbolEntry *symp;
        !           122:        byte attr;
        !           123: {
        !           124:        struct symbol_entry *hp;
        !           125: 
        !           126: #ifdef SAFE
        !           127:        assert (symp!=NULL);
        !           128:        assert (symp->hash == RawHash(symp->name));
        !           129:        assert (symp->attr == A_UNDEFINED);
        !           130: #endif
        !           131: 
        !           132:        hp = hash_table[symp->hash%HASHSIZE];
        !           133:        symp->next = hp;
        !           134:        hash_table[symp->hash%HASHSIZE] = symp;
        !           135:        symp->attr = attr;
        !           136:        if (HAS_UNIQUE(attr)){
        !           137:                struct ranges *rp = &uniques[attr];
        !           138:                int new_unique;
        !           139:                if(symp->unique==-1)
        !           140:                        symp->unique = new_unique = rp->max++;
        !           141:                else {
        !           142:                        new_unique = symp->unique;
        !           143:                        if(new_unique>=rp->max)
        !           144:                                rp->max = new_unique+1;
        !           145:                        else if(new_unique < rp->min)
        !           146:                                rp->min = new_unique;
        !           147:                }
        !           148:                if(new_unique>rp->limit)
        !           149:                        sem_error("number assigned to %s (%d) out of range",
        !           150:                                symp->name, new_unique);
        !           151:                if(new_unique<0)
        !           152:                        sem_error("number assigned to %s (%d) is negative",
        !           153:                                symp->name, new_unique);
        !           154:                assert(rp->max>=rp->min);
        !           155:        }
        !           156:        if (HAS_LIST(attr)) {
        !           157:                AppendToList(&lists[attr], symp);
        !           158:        }
        !           159: }
        !           160: 
        !           161: static void
        !           162: AppendToList(list, sp)
        !           163:        SymbolList *list;
        !           164:        SymbolEntry *sp;
        !           165: {
        !           166:        sp->link = NULL;
        !           167:        if(list->first==NULL)
        !           168:                list->first = sp;
        !           169:        else (list->last)->link = sp;
        !           170:        list->last = sp;
        !           171:        list->count++;
        !           172: }
        !           173: 
        !           174: SymbolCheckNodeValues()
        !           175: {
        !           176:        SymbolList *slist;
        !           177:        SymbolEntry **stab, **spp, *sp;
        !           178:        struct ranges *rp;
        !           179:        int i, range;
        !           180: 
        !           181:        rp = &uniques[A_NODE];
        !           182:        slist = &lists[A_NODE];
        !           183:        range = rp->max - rp->min + 1;
        !           184:        stab = (SymbolEntry **) malloc(range*sizeof(SymbolEntry *));
        !           185: 
        !           186:        for(i=range, spp = stab; i-->0; spp++) *spp = NULL;
        !           187: 
        !           188:        for(sp = slist->first; sp; sp = sp->link) {
        !           189:                SymbolEntry *sp2 = stab[sp->unique];
        !           190:                if(sp2==NULL)
        !           191:                        stab[sp->unique] = sp;
        !           192:                else
        !           193:                        sem_error("%s and %s have the same node value",
        !           194:                                sp2->name, sp->name);
        !           195:        }
        !           196:        free(stab);
        !           197: }
        !           198: 
        !           199: SymbolEntry *
        !           200: SymbolEnterKeyword(s, value)
        !           201:        char *s;
        !           202:        int value;
        !           203: {
        !           204:        SymbolEntry *sp = SymbolAllocate(s);
        !           205:        sp->sd.keyword = value;
        !           206:        SymbolEnter (sp, A_KEYWORD);
        !           207:        return(sp);
        !           208: }
        !           209: 
        !           210: void
        !           211: SymbolInit()
        !           212: {
        !           213:        SymbolEntry *sp;
        !           214: 
        !           215:        mem_init(&sym_mem,sizeof(SymbolEntry));
        !           216:        mem_init(&lab_mem,sizeof(LabelData));
        !           217:        mem_init(&tree_mem,sizeof(struct treeassoc));
        !           218:        SymbolEnterKeyword ("node", K_NODE);
        !           219:        SymbolEnterKeyword ("label", K_LABEL);
        !           220:        SymbolEnterKeyword ("prologue", K_PROLOGUE);
        !           221:        SymbolEnterKeyword ("const", K_CONST);
        !           222:        SymbolEnterKeyword ("insert", K_INSERT);
        !           223:        SymbolEnterKeyword ("cost", K_COST);
        !           224:        SymbolEnterKeyword ("action", K_ACTION);
        !           225: }
        !           226: 
        !           227: void
        !           228: SymbolMap(f)
        !           229:        int (*f)();
        !           230: {
        !           231:        SymbolEntry **spp, *sp;
        !           232:        for(spp = hash_table; spp < &hash_table[HASHSIZE]; spp++)
        !           233:                for(sp= *spp; sp!=NULL; sp = sp->next)
        !           234:                        f(sp);
        !           235: };
        !           236: 
        !           237: static int symcnt, labcnt, nodecnt;
        !           238: static
        !           239: sym_count(sp)
        !           240:        SymbolEntry *sp;
        !           241: {
        !           242:        symcnt++;
        !           243:        switch(sp->attr) {
        !           244:                case A_LABEL: {
        !           245:                        LabelData *lp;
        !           246:                        for(lp = sp->sd.lp;lp!=NULL;lp=lp->next) {
        !           247:                                labcnt++;
        !           248:                                nodecnt += cntnodes(lp->tree);
        !           249:                        }
        !           250:                } break;
        !           251:        }
        !           252: }
        !           253: 
        !           254: void
        !           255: SymbolFinish()
        !           256: {
        !           257:        if(DB_MEM&debug_flag) {
        !           258:                extern struct _mem node_mem;
        !           259:                int symout = mem_outstanding(&sym_mem);
        !           260:                int labout = mem_outstanding(&lab_mem);
        !           261:                int nodeout = mem_outstanding(&node_mem);
        !           262:                SymbolMap(sym_count);
        !           263:                fprintf(stderr,"symbols defined=%d out=%d\n",symcnt, symout);
        !           264:                fprintf(stderr,"labdata def=%d out=%d\n",labcnt,labout);
        !           265:                fprintf(stderr,"node def=%d out=%d\n",nodecnt,nodeout);
        !           266:                assert(symcnt==symout);
        !           267:                assert(labcnt==labout);
        !           268:                assert(nodecnt==nodeout);
        !           269:        }
        !           270: }
        !           271: 
        !           272: void
        !           273: SymbolEnterList (symp, attr)
        !           274:        SymbolEntry *symp;
        !           275:        int attr;
        !           276: {
        !           277:        /*
        !           278:         * enter in reverse order because the list was built in reverse
        !           279:         * order by the parser
        !           280:         */
        !           281: 
        !           282:        if(symp==NULL)
        !           283:                return;
        !           284:        SymbolEnterList(symp->next, attr);
        !           285:        if(symp->attr!=A_UNDEFINED)
        !           286:                sem_error ("multiple declaration ignored: %s", symp->name);
        !           287:        SymbolEnter (symp, attr);
        !           288: }
        !           289: 
        !           290: LabelData *
        !           291: SymbolEnterTreeIntoLabel(symp, tree, costfunc, action, lineno)
        !           292:        SymbolEntry *symp, *action, *costfunc;
        !           293:        struct node *tree;
        !           294:        int lineno;
        !           295: {
        !           296:        LabelData *tp = (LabelData *) mem_get(&lab_mem);
        !           297:        struct treeassoc *ap;
        !           298: 
        !           299:        if (symp==&ErrorSymbol) return(NULL);
        !           300: #ifdef SAFE
        !           301:        assert (tp!=NULL);
        !           302:        assert (symp->attr==A_LABEL);
        !           303: #endif
        !           304: 
        !           305:        tp->tree = tree;
        !           306:        tp->treeIndex = treeIndex++;
        !           307:        tp->lineno = lineno;
        !           308:        tp->next = symp->sd.lp;
        !           309:        tp->label = symp;
        !           310:        symp->sd.lp = tp;
        !           311: 
        !           312:        if (action!=NULL) {
        !           313:                ap = (struct treeassoc *) mem_get(&tree_mem);
        !           314:                ap->tree = tp->treeIndex;
        !           315:                ap->next = action->sd.ca.assoc;
        !           316:                action->sd.ca.assoc = ap;
        !           317:        }
        !           318: 
        !           319:        if (costfunc!=NULL) {
        !           320:                ap = (struct treeassoc *) mem_get(&tree_mem);
        !           321:                ap->tree = tp->treeIndex;
        !           322:                ap->next = costfunc->sd.ca.assoc;
        !           323:                costfunc->sd.ca.assoc = ap;
        !           324:        }
        !           325:        return(tp);
        !           326: }
        !           327: 
        !           328: static void
        !           329: WriteSymbols(sp, mask)
        !           330:        SymbolEntry *sp;
        !           331:        int mask;
        !           332: {
        !           333:        for(;sp!=NULL; sp = sp->link)
        !           334:                fprintf(symfile, "#define %s\t0%o\n", sp->name, sp->unique|mask);
        !           335: }
        !           336: 
        !           337: void
        !           338: SymbolDump()
        !           339: {
        !           340:        WriteSymbols(lists[A_NODE].first, M_NODE);
        !           341:        WriteSymbols(lists[A_LABEL].first, 0);
        !           342:        WriteSymbols(lists[A_CONST].first, 0);
        !           343:        fprintf(symfile, "#define MAXLABELS %d\n", uniques[A_LABEL].max);
        !           344:        fprintf(symfile, "#define MAXTREES %d\n", treeIndex);
        !           345:        fprintf(symfile, "#define MAXNDVAL %d\n", uniques[A_NODE].max);
        !           346: }
        !           347: 
        !           348: void
        !           349: SymbolGenerateWalkerCode()
        !           350: {
        !           351:        register SymbolEntry *pp;
        !           352:        int i;
        !           353:        extern int line_xref_flag;
        !           354:        struct treeassoc *tap;
        !           355:        register LabelData *lp;
        !           356:        register short int *mapTab;
        !           357: 
        !           358:        /*
        !           359:         * Write out the table of tree index to label correspondence
        !           360:         */
        !           361:        mapTab = (short int *) malloc (treeIndex * sizeof(short int));
        !           362:        for(pp=lists[A_LABEL].first; pp!=NULL; pp=pp->link) {
        !           363:                lp = pp->sd.lp;
        !           364:                if(lp==NULL)
        !           365:                        sem_error2("%s undefined\n", pp->name);
        !           366:                for(;lp!=NULL;lp=lp->next)
        !           367:                        mapTab[lp->treeIndex] = pp->unique;
        !           368:        }
        !           369:        fputs("short int mtMap[] = {\n", outfile);
        !           370:        for(i=0, oreset(); i < treeIndex;)
        !           371:                oputoct(mapTab[i++]);
        !           372:        fputs("};\n", outfile);
        !           373: 
        !           374:        /* generate tree to line index table */
        !           375:        if(line_xref_flag) {
        !           376:                for(pp=lists[A_LABEL].first; pp!=NULL; pp=pp->link) {
        !           377:                        lp = pp->sd.lp;
        !           378:                        for(;lp!=NULL;lp=lp->next)
        !           379:                                mapTab[lp->treeIndex] = lp->lineno;
        !           380:                }
        !           381:                fputs("short int mtLine[] = {\n", outfile);
        !           382:                for(i=0, oreset(); i<treeIndex;)
        !           383:                        oputint(mapTab[i++]);
        !           384:                fputs("};\n", outfile);
        !           385:        }
        !           386:        /*
        !           387:         * Generate path table
        !           388:         */
        !           389:        fputs ("short int mtPaths[] = {\n", outfile);
        !           390:        for(pp=lists[A_LABEL].first, oreset(); pp!=NULL; pp=pp->link) {
        !           391:                lp = pp->sd.lp;
        !           392:                if(lp==NULL)
        !           393:                        sem_error2("%s undefined\n", pp->name);
        !           394:                do {
        !           395:                        mapTab[lp->treeIndex] = ointcnt();
        !           396:                        oputint (lp->tree->nlleaves);
        !           397:                        SymbolWritePath (lp->tree);
        !           398:                        oputint (eSTOP);
        !           399:                        lp = lp->next;
        !           400:                } while (lp!=NULL);
        !           401:        }
        !           402:        fputs(" };\nshort int mtPathStart[] = {\n", outfile);
        !           403:        for(i=0, oreset(); i < treeIndex;)
        !           404:                oputint (mapTab[i++]);
        !           405:        fputs("};\n", outfile);
        !           406: 
        !           407:        /*
        !           408:         * Code to perform the action of the trees
        !           409:         */
        !           410:        fputs("NODEPTR\nmtAction (_t, _ll, _s)\n", outfile);
        !           411:        fputs("int _t; __match **_ll; skeleton *_s;\n", outfile);
        !           412:        fputs("{ NODEPTR root = _s->root;\n", outfile);
        !           413:        fputs("switch (_t) {\n", outfile);
        !           414:        for (pp=lists[A_ACTION].first; pp!=NULL; pp=pp->link) {
        !           415:                if ((tap=pp->sd.ca.assoc)==NULL) {
        !           416:                        sem_error2 ("%s not used", pp->name);
        !           417:                        continue;
        !           418:                }
        !           419:                for (; tap!=NULL; tap=tap->next)
        !           420:                        fprintf (outfile, "case %d:", tap->tree);
        !           421:                fputs ("{\n", outfile);
        !           422:                CodeWrite (outfile, pp->sd.ca.code);
        !           423:                fputs("} break;\n", outfile);
        !           424:        }
        !           425:        fputs("} return(_s->root);}\n", outfile);
        !           426: 
        !           427:        fputs ("mtEvalCost(_m, _ll, _s)\n", outfile);
        !           428:        fputs ("__match **_ll; __match *_m; skeleton *_s;\n", outfile);
        !           429:        fputs ("{ NODEPTR root = _s->root;\n", outfile);
        !           430:        fputs ("COST cost; cost = DEFAULT_COST;\n", outfile);
        !           431:        fputs ("switch(_m->tree) {\n", outfile);
        !           432:        for(pp=lists[A_COST].first; pp!=NULL; pp=pp->link) {
        !           433:                if ((tap=pp->sd.ca.assoc)==NULL) {
        !           434:                        sem_error2 ("%s not used", pp->name);
        !           435:                        continue;
        !           436:                }
        !           437:                for (; tap!=NULL; tap=tap->next)
        !           438:                        fprintf (outfile, "case %d:", tap->tree);
        !           439:                fputs ("{\n", outfile);
        !           440:                CodeWrite (outfile, pp->sd.ca.code);
        !           441:                fputs ("} break;\n", outfile);
        !           442:        }
        !           443:        fputs("}\n", outfile);
        !           444:        fputs("_m->cost = cost; return(xDEFER);}\n", outfile);
        !           445: 
        !           446: }
        !           447: 
        !           448: SymbolWritePath (root)
        !           449:        Node *root;
        !           450: {
        !           451:        Node *np;
        !           452:        if(root->nlleaves==0)
        !           453:                return;
        !           454:        if((root->sym)->attr==A_LABEL) {
        !           455:                oputint (eEVAL); oputoct (MV_LABEL((root->sym)->unique));
        !           456:                return;
        !           457:        }
        !           458:        oputint (ePUSH);
        !           459:        for(np = root->children;;) {
        !           460:                if(np->nlleaves > 0)
        !           461:                        SymbolWritePath (np);
        !           462:                if ((np = np->siblings) == NULL)
        !           463:                        break;
        !           464:                oputint (eNEXT);
        !           465:        }
        !           466:        oputint (ePOP);
        !           467:        return;
        !           468: }
        !           469: 
        !           470: static int gensymndx = 0;
        !           471: 
        !           472: char *
        !           473: SymbolGenUnique()
        !           474: {
        !           475:        static char name[7];
        !           476:        name[0] = '$';
        !           477:        sprintf (&name[1], "%05d", gensymndx++);
        !           478:        return (name);
        !           479: }

unix.superglobalmegacorp.com

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