Annotation of researchv10dc/cmd/efl/efixsrc/process.c, revision 1.1

1.1     ! root        1: #include <stdio.h>
        !             2: #include "efix.h"
        !             3: #define Hlen 4091
        !             4: #define HGULP 1020
        !             5: #define SGULP 8092
        !             6:  extern char *strcpy();
        !             7: 
        !             8:  char *
        !             9: alloc(x)
        !            10:  unsigned x;
        !            11: {
        !            12:        extern char *malloc();
        !            13:        char *s;
        !            14:        s = malloc(x);
        !            15:        if (!s) {
        !            16:                fprintf(stderr, "%s: malloc failure!\n", progname);
        !            17:                exit(1);
        !            18:                }
        !            19:        return s;
        !            20:        }
        !            21: 
        !            22:  struct HashHeader {
        !            23:        struct Hash *next, *prev;
        !            24:        } maintab[Hlen], memtab[Hlen];
        !            25: 
        !            26:  struct Hash {
        !            27:        struct HashHeader hh;
        !            28:        char *name;
        !            29:        char *type;
        !            30:        struct Hash *dup;
        !            31:        int lev;
        !            32:        } *halloc_next, *halloc_last, *lasthash;
        !            33: 
        !            34: /* type values:
        !            35:  *     static, auto, extern, register: i
        !            36:  *     char, double, float, int, long, short, unsigned, void: i
        !            37:  *     enum: e
        !            38:  *     struct, union: a
        !            39:  *     typedef: t
        !            40:  *     struct tag, union tag, typedefed name: T{type}
        !            41:  */
        !            42: 
        !            43:  char *salloc_next, *salloc_last;
        !            44:  struct SALLOC {
        !            45:        struct SALLOC *next;
        !            46:        char *last;
        !            47:        char block[SGULP];
        !            48:        } *Salloc_block;
        !            49:  struct HALLOC {
        !            50:        struct HALLOC *next, *prev;
        !            51:        struct Hash block[HGULP];
        !            52:        } *Halloc_block;
        !            53:        
        !            54:  struct Context {
        !            55:        struct Context *next, *prev;
        !            56:        struct SALLOC *Sblock;
        !            57:        char *snext, *slast;
        !            58:        struct HALLOC *Hblock;
        !            59:        struct Hash *hnext;
        !            60:        } *context;
        !            61:  int levnow;
        !            62: 
        !            63: new_context()
        !            64: {
        !            65:        struct Context *C;
        !            66:        ++levnow;
        !            67:        if (!context || !(C = context->next)) {
        !            68:                C = (struct Context *)alloc(sizeof(struct Context));
        !            69:                C->next = 0;
        !            70:                if (context)
        !            71:                        context->next = C;
        !            72:                C->prev = context;
        !            73:                }
        !            74:        context = C;
        !            75:        C->Sblock = Salloc_block;
        !            76:        C->Hblock = Halloc_block;
        !            77:        C->snext = salloc_next;
        !            78:        C->slast = salloc_last;
        !            79:        C->hnext = halloc_next;
        !            80:        }
        !            81: 
        !            82: end_context()
        !            83: {
        !            84:        struct Hash *h, *h0, *h00, *h1;
        !            85:        struct HALLOC *H;
        !            86:        struct Context *C;
        !            87: 
        !            88:        --levnow;
        !            89:        C = context;
        !            90:        context = C->prev;
        !            91:        if (!C || levnow < 0)
        !            92:                scream("too many end_context's");
        !            93:        Salloc_block = C->Sblock;
        !            94:        salloc_next = C->snext;
        !            95:        salloc_last = C->slast;
        !            96:        h00 = C->hnext;
        !            97:        if (H = Halloc_block) {
        !            98:                h0 = H->block;
        !            99:                h = halloc_next;
        !           100:                while(h != h00) {
        !           101:                        if (--h == h0) {
        !           102:                                H = H->prev;
        !           103:                                h0 = H->block;
        !           104:                                h = h0 + HGULP;
        !           105:                                continue;
        !           106:                                }
        !           107:                        h1 = h->hh.next;
        !           108:                        h1->hh.prev = h->hh.prev;
        !           109:                        h->hh.prev->hh.next = h1;
        !           110:                        }
        !           111:                }
        !           112:        Halloc_block = C->Hblock;
        !           113:        halloc_next = h00;
        !           114:        }
        !           115: 
        !           116:  struct Hash *
        !           117: hash(s, ht)
        !           118:  register char *s;
        !           119:  struct HashHeader *ht;
        !           120: {
        !           121:        register x = 0, c;
        !           122:        register struct Hash *h, *h0;
        !           123:        char *s0 = s;
        !           124: 
        !           125:        while(c = *s++) {
        !           126:                if (x & 1)
        !           127:                        x = 0x40000000 | (x>>1) ^ c;
        !           128:                else
        !           129:                        x = (x>>1) ^ c;
        !           130:                }
        !           131:        x %= Hlen;
        !           132:        lasthash = h0 = (struct Hash *) (ht + x);
        !           133:        s = s0;
        !           134:        for(h = h0->hh.next; h != h0; h = h->hh.next)
        !           135:                if (!strcmp(s,h->name))
        !           136:                        return h;
        !           137:        return 0;
        !           138:        }
        !           139: 
        !           140:  char *
        !           141: salloc(s)
        !           142:  char *s;
        !           143: {
        !           144:        unsigned x;
        !           145:        char *t;
        !           146:        struct SALLOC *S;
        !           147: 
        !           148:        x = strlen(s) + 1;
        !           149:        t = salloc_next;
        !           150:        if ((salloc_next += x) > salloc_last) {
        !           151:                if (Salloc_block && (S = Salloc_block->next)) {
        !           152:                        if (S->last - S->block < x)
        !           153:                                scream("Huge string in salloc");
        !           154:                        }
        !           155:                else {
        !           156:                        S = (struct SALLOC *)alloc(x + sizeof(struct SALLOC));
        !           157:                        if (Salloc_block)
        !           158:                                Salloc_block->next = S;
        !           159:                        S->last = S->block + x + SGULP;
        !           160:                        S->next = 0;
        !           161:                        }
        !           162:                t = S->block;
        !           163:                salloc_next = t + x;
        !           164:                salloc_last = S->last;
        !           165:                Salloc_block = S;
        !           166:                }
        !           167:        return strcpy(t, s);
        !           168:        }
        !           169: 
        !           170:  struct Hash *
        !           171: newhash(s,t)
        !           172:  char *s, *t;
        !           173: {
        !           174:        struct Hash *h, *h1;
        !           175:        struct HALLOC *H;
        !           176: 
        !           177:        if ((h = halloc_next++) >= halloc_last) {
        !           178:                if (!Halloc_block || !(H = Halloc_block->next)) {
        !           179:                        H = (struct HALLOC *)
        !           180:                                alloc(sizeof(struct HALLOC));
        !           181:                        H->next = 0;
        !           182:                        H->prev = Halloc_block;
        !           183:                        }
        !           184:                Halloc_block = H;
        !           185:                h = H->block;
        !           186:                halloc_next = h + 1;
        !           187:                halloc_last = h + HGULP;
        !           188:                }
        !           189:        h->name = s;
        !           190:        h->type = t;
        !           191:        h->lev = levnow;
        !           192:        h->hh.next = h1 = lasthash->hh.next;
        !           193:        h1->hh.prev = h;
        !           194:        h->hh.prev = lasthash;
        !           195:        lasthash->hh.next = h;
        !           196:        return h;
        !           197:        }
        !           198: 
        !           199:  struct Tok Toks[3];
        !           200:  char isdcl[128];
        !           201: 
        !           202: setup()
        !           203: {
        !           204:        int i;
        !           205:        struct HashHeader *h;
        !           206:        static char *keywds[] = {
        !           207:                "auto", "i",
        !           208:                "char", "i",
        !           209:                "double", "i",
        !           210:                "enum", "e",
        !           211:                "extern", "i",
        !           212:                "float", "i",
        !           213:                "int", "i",
        !           214:                "long", "i",
        !           215:                "register", "i",
        !           216:                "short", "i",
        !           217:                "static", "i",
        !           218:                "struct", "a",
        !           219:                "typedef", "t",
        !           220:                "union", "a",
        !           221:                "unsigned", "i",
        !           222:                "void", "i",
        !           223:                0, 0};
        !           224:        char **k, *s;
        !           225: 
        !           226:        Toks[0].next = Toks + 1;        Toks[0].prev = Toks + 2;
        !           227:        Toks[1].next = Toks + 2;        Toks[1].prev = Toks;
        !           228:        Toks[2].next = Toks;            Toks[2].prev = Toks + 1;
        !           229:        for(i = 0; i < 3; i++) Toks[i].inlevel = 1;
        !           230:        T = Toks;
        !           231:        for(h = maintab, i = 0; i < Hlen; ++i, ++h)
        !           232:                h->next = h->prev = (struct Hash *)h;
        !           233:        for(h = memtab, i = 0; i < Hlen; ++i, ++h)
        !           234:                h->next = h->prev = (struct Hash *)h;
        !           235: 
        !           236:        for(k = keywds; *k; k += 2) {
        !           237:                hash(*k, maintab);
        !           238:                newhash(k[0], k[1]);
        !           239:                }
        !           240:        for(s = "aeitT"; *s; ++s)
        !           241:                isdcl[*s] = 1;
        !           242:        }
        !           243: 
        !           244: process()
        !           245: {
        !           246:        int t;
        !           247:        struct Tok *T1;
        !           248: 
        !           249:        setup();
        !           250: 
        !           251:        while((t = token(0)) != FEND) {
        !           252:                if (t == SYMBOL)
        !           253:                        dcl();
        !           254:                else if (t != ';') {
        !           255:                        squawk("expected declaration");
        !           256:                        do token(2);
        !           257:                                while(t != ';');
        !           258:                        }
        !           259:                }
        !           260:  done:
        !           261:        for(T1 = T;;) {
        !           262:                T1 = T1->next;
        !           263:                if (!T1->inlevel)
        !           264:                        printf("%s%s", T1->white, T1->tok);
        !           265:                if (T1 == T)
        !           266:                        break;
        !           267:                }
        !           268:        }
        !           269: 
        !           270:  char *
        !           271: memname()
        !           272: {
        !           273:        int pars = 0;
        !           274:        char *s;
        !           275:        int t;
        !           276: 
        !           277:        for(t = T->type; ; t = token(2)) {
        !           278:                switch(t) {
        !           279:                        case '(': ++pars;
        !           280:                        case '*': continue;
        !           281:                        case ':':
        !           282:                                if (pars)
        !           283:                                        scream("unexpected :");
        !           284:                                getexp();
        !           285:                                return 0;
        !           286:                        default: break;
        !           287:                        }
        !           288:                break;
        !           289:                }
        !           290:        if (t != SYMBOL)
        !           291:                scream("expected * ( : or symbol") /*)*/;
        !           292:        s = salloc(T->tok);
        !           293:        for(;;) {
        !           294:                switch(token(2)) {
        !           295:                        case '(':
        !           296:                        case '[':
        !           297:                                ++pars;
        !           298:                                continue;
        !           299:                        case ')':
        !           300:                        case ']':
        !           301:                                --pars;
        !           302:                                continue;
        !           303:                        case ':':
        !           304:                                if (!pars) {
        !           305:                                        getexp();
        !           306:                                        break;
        !           307:                                        }
        !           308:                        case ';':
        !           309:                                break;
        !           310:                        case ',':
        !           311:                                if (pars <= 0)
        !           312:                                        break;
        !           313:                        default:
        !           314:                                continue;
        !           315:                        }
        !           316:                break;
        !           317:                }
        !           318:        if (pars)
        !           319:                squawk("bad paren count in memname");
        !           320:        return s;
        !           321:        }
        !           322: 
        !           323:  char *
        !           324: sdcl(tag)
        !           325: char *tag;
        !           326: {
        !           327:        int t, typed;
        !           328:        char buf[256], *m, *s;
        !           329:        struct Hash *h, *h1;
        !           330:        static int anon;
        !           331:        char *b, *be = buf + sizeof(buf);
        !           332: 
        !           333:        b = adjoin(buf,be,tag);
        !           334:        *b++ = *T->tok; /* 's' or 'u' */
        !           335:        t = token(2);
        !           336:        if (t == SYMBOL) {
        !           337:                adjoin(b,be,T->tok);
        !           338:                t = token(2);
        !           339:                }
        !           340:        else
        !           341:                sprintf(b, "#%d", ++anon);
        !           342:        s = salloc(buf);
        !           343:        if (t != '{') /*}*/ {
        !           344:                return s;
        !           345:                }
        !           346: 
        !           347:        /* struct foo {...} -- process the ... */
        !           348: 
        !           349:        for(t = token(2); /*{*/ t != '}'; t = token(2)) {
        !           350:                for(typed = 0; t == SYMBOL; t = token(2), typed = 1) {
        !           351:                        h = hash(T->tok, maintab);
        !           352:                        if (h) switch(*h->type) {
        !           353:                                case 'a':
        !           354:                                case 'e':
        !           355:                                        t = token(2);
        !           356:                                        if (t != SYMBOL)
        !           357:                                                scream("expected tag");
        !           358:                                case 'i':
        !           359:                                case 'T':
        !           360:                                        continue;
        !           361:                                case 't':
        !           362:                                        scream("typedef within struct!");
        !           363:                                }
        !           364:                        break;
        !           365:                        }
        !           366:                if (!typed)
        !           367:                        scream("no type!");
        !           368:                if (t != ';')
        !           369:                    for(; ; token(2)) {
        !           370:                        if (m = memname()) {
        !           371:                                h = hash(m, memtab);
        !           372:                                h1 = newhash(m, s);
        !           373:                                h1->dup = h;
        !           374:                                }
        !           375:                        switch(T->type) {
        !           376:                                case ',': continue;
        !           377:                                case ';': break;
        !           378:                                default:
        !           379:                                        scream("expected ; or ,");
        !           380:                                }
        !           381:                        break;
        !           382:                        }
        !           383:                }
        !           384:        token(2);
        !           385:        return s;
        !           386:        }
        !           387: 
        !           388: dcl()
        !           389: {
        !           390:        struct Hash *h;
        !           391:        char buf[256], *sym;
        !           392:        int pars = 0, t, typed = 0;
        !           393:        char *b = buf, *buf1 = buf, *be = buf + sizeof(buf), *tag = "";
        !           394: 
        !           395:        for(t = SYMBOL; t == SYMBOL; t = token(2)) {
        !           396:                h = hash(T->tok, maintab);
        !           397:                if (h) switch(*h->type) {
        !           398:                        case 'T':
        !           399:                                tag = h->type + 1;
        !           400:                                typed = 1;
        !           401:                                continue;
        !           402:                        case 'a':       /* aggregate -- struct or union */
        !           403:                                tag = sdcl(tag);
        !           404:                                typed = 1;
        !           405:                                t = T->type;
        !           406:                                goto havetag;
        !           407:                        case 'e':
        !           408:                                do t = token(2);
        !           409:                                        while(t != ';');
        !           410:                                return;
        !           411:                        case 'i':
        !           412:                                typed = 1;
        !           413:                                continue;
        !           414:                        case 't':
        !           415:                                typed = 0;
        !           416:                                *buf = 'T';
        !           417:                                b = buf1 = buf + 1;
        !           418:                                continue;
        !           419:                        }
        !           420:                break;
        !           421:                }
        !           422:  havetag:
        !           423:        for(; t != ';'; t = token(2)) {
        !           424:                if (t != SYMBOL)
        !           425:                    switch(t) {
        !           426:                        case '(':
        !           427:                                ++pars;
        !           428:                        case '*':
        !           429:                                *b++ = t;
        !           430:                                continue;
        !           431:                        default:
        !           432:                                scream("expected symbol, ( or *" /*)*/);
        !           433:                        }
        !           434:                sym = salloc(T->tok);
        !           435:                b = adjoin(b,be,tag);
        !           436:                while(pars > 0) {
        !           437:                        switch(t = token(2)) {
        !           438:                                case '(':
        !           439:                                case '[':
        !           440:                                        ++pars;
        !           441:                                        break;
        !           442:                                case ')':
        !           443:                                case ']':
        !           444:                                        --pars;
        !           445:                                        break;
        !           446:                                default:
        !           447:                                        scream("expected ( [ ] or )");
        !           448:                                }
        !           449:                        *b++ = t;
        !           450:                        }
        !           451:                if (pars < 0)
        !           452:                        scream("negative paren count!");
        !           453:                t = token(2);
        !           454:                if (t == '(' /*)*/) {
        !           455:                        adjoin(b,be,"()");
        !           456:                        if ((h = hash(sym, maintab))) {
        !           457:                                if (h->lev == levnow && strcmp(buf,h->type)) {
        !           458:  badtype:
        !           459:                                        squawk("wrong type!");
        !           460:                                        fprintf(stderr, "expected %s, got %s\n",
        !           461:                                                h->type, buf);
        !           462:                                        exit(1);
        !           463:                                        }
        !           464:                                }
        !           465:                        else newhash(sym,salloc(buf));
        !           466: 
        !           467:                        /* start of a function body? */
        !           468: 
        !           469:                        switch(t = token(2)) {
        !           470:                                case SYMBOL:
        !           471:                                        function();
        !           472:                                        return;
        !           473:                                case /*(*/ ')':
        !           474:                                        t = token(2);
        !           475:                                        if (t == '{'/*}*/) {
        !           476:                                                function();
        !           477:                                                return;
        !           478:                                                }
        !           479:                                        break;
        !           480:                                default:
        !           481:                                        scream(/*(*/"expected symbol or )");
        !           482:                                }
        !           483:                        }
        !           484:                else {
        !           485:                        if (!typed)
        !           486:                                scream("expected type or function prologue");
        !           487:                        if (t == '['/*]*/)
        !           488:                                for(; ; t = token(2)) {
        !           489:                                        switch(t) {
        !           490:                                                case '[':
        !           491:                                                        if (!pars)
        !           492:                                                                adjoin(b,be,"[]");
        !           493:                                                case '(':
        !           494:                                                        ++pars;
        !           495:                                                        continue;
        !           496:                                                case ']':
        !           497:                                                case ')':
        !           498:                                                        --pars;
        !           499:                                                        continue;
        !           500:                                                default:
        !           501:                                                        if (pars)
        !           502:                                                                continue;
        !           503:                                                }
        !           504:                                        break;
        !           505:                                        }
        !           506:                        if ((h = hash(sym, maintab))) {
        !           507:                                if (h->lev == levnow && strcmp(buf,h->type))
        !           508:                                        goto badtype;
        !           509:                                }
        !           510:                        else newhash(sym,salloc(buf));
        !           511:                        }
        !           512:                switch(t) {
        !           513:                        case ',':
        !           514:                                break;
        !           515:                        case ';':
        !           516:                                return;
        !           517:                        case '=':
        !           518:                                t = getexp();
        !           519:                                if (t == ';')
        !           520:                                        return;
        !           521:                                break;
        !           522:                        default:
        !           523:                                scream("expected , ; or =");
        !           524:                        }
        !           525:                b = buf1;       
        !           526:                }
        !           527:        }
        !           528: 
        !           529: doarrow()
        !           530: {
        !           531:        struct Tok *T0, *T1;
        !           532:        int t;
        !           533:        struct Hash *h, *h0;
        !           534:        char *s, *what;
        !           535: 
        !           536:        T0 = T->prev;
        !           537:        if (T0->type != SYMBOL || T0->inlevel)
        !           538:                return;
        !           539:        untok = t = token(2);
        !           540:        if (t != SYMBOL)
        !           541:                return;
        !           542:        T1 = T;
        !           543:        if (!(h = hash(T1->tok, memtab))
        !           544:                || !(h0 = hash(T0->tok, maintab)))
        !           545:                        return;
        !           546:        if (*h0->type == '*' && !strcmp(h0->type+1, h->type))
        !           547:                return;
        !           548:        T0->inlevel = 1;
        !           549:        s = h->type;
        !           550:        what = *s++ == 's' ? "struct" : "union";
        !           551:        if (!h->dup)
        !           552:                printf("%s((%s %s *)%s)", T0->white, what, s, T0->tok);
        !           553:        else {
        !           554:                printf("%s((%s %s /*"/*))*/, T0->white, what, s);
        !           555:                if (verbose) {
        !           556:                        squawk("ambiguous tag");
        !           557:                        fprintf(stderr, "%s %s", what, s);
        !           558:                        }
        !           559:                while(h = h->dup) {
        !           560:                        s = h->type;
        !           561:                        what = *s++ == 's' ? "struct" : "union";
        !           562:                        printf("|| %s %s", what, s);
        !           563:                        if (verbose)
        !           564:                                fprintf(stderr, " || %s %s", what, s);
        !           565:                        }
        !           566:                printf(/*((*/" */ *)%s)", T0->tok);
        !           567:                }
        !           568:        }
        !           569: 
        !           570: getexp()
        !           571: {
        !           572:        int brcnt = 0, t;
        !           573: 
        !           574:        for(;;) switch(t = token(2)) {
        !           575:                case ';':
        !           576:                        if (brcnt)
        !           577:                                scream("unclosed braces!");
        !           578:                        /* no break */
        !           579:                case ',':
        !           580:                        if (!brcnt)
        !           581:                                return t;
        !           582:                        break;
        !           583:                case ARROW:
        !           584:                        doarrow();
        !           585:                        break;
        !           586:                case '(':
        !           587:                case '{':
        !           588:                        ++brcnt;
        !           589:                        break;
        !           590:                case '}':
        !           591:                case ')':
        !           592:                        --brcnt;
        !           593:                        break;
        !           594:                }
        !           595:        }
        !           596: 
        !           597: function()
        !           598: {
        !           599:        int paren, t;
        !           600:        struct Hash *h;
        !           601:        /*debug*/static int zork; extern int lineno;
        !           602: 
        !           603:        if (levnow)
        !           604:                scream("inner function def!");
        !           605:        new_context();
        !           606:        if (T->type == SYMBOL) {
        !           607:                while((t = token(2)) != /*(*/ ')') {
        !           608:                        if (t != ',')
        !           609:                                scream(/*(*/"expected ) or ,");
        !           610:                        if (token(2) != SYMBOL)
        !           611:                                scream("expected dummy arg");
        !           612:                        }
        !           613:                while((t = token(2)) == SYMBOL)
        !           614:                        dcl();
        !           615:                if (t != '{'/*}*/)
        !           616:                        scream(/*{*/"expected }");
        !           617:                }
        !           618:        new_context();
        !           619:        paren = 0;
        !           620:  top:
        !           621:        for(;;) {
        !           622:                switch(t = token(2)) {
        !           623:                        case ';':
        !           624:                                continue;
        !           625:                        case '{':
        !           626:                                new_context();
        !           627:                                continue;
        !           628:                        case '}':
        !           629:                                end_context();
        !           630:                                if (levnow == 1) {
        !           631:                                        end_context();
        !           632:                                        return;
        !           633:                                        }
        !           634:                                continue;
        !           635:                        case '(': /*)*/
        !           636:                                paren++;
        !           637:                                break;
        !           638:                        case SYMBOL:
        !           639:                                if ((h = hash(T->tok,maintab))
        !           640:                                        && isdcl[*h->type]) {
        !           641:                                                dcl();
        !           642:                                                continue;
        !           643:                                                }
        !           644:                        }
        !           645:                /* fall thru for non declaration stmt */
        !           646:                for(;;) {
        !           647:                        /*debug*/ if (lineno == zork)
        !           648:                        /*debug*/       printf("");
        !           649:                        switch(t = token(2)) {
        !           650:                                case ARROW:
        !           651:                                        doarrow();
        !           652:                                        continue;
        !           653:                                case ';':
        !           654:                                        if (!paren)
        !           655:                                                goto top;
        !           656:                                        continue;
        !           657:                                case '(':
        !           658:                                        ++paren;
        !           659:                                        continue;
        !           660:                                case ')':
        !           661:                                        if (--paren < 0)
        !           662:                                                scream("bad paren count");
        !           663:                                        continue;
        !           664:                                case '{':
        !           665:                                        if (paren)
        !           666:                                                scream("unexpected {");
        !           667:                                        new_context();
        !           668:                                        goto top;
        !           669:                                case '}':
        !           670:                                        scream("unexpected }");
        !           671:                                }
        !           672:                        }
        !           673:                }
        !           674:        }

unix.superglobalmegacorp.com

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