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

unix.superglobalmegacorp.com

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