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