|
|
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: #ifdef PI
12: #include "0.h"
13: #include "opcode.h"
14:
15: #ifndef PI0
16: /*
17: * Convert a p1 into a p2.
18: * Mostly used for different
19: * length integers and "to real" conversions.
20: */
21: convert(p1, p2)
22: struct nl *p1, *p2;
23: {
24: if (p1 == NIL || p2 == NIL)
25: return;
26: switch (width(p1) - width(p2)) {
27: case -7:
28: case -6:
29: put1(O_STOD);
30: return;
31: case -4:
32: put1(O_ITOD);
33: return;
34: case -3:
35: case -2:
36: put1(O_STOI);
37: return;
38: case -1:
39: case 0:
40: case 1:
41: return;
42: case 2:
43: case 3:
44: put1(O_ITOS);
45: return;
46: default:
47: panic("convert");
48: }
49: }
50: #endif
51:
52: /*
53: * Compat tells whether
54: * p1 and p2 are compatible
55: * types for an assignment like
56: * context, i.e. value parameters,
57: * indicies for 'in', etc.
58: */
59: compat(p1, p2, t)
60: struct nl *p1, *p2;
61: {
62: register c1, c2;
63:
64: c1 = classify(p1);
65: if (c1 == NIL)
66: return (NIL);
67: c2 = classify(p2);
68: if (c2 == NIL)
69: return (NIL);
70: switch (c1) {
71: case TBOOL:
72: case TCHAR:
73: if (c1 == c2)
74: return (1);
75: break;
76: case TINT:
77: if (c2 == TINT)
78: return (1);
79: case TDOUBLE:
80: if (c2 == TDOUBLE)
81: return (1);
82: #ifndef PI0
83: if (c2 == TINT && divflg == 0) {
84: divchk= 1;
85: c1 = classify(rvalue(t, NLNIL));
86: divchk = NIL;
87: if (c1 == TINT) {
88: error("Type clash: real is incompatible with integer");
89: cerror("This resulted because you used '/' which always returns real rather");
90: cerror("than 'div' which divides integers and returns integers");
91: divflg = 1;
92: return (NIL);
93: }
94: }
95: #endif
96: break;
97: case TSCAL:
98: if (c2 != TSCAL)
99: break;
100: if (scalar(p1) != scalar(p2)) {
101: derror("Type clash: non-identical scalar types");
102: return (NIL);
103: }
104: return (1);
105: case TSTR:
106: if (c2 != TSTR)
107: break;
108: if (width(p1) != width(p2)) {
109: derror("Type clash: unequal length strings");
110: return (NIL);
111: }
112: return (1);
113: case TNIL:
114: if (c2 != TPTR)
115: break;
116: return (1);
117: case TFILE:
118: if (c1 != c2)
119: break;
120: derror("Type clash: files not allowed in this context");
121: return (NIL);
122: default:
123: if (c1 != c2)
124: break;
125: if (p1 != p2) {
126: derror("Type clash: non-identical %s types", clnames[c1]);
127: return (NIL);
128: }
129: if (p1->nl_flags & NFILES) {
130: derror("Type clash: %ss with file components not allowed in this context", clnames[c1]);
131: return (NIL);
132: }
133: return (1);
134: }
135: derror("Type clash: %s is incompatible with %s", clnames[c1], clnames[c2]);
136: return (NIL);
137: }
138:
139: #ifndef PI0
140: /*
141: * Rangechk generates code to
142: * check if the type p on top
143: * of the stack is in range for
144: * assignment to a variable
145: * of type q.
146: */
147: rangechk(p, q)
148: struct nl *p, *q;
149: {
150: register struct nl *rp;
151: register op;
152: int wq, wrp;
153:
154: if (opt('t') == 0)
155: return;
156: rp = p;
157: if (rp == NIL)
158: return;
159: if (q == NIL)
160: return;
161: /*
162: * When op is 1 we are checking length
163: * 4 numbers against length 2 bounds,
164: * and adding it to the opcode forces
165: * generation of appropriate tests.
166: */
167: op = 0;
168: wq = width(q);
169: wrp = width(rp);
170: op = wq != wrp && (wq == 4 || wrp == 4);
171: if (rp->class == TYPE)
172: rp = rp->type;
173: switch (rp->class) {
174: case RANGE:
175: if (rp->range[0] != 0) {
176: # ifndef DEBUG
177: if (wrp <= 2)
178: put3(O_RANG2+op, ( short ) rp->range[0],
179: ( short ) rp->range[1]);
180: else if (rp != nl+T4INT)
181: put(5, O_RANG4+op, rp->range[0], rp->range[1] );
182: # else
183: if (!hp21mx) {
184: if (wrp <= 2)
185: put3(O_RANG2+op,( short ) rp->range[0],
186: ( short ) rp->range[1]);
187: else if (rp != nl+T4INT)
188: put(5,O_RANG4+op,rp->range[0],
189: rp->range[1]);
190: } else
191: if (rp != nl+T2INT && rp != nl+T4INT)
192: put3(O_RANG2+op,( short ) rp->range[0],
193: ( short ) rp->range[1]);
194: # endif
195: break;
196: }
197: /*
198: * Range whose lower bounds are
199: * zero can be treated as scalars.
200: */
201: case SCAL:
202: if (wrp <= 2)
203: put2(O_RSNG2+op, ( short ) rp->range[1]);
204: else
205: put( 3 , O_RSNG4+op, rp->range[1]);
206: break;
207: default:
208: panic("rangechk");
209: }
210: }
211: #endif
212: #endif
213:
214: #ifdef DEBUG
215: conv(dub)
216: int *dub;
217: {
218: int newfp[2];
219: double *dp = dub;
220: long *lp = dub;
221: register int exp;
222: long mant;
223:
224: newfp[0] = dub[0] & 0100000;
225: newfp[1] = 0;
226: if (*dp == 0.0)
227: goto ret;
228: exp = ((dub[0] >> 7) & 0377) - 0200;
229: if (exp < 0) {
230: newfp[1] = 1;
231: exp = -exp;
232: }
233: if (exp > 63)
234: exp = 63;
235: dub[0] &= ~0177600;
236: dub[0] |= 0200;
237: mant = *lp;
238: mant <<= 8;
239: if (newfp[0])
240: mant = -mant;
241: newfp[0] |= (mant >> 17) & 077777;
242: newfp[1] |= (((int) (mant >> 1)) & 0177400) | (exp << 1);
243: ret:
244: dub[0] = newfp[0];
245: dub[1] = newfp[1];
246: }
247: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.