Annotation of 43BSDReno/pgrm/dbx/modula-2.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that: (1) source distributions retain this entire copyright
                      7:  * notice and comment, and (2) distributions including binaries display
                      8:  * the following acknowledgement:  ``This product includes software
                      9:  * developed by the University of California, Berkeley and its contributors''
                     10:  * in the documentation or other materials provided with the distribution
                     11:  * and in all advertising materials mentioning features or use of this
                     12:  * software. Neither the name of the University nor the names of its
                     13:  * contributors may be used to endorse or promote products derived
                     14:  * from this software without specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: static char sccsid[] = "@(#)modula-2.c 5.4 (Berkeley) 6/1/90";
                     22: #endif /* not lint */
                     23: 
                     24: /*
                     25:  * Modula-2 specific symbol routines.
                     26:  */
                     27: 
                     28: #include "defs.h"
                     29: #include "symbols.h"
                     30: #include "modula-2.h"
                     31: #include "languages.h"
                     32: #include "tree.h"
                     33: #include "eval.h"
                     34: #include "mappings.h"
                     35: #include "process.h"
                     36: #include "runtime.h"
                     37: #include "machine.h"
                     38: 
                     39: #ifndef public
                     40: #endif
                     41: 
                     42: private Language mod2;
                     43: private boolean initialized;
                     44: 
                     45: 
                     46: #define ischar(t) ( \
                     47:     (t) == t_char->type or \
                     48:     ((t)->class == RANGE and istypename((t)->type, "char")) \
                     49: )
                     50: 
                     51: /*
                     52:  * Initialize Modula-2 information.
                     53:  */
                     54: 
                     55: public modula2_init ()
                     56: {
                     57:     mod2 = language_define("modula-2", ".mod");
                     58:     language_setop(mod2, L_PRINTDECL, modula2_printdecl);
                     59:     language_setop(mod2, L_PRINTVAL, modula2_printval);
                     60:     language_setop(mod2, L_TYPEMATCH, modula2_typematch);
                     61:     language_setop(mod2, L_BUILDAREF, modula2_buildaref);
                     62:     language_setop(mod2, L_EVALAREF, modula2_evalaref);
                     63:     language_setop(mod2, L_MODINIT, modula2_modinit);
                     64:     language_setop(mod2, L_HASMODULES, modula2_hasmodules);
                     65:     language_setop(mod2, L_PASSADDR, modula2_passaddr);
                     66:     initialized = false;
                     67: }
                     68: 
                     69: /*
                     70:  * Typematch tests if two types are compatible.  The issue
                     71:  * is a bit complicated, so several subfunctions are used for
                     72:  * various kinds of compatibility.
                     73:  */
                     74: 
                     75: private boolean builtinmatch (t1, t2)
                     76: register Symbol t1, t2;
                     77: {
                     78:     boolean b;
                     79: 
                     80:     b = (boolean) (
                     81:        (
                     82:            t2 == t_int->type and t1->class == RANGE and
                     83:            (
                     84:                istypename(t1->type, "integer") or
                     85:                istypename(t1->type, "cardinal")
                     86:            )
                     87:        ) or (
                     88:            t2 == t_char->type and
                     89:            t1->class == RANGE and istypename(t1->type, "char")
                     90:        ) or (
                     91:            t2 == t_real->type and
                     92:            t1->class == RANGE and (
                     93:                istypename(t1->type, "real") or
                     94:                istypename(t1->type, "longreal")
                     95:            )
                     96:        ) or (
                     97:            t2 == t_boolean->type and
                     98:            t1->class == RANGE and istypename(t1->type, "boolean")
                     99:        )
                    100:     );
                    101:     return b;
                    102: }
                    103: 
                    104: private boolean nilMatch (t1, t2)
                    105: register Symbol t1, t2;
                    106: {
                    107:     boolean b;
                    108: 
                    109:     b = (boolean) (
                    110:        (t1 == t_nil and t2->class == PTR) or
                    111:        (t1->class == PTR and t2 == t_nil)
                    112:     );
                    113:     return b;
                    114: }
                    115: 
                    116: private boolean enumMatch (t1, t2)
                    117: register Symbol t1, t2;
                    118: {
                    119:     boolean b;
                    120: 
                    121:     b = (boolean) (
                    122:        (t1->class == SCAL and t2->class == CONST and t2->type == t1) or
                    123:        (t1->class == CONST and t2->class == SCAL and t1->type == t2)
                    124:     );
                    125:     return b;
                    126: }
                    127: 
                    128: private boolean openArrayMatch (t1, t2)
                    129: register Symbol t1, t2;
                    130: {
                    131:     boolean b;
                    132: 
                    133:     b = (boolean) (
                    134:        (
                    135:            t1->class == OPENARRAY and t1->symvalue.ndims == 1 and
                    136:            t2->class == ARRAY and
                    137:            compatible(rtype(t2->chain)->type, t_int) and
                    138:            compatible(t1->type, t2->type)
                    139:        ) or (
                    140:            t2->class == OPENARRAY and t2->symvalue.ndims == 1 and
                    141:            t1->class == ARRAY and
                    142:            compatible(rtype(t1->chain)->type, t_int) and
                    143:            compatible(t1->type, t2->type)
                    144:        )
                    145:     );
                    146:     return b;
                    147: }
                    148: 
                    149: private boolean isConstString (t)
                    150: register Symbol t;
                    151: {
                    152:     boolean b;
                    153: 
                    154:     b = (boolean) (
                    155:        t->language == primlang and t->class == ARRAY and t->type == t_char
                    156:     );
                    157:     return b;
                    158: }
                    159: 
                    160: private boolean stringArrayMatch (t1, t2)
                    161: register Symbol t1, t2;
                    162: {
                    163:     boolean b;
                    164: 
                    165:     b = (boolean) (
                    166:        (
                    167:            isConstString(t1) and
                    168:            t2->class == ARRAY and compatible(t2->type, t_char->type)
                    169:        ) or (
                    170:            isConstString(t2) and
                    171:            t1->class == ARRAY and compatible(t1->type, t_char->type)
                    172:        )
                    173:     );
                    174:     return b;
                    175: }
                    176: 
                    177: public boolean modula2_typematch (type1, type2)
                    178: Symbol type1, type2;
                    179: {
                    180:     boolean b;
                    181:     Symbol t1, t2, tmp;
                    182: 
                    183:     t1 = rtype(type1);
                    184:     t2 = rtype(type2);
                    185:     if (t1 == t2) {
                    186:        b = true;
                    187:     } else {
                    188:        if (t1 == t_char->type or t1 == t_int->type or
                    189:            t1 == t_real->type or t1 == t_boolean->type
                    190:        ) {
                    191:            tmp = t1;
                    192:            t1 = t2;
                    193:            t2 = tmp;
                    194:        }
                    195:        b = (Boolean) (
                    196:            builtinmatch(t1, t2) or
                    197:            nilMatch(t1, t2) or enumMatch(t1, t2) or
                    198:            openArrayMatch(t1, t2) or stringArrayMatch(t1, t2)
                    199:        );
                    200:     }
                    201:     return b;
                    202: }
                    203: 
                    204: /*
                    205:  * Indent n spaces.
                    206:  */
                    207: 
                    208: private indent (n)
                    209: int n;
                    210: {
                    211:     if (n > 0) {
                    212:        printf("%*c", n, ' ');
                    213:     }
                    214: }
                    215: 
                    216: public modula2_printdecl (s)
                    217: Symbol s;
                    218: {
                    219:     register Symbol t;
                    220:     Boolean semicolon;
                    221: 
                    222:     semicolon = true;
                    223:     if (s->class == TYPEREF) {
                    224:        resolveRef(t);
                    225:     }
                    226:     switch (s->class) {
                    227:        case CONST:
                    228:            if (s->type->class == SCAL) {
                    229:                semicolon = false;
                    230:                printf("enumeration constant with value ");
                    231:                eval(s->symvalue.constval);
                    232:                modula2_printval(s);
                    233:            } else {
                    234:                printf("const %s = ", symname(s));
                    235:                eval(s->symvalue.constval);
                    236:                modula2_printval(s);
                    237:            }
                    238:            break;
                    239: 
                    240:        case TYPE:
                    241:            printf("type %s = ", symname(s));
                    242:            printtype(s, s->type, 0);
                    243:            break;
                    244: 
                    245:        case TYPEREF:
                    246:            printf("type %s", symname(s));
                    247:            break;
                    248: 
                    249:        case VAR:
                    250:            if (isparam(s)) {
                    251:                printf("(parameter) %s : ", symname(s));
                    252:            } else {
                    253:                printf("var %s : ", symname(s));
                    254:            }
                    255:            printtype(s, s->type, 0);
                    256:            break;
                    257: 
                    258:        case REF:
                    259:            printf("(var parameter) %s : ", symname(s));
                    260:            printtype(s, s->type, 0);
                    261:            break;
                    262: 
                    263:        case RANGE:
                    264:        case ARRAY:
                    265:        case OPENARRAY:
                    266:        case DYNARRAY:
                    267:        case SUBARRAY:
                    268:        case RECORD:
                    269:        case VARNT:
                    270:        case PTR:
                    271:            printtype(s, s, 0);
                    272:            semicolon = false;
                    273:            break;
                    274: 
                    275:        case FVAR:
                    276:            printf("(function variable) %s : ", symname(s));
                    277:            printtype(s, s->type, 0);
                    278:            break;
                    279: 
                    280:        case FIELD:
                    281:            printf("(field) %s : ", symname(s));
                    282:            printtype(s, s->type, 0);
                    283:            break;
                    284: 
                    285:        case PROC:
                    286:            printf("procedure %s", symname(s));
                    287:            listparams(s);
                    288:            break;
                    289: 
                    290:        case PROG:
                    291:            printf("program %s", symname(s));
                    292:            listparams(s);
                    293:            break;
                    294: 
                    295:        case FUNC:
                    296:            printf("procedure %s", symname(s));
                    297:            listparams(s);
                    298:            printf(" : ");
                    299:            printtype(s, s->type, 0);
                    300:            break;
                    301: 
                    302:        case MODULE:
                    303:            printf("module %s", symname(s));
                    304:            break;
                    305: 
                    306:        default:
                    307:            printf("[%s]", classname(s));
                    308:            break;
                    309:     }
                    310:     if (semicolon) {
                    311:        putchar(';');
                    312:     }
                    313:     putchar('\n');
                    314: }
                    315: 
                    316: /*
                    317:  * Recursive whiz-bang procedure to print the type portion
                    318:  * of a declaration.
                    319:  *
                    320:  * The symbol associated with the type is passed to allow
                    321:  * searching for type names without getting "type blah = blah".
                    322:  */
                    323: 
                    324: private printtype (s, t, n)
                    325: Symbol s;
                    326: Symbol t;
                    327: int n;
                    328: {
                    329:     Symbol tmp;
                    330:     int i;
                    331: 
                    332:     if (t->class == TYPEREF) {
                    333:        resolveRef(t);
                    334:     }
                    335:     switch (t->class) {
                    336:        case VAR:
                    337:        case CONST:
                    338:        case FUNC:
                    339:        case PROC:
                    340:            panic("printtype: class %s", classname(t));
                    341:            break;
                    342: 
                    343:        case ARRAY:
                    344:            printf("array[");
                    345:            tmp = t->chain;
                    346:            if (tmp != nil) {
                    347:                for (;;) {
                    348:                    printtype(tmp, tmp, n);
                    349:                    tmp = tmp->chain;
                    350:                    if (tmp == nil) {
                    351:                        break;
                    352:                    }
                    353:                    printf(", ");
                    354:                }
                    355:            }
                    356:            printf("] of ");
                    357:            printtype(t, t->type, n);
                    358:            break;
                    359: 
                    360:        case OPENARRAY:
                    361:            printf("array of ");
                    362:            for (i = 1; i < t->symvalue.ndims; i++) {
                    363:                printf("array of ");
                    364:            }
                    365:            printtype(t, t->type, n);
                    366:            break;
                    367: 
                    368:        case DYNARRAY:
                    369:            printf("dynarray of ");
                    370:            for (i = 1; i < t->symvalue.ndims; i++) {
                    371:                printf("array of ");
                    372:            }
                    373:            printtype(t, t->type, n);
                    374:            break;
                    375: 
                    376:        case SUBARRAY:
                    377:            printf("subarray of ");
                    378:            for (i = 1; i < t->symvalue.ndims; i++) {
                    379:                printf("array of ");
                    380:            }
                    381:            printtype(t, t->type, n);
                    382:            break;
                    383: 
                    384:        case RECORD:
                    385:            printRecordDecl(t, n);
                    386:            break;
                    387: 
                    388:        case FIELD:
                    389:            if (t->chain != nil) {
                    390:                printtype(t->chain, t->chain, n);
                    391:            }
                    392:            printf("\t%s : ", symname(t));
                    393:            printtype(t, t->type, n);
                    394:            printf(";\n");
                    395:            break;
                    396: 
                    397:        case RANGE:
                    398:            printRangeDecl(t);
                    399:            break;
                    400: 
                    401:        case PTR:
                    402:            printf("pointer to ");
                    403:            printtype(t, t->type, n);
                    404:            break;
                    405: 
                    406:        case TYPE:
                    407:            if (t->name != nil and ident(t->name)[0] != '\0') {
                    408:                printname(stdout, t);
                    409:            } else {
                    410:                printtype(t, t->type, n);
                    411:            }
                    412:            break;
                    413: 
                    414:        case SCAL:
                    415:            printEnumDecl(t, n);
                    416:            break;
                    417: 
                    418:        case SET:
                    419:            printf("set of ");
                    420:            printtype(t, t->type, n);
                    421:            break;
                    422: 
                    423:        case TYPEREF:
                    424:            break;
                    425: 
                    426:        case FPROC:
                    427:        case FFUNC:
                    428:            printf("procedure");
                    429:            break;
                    430: 
                    431:        default:
                    432:            printf("[%s]", classname(t));
                    433:            break;
                    434:     }
                    435: }
                    436: 
                    437: /*
                    438:  * Print out a record declaration.
                    439:  */
                    440: 
                    441: private printRecordDecl (t, n)
                    442: Symbol t;
                    443: int n;
                    444: {
                    445:     register Symbol f;
                    446: 
                    447:     if (t->chain == nil) {
                    448:        printf("record end");
                    449:     } else {
                    450:        printf("record\n");
                    451:        for (f = t->chain; f != nil; f = f->chain) {
                    452:            indent(n+4);
                    453:            printf("%s : ", symname(f));
                    454:            printtype(f->type, f->type, n+4);
                    455:            printf(";\n");
                    456:        }
                    457:        indent(n);
                    458:        printf("end");
                    459:     }
                    460: }
                    461: 
                    462: /*
                    463:  * Print out the declaration of a range type.
                    464:  */
                    465: 
                    466: private printRangeDecl (t)
                    467: Symbol t;
                    468: {
                    469:     long r0, r1;
                    470: 
                    471:     r0 = t->symvalue.rangev.lower;
                    472:     r1 = t->symvalue.rangev.upper;
                    473:     if (ischar(t)) {
                    474:        if (r0 < 0x20 or r0 > 0x7e) {
                    475:            printf("%ld..", r0);
                    476:        } else {
                    477:            printf("'%c'..", (char) r0);
                    478:        }
                    479:        if (r1 < 0x20 or r1 > 0x7e) {
                    480:            printf("\\%lo", r1);
                    481:        } else {
                    482:            printf("'%c'", (char) r1);
                    483:        }
                    484:     } else if (r0 > 0 and r1 == 0) {
                    485:        printf("%ld byte real", r0);
                    486:     } else if (r0 >= 0) {
                    487:        printf("%lu..%lu", r0, r1);
                    488:     } else {
                    489:        printf("%ld..%ld", r0, r1);
                    490:     }
                    491: }
                    492: 
                    493: /*
                    494:  * Print out an enumeration declaration.
                    495:  */
                    496: 
                    497: private printEnumDecl (e, n)
                    498: Symbol e;
                    499: int n;
                    500: {
                    501:     Symbol t;
                    502: 
                    503:     printf("(");
                    504:     t = e->chain;
                    505:     if (t != nil) {
                    506:        printf("%s", symname(t));
                    507:        t = t->chain;
                    508:        while (t != nil) {
                    509:            printf(", %s", symname(t));
                    510:            t = t->chain;
                    511:        }
                    512:     }
                    513:     printf(")");
                    514: }
                    515: 
                    516: /*
                    517:  * List the parameters of a procedure or function.
                    518:  * No attempt is made to combine like types.
                    519:  */
                    520: 
                    521: private listparams (s)
                    522: Symbol s;
                    523: {
                    524:     Symbol t;
                    525: 
                    526:     if (s->chain != nil) {
                    527:        putchar('(');
                    528:        for (t = s->chain; t != nil; t = t->chain) {
                    529:            switch (t->class) {
                    530:                case REF:
                    531:                    printf("var ");
                    532:                    break;
                    533: 
                    534:                case FPROC:
                    535:                case FFUNC:
                    536:                    printf("procedure ");
                    537:                    break;
                    538: 
                    539:                case VAR:
                    540:                    break;
                    541: 
                    542:                default:
                    543:                    panic("unexpected class %d for parameter", t->class);
                    544:            }
                    545:            printf("%s", symname(t));
                    546:            if (s->class == PROG) {
                    547:                printf(", ");
                    548:            } else {
                    549:                printf(" : ");
                    550:                printtype(t, t->type, 0);
                    551:                if (t->chain != nil) {
                    552:                    printf("; ");
                    553:                }
                    554:            }
                    555:        }
                    556:        putchar(')');
                    557:     }
                    558: }
                    559: 
                    560: /*
                    561:  * Test if a pointer type should be treated as a null-terminated string.
                    562:  * The type given is the type that is pointed to.
                    563:  */
                    564: 
                    565: private boolean isCstring (type)
                    566: Symbol type;
                    567: {
                    568:     boolean b;
                    569:     register Symbol a, t;
                    570: 
                    571:     a = rtype(type);
                    572:     if (a->class == ARRAY) {
                    573:        t = rtype(a->chain);
                    574:        b = (boolean) (
                    575:            t->class == RANGE and istypename(a->type, "char") and
                    576:            (t->symvalue.rangev.upper - t->symvalue.rangev.lower + 1) <= 0
                    577:        );
                    578:     } else {
                    579:        b = false;
                    580:     }
                    581:     return b;
                    582: }
                    583: 
                    584: /*
                    585:  * Modula 2 interface to printval.
                    586:  */
                    587: 
                    588: public modula2_printval (s)
                    589: Symbol s;
                    590: {
                    591:     prval(s, size(s));
                    592: }
                    593: 
                    594: /*
                    595:  * Print out the value on the top of the expression stack
                    596:  * in the format for the type of the given symbol, assuming
                    597:  * the size of the object is n bytes.
                    598:  */
                    599: 
                    600: private prval (s, n)
                    601: Symbol s;
                    602: integer n;
                    603: {
                    604:     Symbol t;
                    605:     Address a;
                    606:     integer len;
                    607:     double r;
                    608:     integer i;
                    609: 
                    610:     if (s->class == TYPEREF) {
                    611:        resolveRef(s);
                    612:     }
                    613:     switch (s->class) {
                    614:        case CONST:
                    615:        case TYPE:
                    616:        case REF:
                    617:        case VAR:
                    618:        case FVAR:
                    619:        case TAG:
                    620:            prval(s->type, n);
                    621:            break;
                    622: 
                    623:        case FIELD:
                    624:            if (isbitfield(s)) {
                    625:                i = extractField(s);
                    626:                t = rtype(s->type);
                    627:                if (t->class == SCAL) {
                    628:                    printEnum(i, t);
                    629:                } else {
                    630:                    printRangeVal(i, t);
                    631:                }
                    632:            } else {
                    633:                prval(s->type, n);
                    634:            }
                    635:            break;
                    636: 
                    637:        case ARRAY:
                    638:            t = rtype(s->type);
                    639:            if (ischar(t)) {
                    640:                len = size(s);
                    641:                sp -= len;
                    642:                printf("\"%.*s\"", len, sp);
                    643:                break;
                    644:            } else {
                    645:                printarray(s);
                    646:            }
                    647:            break;
                    648: 
                    649:        case OPENARRAY:
                    650:        case DYNARRAY:
                    651:            printDynarray(s);
                    652:            break;
                    653: 
                    654:        case SUBARRAY:
                    655:            printSubarray(s);
                    656:            break;
                    657: 
                    658:        case RECORD:
                    659:            printrecord(s);
                    660:            break;
                    661: 
                    662:        case VARNT:
                    663:            printf("[variant]");
                    664:            break;
                    665: 
                    666:        case RANGE:
                    667:            printrange(s, n);
                    668:            break;
                    669: 
                    670:        /*
                    671:         * Unresolved opaque type.
                    672:         * Probably a pointer.
                    673:         */
                    674:        case TYPEREF:
                    675:            a = pop(Address);
                    676:            printf("@%x", a);
                    677:            break;
                    678: 
                    679:        case FILET:
                    680:            a = pop(Address);
                    681:            if (a == 0) {
                    682:                printf("nil");
                    683:            } else {
                    684:                printf("0x%x", a);
                    685:            }
                    686:            break;
                    687: 
                    688:        case PTR:
                    689:            a = pop(Address);
                    690:            if (a == 0) {
                    691:                printf("nil");
                    692:            } else if (isCstring(s->type)) {
                    693:                printString(a, true);
                    694:            } else {
                    695:                printf("0x%x", a);
                    696:            }
                    697:            break;
                    698: 
                    699:        case SCAL:
                    700:            i = 0;
                    701:            popn(n, &i);
                    702:            printEnum(i, s);
                    703:            break;
                    704: 
                    705:        case FPROC:
                    706:        case FFUNC:
                    707:            a = pop(long);
                    708:            t = whatblock(a);
                    709:            if (t == nil) {
                    710:                printf("0x%x", a);
                    711:            } else {
                    712:                printname(stdout, t);
                    713:            }
                    714:            break;
                    715: 
                    716:        case SET:
                    717:            printSet(s);
                    718:            break;
                    719: 
                    720:        default:
                    721:            if (ord(s->class) < ord(BADUSE) or ord(s->class) > ord(TYPEREF)) {
                    722:                panic("printval: bad class %d", ord(s->class));
                    723:            }
                    724:            printf("[%s]", classname(s));
                    725:            break;
                    726:     }
                    727: }
                    728: 
                    729: /*
                    730:  * Print out a dynamic array.
                    731:  */
                    732: 
                    733: private Address printDynSlice();
                    734: 
                    735: private printDynarray (t)
                    736: Symbol t;
                    737: {
                    738:     Address base;
                    739:     integer n;
                    740:     Stack *savesp, *newsp;
                    741:     Symbol eltype;
                    742: 
                    743:     savesp = sp;
                    744:     sp -= (t->symvalue.ndims * sizeof(Word));
                    745:     base = pop(Address);
                    746:     newsp = sp;
                    747:     sp = savesp;
                    748:     eltype = rtype(t->type);
                    749:     if (t->symvalue.ndims == 0) {
                    750:        if (ischar(eltype)) {
                    751:            printString(base, true);
                    752:        } else {
                    753:            printf("[dynarray @nocount]");
                    754:        }
                    755:     } else {
                    756:        n = ((long *) sp)[-(t->symvalue.ndims)];
                    757:        base = printDynSlice(base, n, t->symvalue.ndims, eltype, size(eltype));
                    758:     }
                    759:     sp = newsp;
                    760: }
                    761: 
                    762: /*
                    763:  * Print out one dimension of a multi-dimension dynamic array.
                    764:  *
                    765:  * Return the address of the element that follows the printed elements.
                    766:  */
                    767: 
                    768: private Address printDynSlice (base, count, ndims, eltype, elsize)
                    769: Address base;
                    770: integer count, ndims;
                    771: Symbol eltype;
                    772: integer elsize;
                    773: {
                    774:     Address b;
                    775:     integer i, n;
                    776:     char *slice;
                    777:     Stack *savesp;
                    778: 
                    779:     b = base;
                    780:     if (ndims > 1) {
                    781:        n = ((long *) sp)[-ndims + 1];
                    782:     }
                    783:     if (ndims == 1 and ischar(eltype)) {
                    784:        slice = newarr(char, count);
                    785:        dread(slice, b, count);
                    786:        printf("\"%.*s\"", count, slice);
                    787:        dispose(slice);
                    788:        b += count;
                    789:     } else {
                    790:        printf("(");
                    791:        for (i = 0; i < count; i++) {
                    792:            if (i != 0) {
                    793:                printf(", ");
                    794:            }
                    795:            if (ndims == 1) {
                    796:                slice = newarr(char, elsize);
                    797:                dread(slice, b, elsize);
                    798:                savesp = sp;
                    799:                sp = slice + elsize;
                    800:                printval(eltype);
                    801:                sp = savesp;
                    802:                dispose(slice);
                    803:                b += elsize;
                    804:            } else {
                    805:                b = printDynSlice(b, n, ndims - 1, eltype, elsize);
                    806:            }
                    807:        }
                    808:        printf(")");
                    809:     }
                    810:     return b;
                    811: }
                    812: 
                    813: private printSubarray (t)
                    814: Symbol t;
                    815: {
                    816:     printf("[subarray]");
                    817: }
                    818: 
                    819: /*
                    820:  * Print out the value of a scalar (non-enumeration) type.
                    821:  */
                    822: 
                    823: private printrange (s, n)
                    824: Symbol s;
                    825: integer n;
                    826: {
                    827:     double d;
                    828:     float f;
                    829:     integer i;
                    830: 
                    831:     if (s->symvalue.rangev.upper == 0 and s->symvalue.rangev.lower > 0) {
                    832:        if (n == sizeof(float)) {
                    833:            popn(n, &f);
                    834:            d = f;
                    835:        } else {
                    836:            popn(n, &d);
                    837:        }
                    838:        prtreal(d);
                    839:     } else {
                    840:        i = 0;
                    841:        popn(n, &i);
                    842:        printRangeVal(i, s);
                    843:     }
                    844: }
                    845: 
                    846: /*
                    847:  * Print out a set.
                    848:  */
                    849: 
                    850: private printSet (s)
                    851: Symbol s;
                    852: {
                    853:     Symbol t;
                    854:     integer nbytes;
                    855: 
                    856:     nbytes = size(s);
                    857:     t = rtype(s->type);
                    858:     printf("{");
                    859:     sp -= nbytes;
                    860:     if (t->class == SCAL) {
                    861:        printSetOfEnum(t);
                    862:     } else if (t->class == RANGE) {
                    863:        printSetOfRange(t);
                    864:     } else {
                    865:        panic("expected range or enumerated base type for set");
                    866:     }
                    867:     printf("}");
                    868: }
                    869: 
                    870: /*
                    871:  * Print out a set of an enumeration.
                    872:  */
                    873: 
                    874: private printSetOfEnum (t)
                    875: Symbol t;
                    876: {
                    877:     register Symbol e;
                    878:     register integer i, j, *p;
                    879:     boolean first;
                    880: 
                    881:     p = (int *) sp;
                    882:     i = *p;
                    883:     j = 0;
                    884:     e = t->chain;
                    885:     first = true;
                    886:     while (e != nil) {
                    887:        if ((i&1) == 1) {
                    888:            if (first) {
                    889:                first = false;
                    890:                printf("%s", symname(e));
                    891:            } else {
                    892:                printf(", %s", symname(e));
                    893:            }
                    894:        }
                    895:        i >>= 1;
                    896:        ++j;
                    897:        if (j >= sizeof(integer)*BITSPERBYTE) {
                    898:            j = 0;
                    899:            ++p;
                    900:            i = *p;
                    901:        }
                    902:        e = e->chain;
                    903:     }
                    904: }
                    905: 
                    906: /*
                    907:  * Print out a set of a subrange type.
                    908:  */
                    909: 
                    910: private printSetOfRange (t)
                    911: Symbol t;
                    912: {
                    913:     register integer i, j, *p;
                    914:     long v;
                    915:     boolean first;
                    916: 
                    917:     p = (int *) sp;
                    918:     i = *p;
                    919:     j = 0;
                    920:     v = t->symvalue.rangev.lower;
                    921:     first = true;
                    922:     while (v <= t->symvalue.rangev.upper) {
                    923:        if ((i&1) == 1) {
                    924:            if (first) {
                    925:                first = false;
                    926:                printf("%ld", v);
                    927:            } else {
                    928:                printf(", %ld", v);
                    929:            }
                    930:        }
                    931:        i >>= 1;
                    932:        ++j;
                    933:        if (j >= sizeof(integer)*BITSPERBYTE) {
                    934:            j = 0;
                    935:            ++p;
                    936:            i = *p;
                    937:        }
                    938:        ++v;
                    939:     }
                    940: }
                    941: 
                    942: /*
                    943:  * Construct a node for subscripting a dynamic or subarray.
                    944:  * The list of indices is left for processing in evalaref,
                    945:  * unlike normal subscripting in which the list is expanded
                    946:  * across individual INDEX nodes.
                    947:  */
                    948: 
                    949: private Node dynref (a, t, slist)
                    950: Node a;
                    951: Symbol t;
                    952: Node slist;
                    953: {
                    954:     Node p, r;
                    955:     integer n;
                    956: 
                    957:     p = slist;
                    958:     n = 0;
                    959:     while (p != nil) {
                    960:        if (not compatible(p->value.arg[0]->nodetype, t_int)) {
                    961:            suberror("subscript \"", p->value.arg[0], "\" is the wrong type");
                    962:        }
                    963:        ++n;
                    964:        p = p->value.arg[1];
                    965:     }
                    966:     if (n > t->symvalue.ndims and (t->symvalue.ndims != 0 or n != 1)) {
                    967:        suberror("too many subscripts for ", a, nil);
                    968:     } else if (n < t->symvalue.ndims) {
                    969:        suberror("not enough subscripts for ", a, nil);
                    970:     }
                    971:     r = build(O_INDEX, a, slist);
                    972:     r->nodetype = rtype(t->type);
                    973:     return r;
                    974: }
                    975: 
                    976: /*
                    977:  * Construct a node for subscripting.
                    978:  */
                    979: 
                    980: public Node modula2_buildaref (a, slist)
                    981: Node a, slist;
                    982: {
                    983:     register Symbol t;
                    984:     register Node p;
                    985:     Symbol eltype;
                    986:     Node esub, r;
                    987:     integer n;
                    988: 
                    989:     t = rtype(a->nodetype);
                    990:     switch (t->class) {
                    991:        case OPENARRAY:
                    992:        case DYNARRAY:
                    993:        case SUBARRAY:
                    994:            r = dynref(a, t, slist);
                    995:            break;
                    996: 
                    997:        case ARRAY:
                    998:            r = a;
                    999:            eltype = rtype(t->type);
                   1000:            p = slist;
                   1001:            t = t->chain;
                   1002:            while (p != nil and t != nil) {
                   1003:                esub = p->value.arg[0];
                   1004:                if (not compatible(rtype(t), rtype(esub->nodetype))) {
                   1005:                    suberror("subscript \"", esub, "\" is the wrong type");
                   1006:                }
                   1007:                r = build(O_INDEX, r, esub);
                   1008:                r->nodetype = eltype;
                   1009:                p = p->value.arg[1];
                   1010:                t = t->chain;
                   1011:            }
                   1012:            if (p != nil) {
                   1013:                suberror("too many subscripts for ", a, nil);
                   1014:            } else if (t != nil) {
                   1015:                suberror("not enough subscripts for ", a, nil);
                   1016:            }
                   1017:            break;
                   1018: 
                   1019:        default:
                   1020:            suberror("\"", a, "\" is not an array");
                   1021:            break;
                   1022:     }
                   1023:     return r;
                   1024: }
                   1025: 
                   1026: /*
                   1027:  * Subscript usage error reporting.
                   1028:  */
                   1029: 
                   1030: private suberror (s1, e1, s2)
                   1031: String s1, s2;
                   1032: Node e1;
                   1033: {
                   1034:     beginerrmsg();
                   1035:     if (s1 != nil) {
                   1036:        fprintf(stderr, s1);
                   1037:     }
                   1038:     if (e1 != nil) {
                   1039:        prtree(stderr, e1);
                   1040:     }
                   1041:     if (s2 != nil) {
                   1042:        fprintf(stderr, s2);
                   1043:     }
                   1044:     enderrmsg();
                   1045: }
                   1046: 
                   1047: /*
                   1048:  * Check that a subscript value is in the appropriate range.
                   1049:  */
                   1050: 
                   1051: private subchk (value, lower, upper)
                   1052: long value, lower, upper;
                   1053: {
                   1054:     if (value < lower or value > upper) {
                   1055:        error("subscript value %d out of range [%d..%d]", value, lower, upper);
                   1056:     }
                   1057: }
                   1058: 
                   1059: /*
                   1060:  * Compute the offset for subscripting a dynamic array.
                   1061:  */
                   1062: 
                   1063: private getdynoff (ndims, sub)
                   1064: integer ndims;
                   1065: long *sub;
                   1066: {
                   1067:     long k, off, *count;
                   1068: 
                   1069:     count = (long *) sp;
                   1070:     off = 0;
                   1071:     for (k = 0; k < ndims - 1; k++) {
                   1072:        subchk(sub[k], 0, count[k] - 1);
                   1073:        off += (sub[k] * count[k+1]);
                   1074:     }
                   1075:     subchk(sub[ndims - 1], 0, count[ndims - 1] - 1);
                   1076:     return off + sub[ndims - 1];
                   1077: }
                   1078: 
                   1079: /*
                   1080:  * Compute the offset associated with a subarray.
                   1081:  */
                   1082: 
                   1083: private getsuboff (ndims, sub)
                   1084: integer ndims;
                   1085: long *sub;
                   1086: {
                   1087:     long k, off;
                   1088:     struct subarrayinfo {
                   1089:        long count;
                   1090:        long mult;
                   1091:     } *info;
                   1092: 
                   1093:     info = (struct subarrayinfo *) sp;
                   1094:     off = 0;
                   1095:     for (k = 0; k < ndims; k++) {
                   1096:        subchk(sub[k], 0, info[k].count - 1);
                   1097:        off += sub[k] * info[k].mult;
                   1098:     }
                   1099:     return off;
                   1100: }
                   1101: 
                   1102: /*
                   1103:  * Evaluate a subscript index.
                   1104:  */
                   1105: 
                   1106: public modula2_evalaref (s, base, i)
                   1107: Symbol s;
                   1108: Address base;
                   1109: long i;
                   1110: {
                   1111:     Symbol t;
                   1112:     long lb, ub, off;
                   1113:     long *sub;
                   1114:     Address b;
                   1115: 
                   1116:     t = rtype(s);
                   1117:     if (t->class == ARRAY) {
                   1118:        findbounds(rtype(t->chain), &lb, &ub);
                   1119:        if (i < lb or i > ub) {
                   1120:            error("subscript %d out of range [%d..%d]", i, lb, ub);
                   1121:        }
                   1122:        push(long, base + (i - lb) * size(t->type));
                   1123:     } else if ((t->class == OPENARRAY or t->class == DYNARRAY) and
                   1124:        t->symvalue.ndims == 0
                   1125:     ) {
                   1126:        push(long, base + i * size(t->type));
                   1127:     } else if (t->class == OPENARRAY or t->class == DYNARRAY or
                   1128:        t->class == SUBARRAY
                   1129:     ) {
                   1130:        push(long, i);
                   1131:        sub = (long *) (sp - (t->symvalue.ndims * sizeof(long)));
                   1132:        rpush(base, size(t));
                   1133:        sp -= (t->symvalue.ndims * sizeof(long));
                   1134:        b = pop(Address);
                   1135:        sp += sizeof(Address);
                   1136:        if (t->class == SUBARRAY) {
                   1137:            off = getsuboff(t->symvalue.ndims, sub);
                   1138:        } else {
                   1139:            off = getdynoff(t->symvalue.ndims, sub);
                   1140:        }
                   1141:        sp = (Stack *) sub;
                   1142:        push(long, b + off * size(t->type));
                   1143:     } else {
                   1144:        error("[internal error: expected array in evalaref]");
                   1145:     }
                   1146: }
                   1147: 
                   1148: /*
                   1149:  * Initial Modula-2 type information.
                   1150:  */
                   1151: 
                   1152: #define NTYPES 12
                   1153: 
                   1154: private Symbol inittype[NTYPES + 1];
                   1155: 
                   1156: private addType (n, s, lower, upper)
                   1157: integer n;
                   1158: String s;
                   1159: long lower, upper;
                   1160: {
                   1161:     register Symbol t;
                   1162: 
                   1163:     if (n > NTYPES) {
                   1164:        panic("initial Modula-2 type number too large for '%s'", s);
                   1165:     }
                   1166:     t = insert(identname(s, true));
                   1167:     t->language = mod2;
                   1168:     t->class = TYPE;
                   1169:     t->type = newSymbol(nil, 0, RANGE, t, nil);
                   1170:     t->type->symvalue.rangev.lower = lower;
                   1171:     t->type->symvalue.rangev.upper = upper;
                   1172:     t->type->language = mod2;
                   1173:     inittype[n] = t;
                   1174: }
                   1175: 
                   1176: private initModTypes ()
                   1177: {
                   1178:     addType(1, "integer", 0x80000000L, 0x7fffffffL);
                   1179:     addType(2, "char", 0L, 255L);
                   1180:     addType(3, "boolean", 0L, 1L);
                   1181:     addType(4, "unsigned", 0L, 0xffffffffL);
                   1182:     addType(5, "real", 4L, 0L);
                   1183:     addType(6, "longreal", 8L, 0L);
                   1184:     addType(7, "word", 0L, 0xffffffffL);
                   1185:     addType(8, "byte", 0L, 255L);
                   1186:     addType(9, "address", 0L, 0xffffffffL);
                   1187:     addType(10, "file", 0L, 0xffffffffL);
                   1188:     addType(11, "process", 0L, 0xffffffffL);
                   1189:     addType(12, "cardinal", 0L, 0x7fffffffL);
                   1190: }
                   1191: 
                   1192: /*
                   1193:  * Initialize typetable.
                   1194:  */
                   1195: 
                   1196: public modula2_modinit (typetable)
                   1197: Symbol typetable[];
                   1198: {
                   1199:     register integer i;
                   1200: 
                   1201:     if (not initialized) {
                   1202:        initModTypes();
                   1203:        initialized = true;
                   1204:     }
                   1205:     for (i = 1; i <= NTYPES; i++) {
                   1206:        typetable[i] = inittype[i];
                   1207:     }
                   1208: }
                   1209: 
                   1210: public boolean modula2_hasmodules ()
                   1211: {
                   1212:     return true;
                   1213: }
                   1214: 
                   1215: public boolean modula2_passaddr (param, exprtype)
                   1216: Symbol param, exprtype;
                   1217: {
                   1218:     return false;
                   1219: }

unix.superglobalmegacorp.com

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