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