Annotation of 43BSD/ucb/dbx/modula-2.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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