Annotation of 43BSDReno/pgrm/dbx/modula-2.c, revision 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.