Annotation of researchv8dc/cmd/cyntax/cem/equiv.c, revision 1.1.1.1

1.1       root        1: #include       "cem.h"
                      2: #define        STD_OBJ 1
                      3: #include       "stdobj.h"
                      4: #include       "types.h"
                      5: #include       "symbol.h"
                      6: #include       "type.h"
                      7: #include       "var.h"
                      8: 
                      9: /*
                     10:  *     Type equivalence routines.
                     11:  */
                     12: 
                     13: /*
                     14:  *     Does p differ from q because of a file modtime difference?
                     15:  */
                     16: int
                     17: different_vintage(p, q)
                     18: register type  *p;
                     19: register type  *q;
                     20: {
                     21:        register char   *s;
                     22:        register char   *t;
                     23: 
                     24:        loop
                     25:        {
                     26:                if (p->t_type != q->t_type)
                     27:                        return 0;
                     28: 
                     29:                switch (p->t_type)
                     30:                {
                     31:                case t_arrayof:
                     32:                        if (p->d.size != q->d.size)
                     33:                                return 0;
                     34: 
                     35:                case t_dimless:
                     36:                case t_ftnreturning:
                     37:                case t_ptrto:
                     38:                        p = p->t_subtype;
                     39:                        q = q->t_subtype;
                     40:                        continue;
                     41: 
                     42:                case t_basetype:
                     43:                case t_bitfield:
                     44:                        return 0;
                     45: 
                     46:                case t_enum:
                     47:                        s = p->d.e->e_file->sy_name;
                     48:                        t = q->d.e->e_file->sy_name;
                     49:                        break;
                     50: 
                     51:                case t_structof:
                     52:                        s = p->d.s->s_file->sy_name;
                     53:                        t = q->d.s->s_file->sy_name;
                     54:                        break;
                     55: 
                     56:                case t_unionof:
                     57:                        s = p->d.u->u_file->sy_name;
                     58:                        t = q->d.u->u_file->sy_name;
                     59:                        break;
                     60: 
                     61:                default:
                     62:                        fprintf(stderr, "%s: bad type in different_vintage\n", my_name);
                     63:                        exit(1);
                     64:                }
                     65: 
                     66:                if (s == t)
                     67:                        return 0;
                     68: 
                     69:                while (*s++ == *t)
                     70:                {
                     71:                        if (*t++ == TIME_SEP)
                     72:                                return 1;
                     73:                }
                     74: 
                     75:                return 0;
                     76:        }
                     77: }
                     78: 
                     79: /*
                     80:  *     Is p an elaboration of q (complex type as base).
                     81:  */
                     82: int
                     83: complex_elaboration(p, q)
                     84: register type  *p;
                     85: register type  *q;
                     86: {
                     87:        register symbol *s;
                     88:        register symbol *t;
                     89: 
                     90:        loop
                     91:        {
                     92:                if (p->t_type != q->t_type)
                     93:                        return 0;
                     94: 
                     95:                switch (p->t_type)
                     96:                {
                     97:                case t_arrayof:
                     98:                        if (p->d.size != q->d.size)
                     99:                                return 0;
                    100: 
                    101:                case t_dimless:
                    102:                case t_ftnreturning:
                    103:                case t_ptrto:
                    104:                        p = p->t_subtype;
                    105:                        q = q->t_subtype;
                    106:                        continue;
                    107: 
                    108:                case t_basetype:
                    109:                case t_bitfield:
                    110:                        return 0;
                    111: 
                    112:                case t_enum:
                    113:                        if (p->d.e->e_list == NULL || q->d.e->e_list != NULL)
                    114:                                return 0;
                    115: 
                    116:                        s = p->d.e->e_name;
                    117:                        t = q->d.e->e_name;
                    118:                        break;
                    119: 
                    120:                case t_structof:
                    121:                        if (p->d.s->s_list == NULL || q->d.s->s_list != NULL)
                    122:                                return 0;
                    123: 
                    124:                        s = p->d.s->s_name;
                    125:                        t = q->d.s->s_name;
                    126:                        break;
                    127: 
                    128:                case t_unionof:
                    129:                        if (p->d.u->u_list == NULL || q->d.u->u_list != NULL)
                    130:                                return 0;
                    131: 
                    132:                        s = p->d.u->u_name;
                    133:                        t = q->d.u->u_name;
                    134:                        break;
                    135: 
                    136:                default:
                    137:                        fprintf(stderr, "%s: bad type in complex_elaboration\n", my_name);
                    138:                        exit(1);
                    139:                }
                    140: 
                    141:                return s == t || s == NULL;
                    142:        }
                    143: }
                    144: 
                    145: /*
                    146:  *     Is p an elaboration of q (a dimensionless array).
                    147:  */
                    148: int
                    149: array_elaboration(p, q)
                    150: register type  *p;
                    151: register type  *q;
                    152: {
                    153:        return p->t_type == t_arrayof && q->t_type == t_dimless && p->t_subtype == q->t_subtype;
                    154: }
                    155: 
                    156: /*
                    157:  *     Can t be coerced (silently) to u (reflexive).
                    158:  */
                    159: int
                    160: coercible(t, u)
                    161: type   *t;
                    162: type   *u;
                    163: {
                    164:        register int    e;
                    165:        register int    b;
                    166: 
                    167:        if (pedantic)
                    168:                return 0;
                    169: 
                    170:        switch (t->t_type)
                    171:        {
                    172:        case t_basetype:
                    173:                if ((t->d.mask & FLOAT) != 0)
                    174:                        return 0;
                    175: 
                    176:                b = 1;
                    177:                e = 0;
                    178:                break;
                    179: 
                    180:        case t_enum:
                    181:                b = 0;
                    182:                e = 1;
                    183:                break;
                    184: 
                    185:        default:
                    186:                return 0;
                    187:        }
                    188: 
                    189:        switch (u->t_type)
                    190:        {
                    191:        case t_basetype:
                    192:                if ((u->d.mask & FLOAT) != 0)
                    193:                        return 0;
                    194: 
                    195:                b++;
                    196:                break;
                    197: 
                    198:        case t_enum:
                    199:                e++;
                    200:                break;
                    201: 
                    202:        default:
                    203:                return 0;
                    204:        }
                    205: 
                    206:        if (b == 2)
                    207:                return (t->d.mask & ~UNSIGNED) == (u->d.mask & ~UNSIGNED);
                    208: 
                    209:        return e != 2;
                    210: }
                    211: 
                    212: static int     really_compatible();
                    213: 
                    214: /*
                    215:  *     Struct/union member compatible.
                    216:  */
                    217: static int
                    218: member_compatible(p, q)
                    219: type   *p;
                    220: type   *q;
                    221: {
                    222:        if (p == q)
                    223:                return 1;
                    224: 
                    225:        return really_compatible(p, q);
                    226: }
                    227: 
                    228: /*
                    229:  *     Is p compatible with q (reflexive).
                    230:  */
                    231: static int
                    232: really_compatible(p, q)
                    233: register type  *p;
                    234: register type  *q;
                    235: {
                    236:        typedef struct busy     busy;
                    237: 
                    238:        struct busy
                    239:        {
                    240:                type    *b_p;
                    241:                type    *b_q;
                    242:                busy    *b_next;
                    243:        };
                    244: 
                    245:        busy            this;
                    246:        static busy     *busy_list;
                    247: 
                    248:        loop
                    249:        {
                    250:                if (p->t_type != q->t_type)
                    251:                {
                    252:                        if (p->t_type == t_arrayof || p->t_type == t_dimless)
                    253:                                p = p->t_subtype;
                    254:                        else
                    255:                                return 0;
                    256: 
                    257:                        if (q->t_type == t_arrayof || q->t_type == t_dimless)
                    258:                                q = q->t_subtype;
                    259:                        else
                    260:                                return 0;
                    261: 
                    262:                        /*
                    263:                         *      If the types are now equal one is an array
                    264:                         *      elaboration of the other.
                    265:                         */
                    266:                        if (p == q)
                    267:                                return 1;
                    268: 
                    269:                        continue;
                    270:                }
                    271: 
                    272:                switch (p->t_type)
                    273:                {
                    274:                case t_arrayof:
                    275:                        if (p->d.size != q->d.size)
                    276:                                return 0;
                    277: 
                    278:                case t_dimless:
                    279:                case t_ftnreturning:
                    280:                case t_ptrto:
                    281:                        p = p->t_subtype;
                    282:                        q = q->t_subtype;
                    283:                        break;
                    284: 
                    285:                case t_basetype:
                    286:                case t_bitfield:
                    287:                        return 0;
                    288: 
                    289:                case t_enum:
                    290:                        if
                    291:                        (
                    292:                                p->d.e->e_name != q->d.e->e_name
                    293:                                &&
                    294:                                p->d.e->e_name != NULL
                    295:                                &&
                    296:                                q->d.e->e_name != NULL
                    297:                        )
                    298:                                return 0;
                    299: 
                    300:                        if (p->d.e->e_list == NULL || q->d.e->e_list == NULL)
                    301:                                        return 1;
                    302: 
                    303:                        return 0;
                    304: 
                    305:                case t_structof:
                    306:                        if
                    307:                        (
                    308:                                p->d.s->s_name != q->d.s->s_name
                    309:                                &&
                    310:                                p->d.s->s_name != NULL
                    311:                                &&
                    312:                                q->d.s->s_name != NULL
                    313:                        )
                    314:                                return 0;
                    315: 
                    316:                        if (p->d.s->s_list == NULL || q->d.s->s_list == NULL)
                    317:                                        return 1;
                    318: 
                    319:                        if (p->d.s->s_size != q->d.s->s_size)
                    320:                                return 0;
                    321: 
                    322:                        {
                    323:                                register busy   *sb;
                    324: 
                    325:                                for (sb = busy_list; sb != NULL; sb = sb->b_next)
                    326:                                {
                    327:                                        if
                    328:                                        (
                    329:                                                sb->b_p == p && sb->b_q == q
                    330:                                                ||
                    331:                                                sb->b_p == q && sb->b_q == p
                    332:                                        )
                    333:                                                return 1;
                    334:                                }
                    335:                        }
                    336: 
                    337:                        if (modtimes && p->d.s->s_line == q->d.s->s_line && match_times(p->d.s->s_file, q->d.s->s_file))
                    338:                                return 1;
                    339: 
                    340:                        this.b_p = p;
                    341:                        this.b_q = q;
                    342:                        this.b_next = busy_list;
                    343:                        busy_list = &this;
                    344: 
                    345:                        {
                    346:                                register s_elt  *a;
                    347:                                register s_elt  *b;
                    348: 
                    349:                                a = p->d.s->s_list;
                    350:                                b = q->d.s->s_list;
                    351: 
                    352:                                while (a != NULL)
                    353:                                {
                    354:                                        if (b == NULL || !member_compatible(a->s_type, b->s_type))
                    355:                                        {
                    356:                                                busy_list = this.b_next;
                    357:                                                return 0;
                    358:                                        }
                    359: 
                    360:                                        a = a->s_next;
                    361:                                        b = b->s_next;
                    362:                                }
                    363: 
                    364:                                busy_list = this.b_next;
                    365:                                return b == NULL;
                    366:                        }
                    367: 
                    368:                case t_unionof:
                    369:                        if
                    370:                        (
                    371:                                p->d.u->u_name != q->d.u->u_name
                    372:                                &&
                    373:                                p->d.u->u_name != NULL
                    374:                                &&
                    375:                                q->d.u->u_name != NULL
                    376:                        )
                    377:                                return 0;
                    378: 
                    379:                        if (p->d.u->u_list == NULL || q->d.u->u_list == NULL)
                    380:                                        return 1;
                    381: 
                    382:                        if (p->d.u->u_size != q->d.u->u_size)
                    383:                                return 0;
                    384: 
                    385:                        {
                    386:                                register busy   *ub;
                    387: 
                    388:                                for (ub = busy_list; ub != NULL; ub = ub->b_next)
                    389:                                {
                    390:                                        if
                    391:                                        (
                    392:                                                ub->b_p == p && ub->b_q == q
                    393:                                                ||
                    394:                                                ub->b_p == q && ub->b_q == p
                    395:                                        )
                    396:                                                return 1;
                    397:                                }
                    398:                        }
                    399: 
                    400:                        if (modtimes && p->d.u->u_line == q->d.u->u_line && match_times(p->d.u->u_file, q->d.u->u_file))
                    401:                                return 1;
                    402: 
                    403:                        this.b_p = p;
                    404:                        this.b_q = q;
                    405:                        this.b_next = busy_list;
                    406:                        busy_list = &this;
                    407: 
                    408:                        {
                    409:                                register u_elt  *a;
                    410:                                register u_elt  *b;
                    411: 
                    412:                                a = p->d.u->u_list;
                    413:                                b = q->d.u->u_list;
                    414: 
                    415:                                while (a != NULL)
                    416:                                {
                    417:                                        if (b == NULL || !member_compatible(a->u_type, b->u_type))
                    418:                                        {
                    419:                                                busy_list = this.b_next;
                    420:                                                return 0;
                    421:                                        }
                    422: 
                    423:                                        a = a->u_next;
                    424:                                        b = b->u_next;
                    425:                                }
                    426: 
                    427:                                busy_list = this.b_next;
                    428:                                return b == NULL;
                    429:                        }
                    430: 
                    431:                default:
                    432:                        fprintf(stderr, "%s: bad type in really_compatible\n", my_name);
                    433:                        exit(1);
                    434:                }
                    435:        }
                    436: }
                    437: 
                    438: int
                    439: compatible_arglist(a, b, v)
                    440: register arg   *a;
                    441: register arg   *b;
                    442: int            v;
                    443: {
                    444:        register args   *p;
                    445:        register args   *q;
                    446:        register int    n;
                    447: 
                    448:        if (v < 0)
                    449:        {
                    450:                if (a->a_count != b->a_count)
                    451:                        return 0;
                    452: 
                    453:                n = a->a_count;
                    454:        }
                    455:        else
                    456:        {
                    457:                if (b->a_count < v)
                    458:                        return 0;
                    459: 
                    460:                n = v;
                    461:        }
                    462: 
                    463:        p = a->a_head;
                    464:        q = b->a_head;
                    465: 
                    466:        while (--n >= 0)
                    467:        {
                    468:                if (p->a_type != q->a_type && !compatible(p->a_type, q->a_type))
                    469:                        return 0;
                    470: 
                    471:                p = p->a_next;
                    472:                q = q->a_next;
                    473:        }
                    474: 
                    475:        return 1;
                    476: }
                    477: 
                    478: int
                    479: coercible_arglist(a, b, v)
                    480: register arg   *a;
                    481: register arg   *b;
                    482: int            v;
                    483: {
                    484:        register args   *p;
                    485:        register args   *q;
                    486:        register int    n;
                    487: 
                    488:        if (v < 0)
                    489:        {
                    490:                if (a->a_count != b->a_count)
                    491:                        return 0;
                    492: 
                    493:                n = a->a_count;
                    494:        }
                    495:        else
                    496:        {
                    497:                if (b->a_count < v)
                    498:                        return 0;
                    499: 
                    500:                n = v;
                    501:        }
                    502: 
                    503:        p = a->a_head;
                    504:        q = b->a_head;
                    505: 
                    506:        while (--n >= 0)
                    507:        {
                    508:                if (p->a_type != q->a_type && !coercible(p->a_type, q->a_type))
                    509:                        return 0;
                    510: 
                    511:                p = p->a_next;
                    512:                q = q->a_next;
                    513:        }
                    514: 
                    515:        return 1;
                    516: }
                    517: 
                    518: /*
                    519:  *     We win a lot by hashing previous results.
                    520:  */
                    521: #define        CHASHSZ 37
                    522: #define        CPRIME0 7
                    523: #define        CPRIME1 31
                    524: 
                    525: /*
                    526:  *     'compatible' hashing by type indices.
                    527:  */
                    528: static int
                    529: hash_compatible(h0, h1, r)
                    530: long   h0;
                    531: long   h1;
                    532: int    r;
                    533: {
                    534:        typedef struct chash    chash;
                    535: 
                    536:        struct chash
                    537:        {
                    538:                long    h0;
                    539:                long    h1;
                    540:                int     r;
                    541:                chash   *left;
                    542:                chash   *right;
                    543:        };
                    544: 
                    545:        register long   i;
                    546:        register long   j;
                    547:        register chash  **n;
                    548:        static chash    *chasht[CHASHSZ];
                    549: 
                    550:        i = CPRIME0 * h0 + CPRIME1 * h1;
                    551: 
                    552:        if (i < 0)
                    553:                j = -i % CHASHSZ;
                    554:        else
                    555:                j = i % CHASHSZ;
                    556: 
                    557:        n = &chasht[j];
                    558: 
                    559:        while (*n != NULL)
                    560:        {
                    561:                j = CPRIME0 * (*n)->h0 + CPRIME1 * (*n)->h1 - i;
                    562: 
                    563:                if (j == 0 && (*n)->h0 == h0 && (*n)->h1 == h1)
                    564:                        return (*n)->r;
                    565: 
                    566:                n = j > 0 ? &(*n)->left : &(*n)->right;
                    567:        }
                    568: 
                    569:        if (r >= 0)
                    570:        {
                    571:                *n = talloc(chash);
                    572:                (*n)->h0 = h0;
                    573:                (*n)->h1 = h1;
                    574:                (*n)->r = r;
                    575:                (*n)->left = NULL;
                    576:                (*n)->right = NULL;
                    577:        }
                    578: 
                    579:        return r;
                    580: }
                    581: 
                    582: /*
                    583:  *     Is p compatible with q (reflexive).  This includes coercible.
                    584:  */
                    585: int
                    586: compatible(p, q)
                    587: type   *p;
                    588: type   *q;
                    589: {
                    590:        register int    ret;
                    591: 
                    592:        if (coercible(p, q))
                    593:                return 1;
                    594: 
                    595:        if
                    596:        (
                    597:                (ret = hash_compatible(p->t_index, q->t_index, -1)) < 0
                    598:                &&
                    599:                (ret = hash_compatible(q->t_index, p->t_index, -1)) < 0
                    600:        )
                    601:        {
                    602:                ret = really_compatible(p, q);
                    603:                hash_compatible(p->t_index, q->t_index, ret);
                    604:        }
                    605: 
                    606:        return ret;
                    607: }

unix.superglobalmegacorp.com

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