Annotation of 40BSD/cmd/pxp/nl.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1979 Regents of the University of California */
                      2: #
                      3: /*
                      4:  * pi - Pascal interpreter code translator
                      5:  *
                      6:  * Charles Haley, Bill Joy UCB
                      7:  * Version 1.2 January 1979
                      8:  */
                      9: 
                     10: #include "0.h"
                     11: #include "opcode.h"
                     12: 
                     13: #ifdef PI
                     14: /*
                     15:  * Array of information about pre-defined, block 0 symbols.
                     16:  */
                     17: int    *biltins[] {
                     18: 
                     19:        /*
                     20:         * Types
                     21:         */
                     22:        "boolean",
                     23:        "char",
                     24:        "integer",
                     25:        "real",
                     26:        "_nil",         /* dummy name */
                     27:        0,
                     28: 
                     29:        /*
                     30:         * Ranges
                     31:         */
                     32:        TINT,           0177777, 0177600, 0, 0177,
                     33:        TINT,           0177777, 0100000, 0, 077777,
                     34:        TINT,           0100000, 0, 077777, 0177777,
                     35:        TCHAR,          0, 0, 0, 127,
                     36:        TBOOL,          0, 0, 0, 1,
                     37:        TDOUBLE,        0, 0, 0, 0,             /* fake for reals */
                     38:        0,
                     39: 
                     40:        /*
                     41:         * Built-in composite types
                     42:         */
                     43:        "Boolean",
                     44:        "intset",
                     45:        "alfa",
                     46:        "text",
                     47:        "input", 
                     48:        "output", 
                     49: 
                     50:        /*
                     51:         * Built-in constants
                     52:         */
                     53:        "true",         TBOOL,  1, 0,
                     54:        "false",        TBOOL,  0, 0,
                     55:        "minchar",      T1CHAR, 0, 0,
                     56:        "maxchar",      T1CHAR, 0177, 0,
                     57:        "bell",         T1CHAR, 07, 0,
                     58:        "tab",          T1CHAR, 011, 0,
                     59:        "minint",       T4INT,  0100000, 0,             /* Must be last 2! */
                     60:        "maxint",       T4INT,  077777, 0177777,
                     61:        0,
                     62: 
                     63:        /*
                     64:         * Built-in functions
                     65:         */
                     66: #ifndef PI0
                     67:        "abs",          O_ABS2,
                     68:        "arctan",       O_ATAN,
                     69:        "card",         O_CARD|NSTAND,
                     70:        "chr",          O_CHR2,
                     71:        "clock",        O_CLCK|NSTAND,
                     72:        "cos",          O_COS,
                     73:        "eof",          O_EOF,
                     74:        "eoln",         O_EOLN,
                     75:        "eos",          0,
                     76:        "exp",          O_EXP,
                     77:        "expo",         O_EXPO|NSTAND,
                     78:        "ln",           O_LN,
                     79:        "odd",          O_ODD2,
                     80:        "ord",          O_ORD2,
                     81:        "pred",         O_PRED2,
                     82:        "round",        O_ROUND,
                     83:        "sin",          O_SIN,
                     84:        "sqr",          O_SQR2,
                     85:        "sqrt",         O_SQRT,
                     86:        "succ",         O_SUCC2,
                     87:        "trunc",        O_TRUNC,
                     88:        "undefined",    O_UNDEF|NSTAND,
                     89:        /*
                     90:         * Extensions
                     91:         */
                     92:        "argc",         O_ARGC|NSTAND,
                     93:        "random",       O_RANDOM|NSTAND,
                     94:        "seed",         O_SEED|NSTAND,
                     95:        "wallclock",    O_WCLCK|NSTAND,
                     96:        "sysclock",     O_SCLCK|NSTAND,
                     97:        0,
                     98: 
                     99:        /*
                    100:         * Built-in procedures
                    101:         */
                    102:        "date",         O_DATE|NSTAND,
                    103:        "flush",        O_FLUSH|NSTAND,
                    104:        "get",          O_GET,
                    105:        "getseg",       0,
                    106:        "halt",         O_HALT|NSTAND,
                    107:        "linelimit",    O_LLIMIT|NSTAND,
                    108:        "message",      O_MESSAGE|NSTAND,
                    109:        "new",          O_NEW,
                    110:        "pack",         O_PACK,
                    111:        "page",         O_PAGE,
                    112:        "put",          O_PUT,
                    113:        "putseg",       0,
                    114:        "read",         O_READ4,
                    115:        "readln",       O_READLN,
                    116:        "remove",       O_REMOVE|NSTAND,
                    117:        "reset",        O_RESET,
                    118:        "rewrite",      O_REWRITE,
                    119:        "time",         O_TIME|NSTAND,
                    120:        "unpack",       O_UNPACK,
                    121:        "write",        O_WRIT2,
                    122:        "writeln",      O_WRITLN,
                    123:        /*
                    124:         * Extensions
                    125:         */
                    126:        "argv",         O_ARGV|NSTAND,
                    127:        "null",         O_NULL|NSTAND,
                    128:        "stlimit",      O_STLIM|NSTAND,
                    129:        0,
                    130: #else
                    131:        "abs",
                    132:        "arctan",
                    133:        "card",
                    134:        "chr",
                    135:        "clock",
                    136:        "cos",
                    137:        "eof",
                    138:        "eoln",
                    139:        "eos",
                    140:        "exp",
                    141:        "expo",
                    142:        "ln",
                    143:        "odd",
                    144:        "ord",
                    145:        "pred",
                    146:        "round",
                    147:        "sin",
                    148:        "sqr",
                    149:        "sqrt",
                    150:        "succ",
                    151:        "trunc",
                    152:        "undefined",
                    153:        /*
                    154:         * Extensions
                    155:         */
                    156:        "argc",
                    157:        "random",
                    158:        "seed",
                    159:        "wallclock",
                    160:        "sysclock",
                    161:        0,
                    162: 
                    163:        /*
                    164:         * Built-in procedures
                    165:         */
                    166:        "date",
                    167:        "flush",
                    168:        "get",
                    169:        "getseg",
                    170:        "halt",
                    171:        "linelimit",
                    172:        "message",
                    173:        "new",
                    174:        "pack",
                    175:        "page",
                    176:        "put",
                    177:        "putseg",
                    178:        "read",
                    179:        "readln",
                    180:        "remove",
                    181:        "reset",
                    182:        "rewrite",
                    183:        "time",
                    184:        "unpack",
                    185:        "write",
                    186:        "writeln",
                    187:        /*
                    188:         * Extensions
                    189:         */
                    190:        "argv",
                    191:        "null",
                    192:        "stlimit",
                    193:        0,
                    194: #endif
                    195: };
                    196: 
                    197: /*
                    198:  * NAMELIST SEGMENT DEFINITIONS
                    199:  */
                    200: struct nls {
                    201:        struct nl *nls_low;
                    202:        struct nl *nls_high;
                    203: } ntab[MAXNL], *nlact;
                    204: 
                    205: struct nl nl[INL];
                    206: struct nl *nlp nl;
                    207: struct nls *nlact ntab;
                    208: /*
                    209:  * Initnl initializes the first namelist segment and then
                    210:  * uses the array biltins to initialize the name list for
                    211:  * block 0.
                    212:  */
                    213: initnl()
                    214: {
                    215:        register int *q;
                    216:        register struct nl *p;
                    217:        register int i;
                    218: 
                    219: #ifdef DEBUG
                    220:        if (hp21mx) {
                    221:                MININT = -32768.;
                    222:                MAXINT = 32767.;
                    223: #ifndef PI0
                    224:                genmx();
                    225: #endif
                    226:        }
                    227: #endif
                    228:        ntab[0].nls_low = nl;
                    229:        ntab[0].nls_high = &nl[INL];
                    230:        defnl(0, 0, 0, 0);
                    231:        /*
                    232:         * Fundamental types
                    233:         */
                    234:        for (q = biltins; *q != 0; q++)
                    235:                hdefnl(*q, TYPE, nlp, 0);
                    236:        q++;
                    237: 
                    238:        /*
                    239:         * Ranges
                    240:         */
                    241:        while (*q) {
                    242:                p = defnl(0, RANGE, nl+*q, 0);
                    243:                nl[*q++].type = p;
                    244:                for (i = 0; i < 4; i++)
                    245:                        p->value[i] = *q++;
                    246:        }
                    247:        q++;
                    248: 
                    249: #ifdef DEBUG
                    250:        if (hp21mx) {
                    251:                nl[T4INT].range[0] = MININT;
                    252:                nl[T4INT].range[1] = MAXINT;
                    253:        }
                    254: #endif
                    255: 
                    256:        /*
                    257:         * Pre-defined composite types
                    258:         */
                    259:        hdefnl(*q++, TYPE, nl+T1BOOL, 0);
                    260:        enter(defnl((intset = *q++), TYPE, nlp+1, 0));
                    261:        defnl(0, SET, nlp+1, 0);
                    262:        defnl(0, RANGE, nl+TINT, 0)->value[3] = 127;
                    263:      p=        defnl(0, RANGE, nl+TINT, 0);
                    264:        p->value[1] = 1;
                    265:        p->value[3] = 10;
                    266:        defnl(0, ARRAY, nl+T1CHAR, 1)->chain = p;
                    267:        hdefnl(*q++, TYPE, nlp-1, 0);   /* "alfa" */
                    268:        hdefnl(*q++, TYPE, nlp+1, 0);   /* "text" */
                    269:      p=        defnl(0, FILE, nl+T1CHAR, 0);
                    270:        p->nl_flags =| NFILES;
                    271: #ifndef PI0
                    272:        input = hdefnl(*q++, VAR, p, -2);       /* "input" */
                    273:        output = hdefnl(*q++, VAR, p, -4);      /* "output" */
                    274: #else
                    275:        input = hdefnl(*q++, VAR, p, 0);        /* "input" */
                    276:        output = hdefnl(*q++, VAR, p, 0);       /* "output" */
                    277: #endif
                    278: 
                    279:        /*
                    280:         * Pre-defined constants
                    281:         */
                    282:        for (; *q; q =+ 4)
                    283:                hdefnl(q[0], CONST, nl+q[1], q[2])->value[1] = q[3];
                    284: 
                    285: #ifdef DEBUG
                    286:        if (hp21mx) {
                    287:                nlp[-2].range[0] = MININT;
                    288:                nlp[-1].range[0] = MAXINT;
                    289:        }
                    290: #endif
                    291: 
                    292:        /*
                    293:         * Built-in procedures and functions
                    294:         */
                    295: #ifndef PI0
                    296:        for (q++; *q; q =+ 2)
                    297:                hdefnl(q[0], FUNC, 0, q[1]);
                    298:        for (q++; *q; q =+ 2)
                    299:                hdefnl(q[0], PROC, 0, q[1]);
                    300: #else
                    301:        for (q++; *q;)
                    302:                hdefnl(*q++, FUNC, 0, 0);
                    303:        for (q++; *q;)
                    304:                hdefnl(*q++, PROC, 0, 0);
                    305: #endif
                    306: }
                    307: 
                    308: hdefnl(sym, cls, typ, val)
                    309: {
                    310:        register struct nl *p;
                    311: 
                    312: #ifndef PI1
                    313:        if (sym)
                    314:                hash(sym, 0);
                    315: #endif
                    316:        p = defnl(sym, cls, typ, val);
                    317:        if (sym)
                    318:                enter(p);
                    319:        return (p);
                    320: }
                    321: 
                    322: /*
                    323:  * Free up the name list segments
                    324:  * at the end of a statement/proc/func
                    325:  * All segments are freed down to the one in which
                    326:  * p points.
                    327:  */
                    328: nlfree(p)
                    329:        struct nl *p;
                    330: {
                    331: 
                    332:        nlp = p;
                    333:        while (nlact->nls_low > nlp || nlact->nls_high < nlp) {
                    334:                free(nlact->nls_low);
                    335:                nlact->nls_low = NIL;
                    336:                nlact->nls_high = NIL;
                    337:                --nlact;
                    338:                if (nlact < &ntab[0])
                    339:                        panic("nlfree");
                    340:        }
                    341: }
                    342: #endif
                    343: 
                    344: char   VARIABLE[]      "variable";
                    345: 
                    346: char   *classes[] {
                    347:        "undefined",
                    348:        "constant",
                    349:        "type",
                    350:        VARIABLE,
                    351:        "array",
                    352:        "pointer or file",
                    353:        "record",
                    354:        "field",
                    355:        "procedure",
                    356:        "function",
                    357:        VARIABLE,
                    358:        VARIABLE,
                    359:        "pointer",
                    360:        "file",
                    361:        "set",
                    362:        "subrange",
                    363:        "label",
                    364:        "withptr",
                    365:        "scalar",
                    366:        "string",
                    367:        "program",
                    368:        "improper",
                    369: #ifdef DEBUG
                    370:        "variant",
                    371: #endif
                    372: };
                    373: 
                    374: char   snark[] "SNARK";
                    375: 
                    376: #ifdef PI
                    377: #ifdef DEBUG
                    378: char   *ctext[]
                    379: {
                    380:        "BADUSE",
                    381:        "CONST",
                    382:        "TYPE",
                    383:        "VAR",
                    384:        "ARRAY",
                    385:        "PTRFILE",
                    386:        "RECORD",
                    387:        "FIELD",
                    388:        "PROC",
                    389:        "FUNC",
                    390:        "FVAR",
                    391:        "REF",
                    392:        "PTR",
                    393:        "FILE",
                    394:        "SET",
                    395:        "RANGE",
                    396:        "LABEL",
                    397:        "WITHPTR",
                    398:        "SCAL",
                    399:        "STR",
                    400:        "PROG",
                    401:        "IMPROPER",
                    402:        "VARNT"
                    403: };
                    404: 
                    405: char   *stars  "\t***";
                    406: 
                    407: /*
                    408:  * Dump the namelist from the
                    409:  * current nlp down to 'to'.
                    410:  * All the namelist is dumped if
                    411:  * to is NIL.
                    412:  */
                    413: dumpnl(to, rout)
                    414:        struct nl *to;
                    415: {
                    416:        register struct nl *p;
                    417:        register int j;
                    418:        struct nls *nlsp;
                    419:        int i, v, head;
                    420: 
                    421:        if (opt('y') == 0)
                    422:                return;
                    423:        if (to != NIL)
                    424:                printf("\n\"%s\" Block=%d\n", rout, cbn);
                    425:        nlsp = nlact;
                    426:        head = NIL;
                    427:        for (p = nlp; p != to;) {
                    428:                if (p == nlsp->nls_low) {
                    429:                        if (nlsp == &ntab[0])
                    430:                                break;
                    431:                        nlsp--;
                    432:                        p = nlsp->nls_high;
                    433:                }
                    434:                p--;
                    435:                if (head == NIL) {
                    436:                        printf("\tName\tClass  Bn+Flags\tType\tVal\tChn\n");
                    437:                        head++;
                    438:                }
                    439:                printf("%3d:", nloff(p));
                    440:                if (p->symbol)
                    441:                        printf("\t%.7s", p->symbol);
                    442:                else
                    443:                        printf(stars);
                    444:                if (p->class)
                    445:                        printf("\t%s", ctext[p->class]);
                    446:                else
                    447:                        printf(stars);
                    448:                if (p->nl_flags) {
                    449:                        putchar('\t');
                    450:                        if (p->nl_flags & 037)
                    451:                                printf("%d ", p->nl_flags & 037);
                    452: #ifndef PI0
                    453:                        if (p->nl_flags & NMOD)
                    454:                                putchar('M');
                    455:                        if (p->nl_flags & NUSED)
                    456:                                putchar('U');
                    457: #endif
                    458:                        if (p->nl_flags & NFILES)
                    459:                                putchar('F');
                    460:                } else
                    461:                        printf(stars);
                    462:                if (p->type)
                    463:                        printf("\t[%d]", nloff(p->type));
                    464:                else
                    465:                        printf(stars);
                    466:                v = p->value[0];
                    467:                switch (p->class) {
                    468:                        case TYPE:
                    469:                                break;
                    470:                        case VARNT:
                    471:                                goto con;
                    472:                        case CONST:
                    473:                                switch (nloff(p->type)) {
                    474:                                        default:
                    475:                                                printf("\t%d", v);
                    476:                                                break;
                    477:                                        case TDOUBLE:
                    478:                                                printf("\t%f", p->real);
                    479:                                                break;
                    480:                                        case TINT:
                    481: con:
                    482:                                                printf("\t%ld", p->range[0]);
                    483:                                                break;
                    484:                                        case TSTR:
                    485:                                                printf("\t'%s'", v);
                    486:                                                break;
                    487:                                        }
                    488:                                break;
                    489:                        case VAR:
                    490:                        case REF:
                    491:                        case WITHPTR:
                    492:                                printf("\t%d,%d", cbn, v);
                    493:                                break;
                    494:                        case SCAL:
                    495:                        case RANGE:
                    496:                                printf("\t%ld..%ld", p->range[0], p->range[1]);
                    497:                                break;
                    498:                        case RECORD:
                    499:                                printf("\t%d(%d)", v, p->value[NL_FLDSZ]);
                    500:                                break;
                    501:                        case FIELD:
                    502:                                printf("\t%d", v);
                    503:                                break;
                    504:                        case STR:
                    505:                                printf("\t\"%s\"", p->value[1]);
                    506:                                goto casedef;
                    507:                        case FVAR:
                    508:                        case FUNC:
                    509:                        case PROC:
                    510:                        case PROG:
                    511:                                if (cbn == 0) {
                    512:                                        printf("\t<%o>", p->value[0] & 0377);
                    513: #ifndef PI0
                    514:                                        if (p->value[0] & NSTAND)
                    515:                                                printf("\tNSTAND");
                    516: #endif
                    517:                                        break;
                    518:                                }
                    519:                                v = p->value[1];
                    520:                        default:
                    521: casedef:
                    522:                                if (v)
                    523:                                        printf("\t<%d>", v);
                    524:                                else
                    525:                                        printf(stars);
                    526:                }
                    527:                if (p->chain)
                    528:                        printf("\t[%d]", nloff(p->chain));
                    529:                switch (p->class) {
                    530:                        case RECORD:
                    531:                                if (p->value[NL_VARNT])
                    532:                                        printf("\tVARNT=[%d]", nloff(p->value[NL_VARNT]));
                    533:                                if (p->value[NL_TAG])
                    534:                                        printf(" TAG=[%d]", nloff(p->value[NL_TAG]));
                    535:                                break;
                    536:                        case VARNT:
                    537:                                printf("\tVTOREC=[%d]", nloff(p->value[NL_VTOREC]));
                    538:                                break;
                    539:                }
                    540:                putchar('\n');
                    541:        }
                    542:        if (head == 0)
                    543:                printf("\tNo entries\n");
                    544: }
                    545: #endif
                    546: 
                    547: 
                    548: /*
                    549:  * Define a new name list entry
                    550:  * with initial symbol, class, type
                    551:  * and value[0] as given.  A new name
                    552:  * list segment is allocated to hold
                    553:  * the next name list slot if necessary.
                    554:  */
                    555: defnl(sym, cls, typ, val)
                    556:        char *sym;
                    557:        int cls;
                    558:        struct nl *typ;
                    559:        int val;
                    560: {
                    561:        register struct nl *p;
                    562:        register int *q, i;
                    563:        char *cp;
                    564: 
                    565:        p = nlp;
                    566: 
                    567:        /*
                    568:         * Zero out this entry
                    569:         */
                    570:        q = p;
                    571:        i = (sizeof *p)/2;
                    572:        do
                    573:                *q++ = 0;
                    574:        while (--i);
                    575: 
                    576:        /*
                    577:         * Insert the values
                    578:         */
                    579:        p->symbol = sym;
                    580:        p->class = cls;
                    581:        p->type = typ;
                    582:        p->nl_block = cbn;
                    583:        p->value[0] = val;
                    584: 
                    585:        /*
                    586:         * Insure that the next namelist
                    587:         * entry actually exists. This is
                    588:         * really not needed here, it would
                    589:         * suffice to do it at entry if we
                    590:         * need the slot.  It is done this
                    591:         * way because, historically, nlp
                    592:         * always pointed at the next namelist
                    593:         * slot.
                    594:         */
                    595:        nlp++;
                    596:        if (nlp >= nlact->nls_high) {
                    597:                i = NLINC;
                    598:                cp = alloc(NLINC * sizeof *nlp);
                    599:                if (cp == -1) {
                    600:                        i = NLINC / 2;
                    601:                        cp = alloc((NLINC / 2) * sizeof *nlp);
                    602:                }
                    603:                if (cp == -1) {
                    604:                        error("Ran out of memory (defnl)");
                    605:                        pexit(DIED);
                    606:                }
                    607:                nlact++;
                    608:                if (nlact >= &ntab[MAXNL]) {
                    609:                        error("Ran out of name list tables");
                    610:                        pexit(DIED);
                    611:                }
                    612:                nlp = cp;
                    613:                nlact->nls_low = nlp;
                    614:                nlact->nls_high = nlact->nls_low + i;
                    615:        }
                    616:        return (p);
                    617: }
                    618: 
                    619: /*
                    620:  * Make a duplicate of the argument
                    621:  * namelist entry for, e.g., type
                    622:  * declarations of the form 'type a = b'
                    623:  * and array indicies.
                    624:  */
                    625: nlcopy(p)
                    626:        struct nl *p;
                    627: {
                    628:        register int *p1, *p2, i;
                    629: 
                    630:        p1 = p;
                    631:        p = p2 = defnl(0, 0, 0, 0);
                    632:        i = (sizeof *p)/2;
                    633:        do
                    634:                *p2++ = *p1++;
                    635:        while (--i);
                    636:        return (p);
                    637: }
                    638: 
                    639: /*
                    640:  * Compute a namelist offset
                    641:  */
                    642: nloff(p)
                    643:        struct nl *p;
                    644: {
                    645: 
                    646:        return (p - nl);
                    647: }
                    648: 
                    649: /*
                    650:  * Enter a symbol into the block
                    651:  * symbol table.  Symbols are hashed
                    652:  * 64 ways based on low 6 bits of the
                    653:  * character pointer into the string
                    654:  * table.
                    655:  */
                    656: enter(np)
                    657:        struct nl *np;
                    658: {
                    659:        register struct nl *rp, *hp;
                    660:        register struct nl *p;
                    661:        int i;
                    662: 
                    663:        rp = np;
                    664:        if (rp == NIL)
                    665:                return (NIL);
                    666: #ifndef PI1
                    667:        if (cbn > 0)
                    668:                if (rp->symbol == input->symbol || rp->symbol == output->symbol)
                    669:                        error("Pre-defined files input and output must not be redefined");
                    670: #endif
                    671:        i = rp->symbol;
                    672:        i =& 077;
                    673:        hp = disptab[i];
                    674:        if (rp->class != BADUSE && rp->class != FIELD)
                    675:        for (p = hp; p != NIL && (p->nl_block & 037) == cbn; p = p->nl_next)
                    676:                if (p->symbol == rp->symbol && p->class != BADUSE && p->class != FIELD) {
                    677: #ifndef PI1
                    678:                        error("%s is already defined in this block", rp->symbol);
                    679: #endif
                    680:                        break;
                    681: 
                    682:                }
                    683:        rp->nl_next = hp;
                    684:        disptab[i] = rp;
                    685:        return (rp);
                    686: }
                    687: #endif
                    688: 
                    689: double MININT          -2147483648.;
                    690: double MAXINT          2147483647.;

unix.superglobalmegacorp.com

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