|
|
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.;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.