merge in onyx changes
[unix-history] / usr / src / usr.bin / pascal / src / stkrval.c
CommitLineData
28e6b83a
PK
1/* Copyright (c) 1979 Regents of the University of California */
2
6cbd3a07 3static char sccsid[] = "@(#)stkrval.c 1.4 %G%";
28e6b83a
PK
4
5#include "whoami.h"
6#include "0.h"
7#include "tree.h"
8#include "opcode.h"
9#include "objfmt.h"
10#ifdef PC
11# include "pcops.h"
12#endif PC
13
14/*
15 * stkrval Rvalue - an expression, and coerce it to be a stack quantity.
16 *
17 * Contype is the type that the caller would prefer, nand is important
18 * if constant sets or constant strings are involved, the latter
19 * because of string padding.
20 */
21/*
22 * for the obj version, this is a copy of rvalue hacked to use fancy new
23 * push-onto-stack-and-convert opcodes.
24 * for the pc version, i just call rvalue and convert if i have to,
25 * based on the return type of rvalue.
26 */
27struct nl *
28stkrval(r, contype , required )
29 register int *r;
30 struct nl *contype;
31 long required;
32{
33 register struct nl *p;
34 register struct nl *q;
35 register char *cp, *cp1;
36 register int c, w;
37 int **pt;
38 long l;
39 double f;
40
41 if (r == NIL)
42 return (NIL);
43 if (nowexp(r))
44 return (NIL);
45 /*
46 * The root of the tree tells us what sort of expression we have.
47 */
48 switch (r[0]) {
49
50 /*
51 * The constant nil
52 */
53 case T_NIL:
54# ifdef OBJ
55 put(2, O_CON14, 0);
56# endif OBJ
57# ifdef PC
58 putleaf( P2ICON , 0 , 0 , P2INT , 0 );
59# endif PC
60 return (nl+TNIL);
61
62 case T_FCALL:
63 case T_VAR:
64 p = lookup(r[2]);
65 if (p == NIL || p->class == BADUSE)
66 return (NIL);
67 switch (p->class) {
68 case VAR:
69 /*
6cbd3a07 70 * if a variable is
28e6b83a
PK
71 * qualified then get
72 * the rvalue by a
73 * stklval and an ind.
74 */
75 if (r[3] != NIL)
76 goto ind;
77 q = p->type;
78 if (q == NIL)
79 return (NIL);
80 if (classify(q) == TSTR)
81 return(stklval(r, NOFLAGS));
82# ifdef OBJ
83 w = width(q);
84 switch (w) {
85 case 8:
6cbd3a07
KM
86 put(2, O_RV8 | bn << 8+INDX,
87 (int)p->value[0]);
28e6b83a
PK
88 return(q);
89 case 4:
6cbd3a07
KM
90 put(2, O_RV4 | bn << 8+INDX,
91 (int)p->value[0]);
28e6b83a
PK
92 return(q);
93 case 2:
6cbd3a07
KM
94 put(2, O_RV24 | bn << 8+INDX,
95 (int)p->value[0]);
28e6b83a
PK
96 return(q);
97 case 1:
6cbd3a07
KM
98 put(2, O_RV14 | bn << 8+INDX,
99 (int)p->value[0]);
28e6b83a
PK
100 return(q);
101 default:
6cbd3a07
KM
102 put(3, O_RV | bn << 8+INDX,
103 (int)p->value[0], w);
28e6b83a
PK
104 return(q);
105 }
106# endif OBJ
107# ifdef PC
108 return rvalue( r , contype , required );
109# endif PC
110
111 case WITHPTR:
112 case REF:
113 /*
114 * A stklval for these
115 * is actually what one
116 * might consider a rvalue.
117 */
118ind:
119 q = stklval(r, NOFLAGS);
120 if (q == NIL)
121 return (NIL);
122 if (classify(q) == TSTR)
123 return(q);
124# ifdef OBJ
125 w = width(q);
126 switch (w) {
127 case 8:
128 put(1, O_IND8);
129 return(q);
130 case 4:
131 put(1, O_IND4);
132 return(q);
133 case 2:
134 put(1, O_IND24);
135 return(q);
136 case 1:
137 put(1, O_IND14);
138 return(q);
139 default:
140 put(2, O_IND, w);
141 return(q);
142 }
143# endif OBJ
144# ifdef PC
145 if ( required == RREQ ) {
146 putop( P2UNARY P2MUL , p2type( q ) );
147 }
148 return q;
149# endif PC
150
151 case CONST:
152 if (r[3] != NIL) {
153 error("%s is a constant and cannot be qualified", r[2]);
154 return (NIL);
155 }
156 q = p->type;
157 if (q == NIL)
158 return (NIL);
159 if (q == nl+TSTR) {
160 /*
161 * Find the size of the string
162 * constant if needed.
163 */
164 cp = p->ptr[0];
165cstrng:
166 cp1 = cp;
167 for (c = 0; *cp++; c++)
168 continue;
169 w = 0;
170 if (contype != NIL && !opt('s')) {
171 if (width(contype) < c && classify(contype) == TSTR) {
172 error("Constant string too long");
173 return (NIL);
174 }
175 w = width(contype) - c;
176 }
177# ifdef OBJ
178 put(2, O_LVCON, lenstr(cp1, w));
179 putstr(cp1, w);
180# endif OBJ
181# ifdef PC
182 putCONG( cp1 , c + w , LREQ );
183# endif PC
184 /*
185 * Define the string temporarily
186 * so later people can know its
187 * width.
188 * cleaned out by stat.
189 */
190 q = defnl(0, STR, 0, c);
191 q->type = q;
192 return (q);
193 }
194 if (q == nl+T1CHAR) {
195# ifdef OBJ
6cbd3a07 196 put(2, O_CONC4, (int)p->value[0]);
28e6b83a
PK
197# endif OBJ
198# ifdef PC
199 putleaf( P2ICON , p -> value[0] , 0 , P2CHAR , 0 );
200# endif PC
201 return(q);
202 }
203 /*
204 * Every other kind of constant here
205 */
206# ifdef OBJ
207 switch (width(q)) {
208 case 8:
209#ifndef DEBUG
210 put(2, O_CON8, p->real);
211 return(q);
212#else
213 if (hp21mx) {
214 f = p->real;
215 conv(&f);
216 l = f.plong;
217 put(2, O_CON4, l);
218 } else
219 put(2, O_CON8, p->real);
220 return(q);
221#endif
222 case 4:
223 put(2, O_CON4, p->range[0]);
224 return(q);
225 case 2:
226 put(2, O_CON24, (short)p->range[0]);
227 return(q);
228 case 1:
6cbd3a07 229 put(2, O_CON14, p->value[0]);
28e6b83a
PK
230 return(q);
231 default:
232 panic("stkrval");
233 }
234# endif OBJ
235# ifdef PC
236 return rvalue( r , contype , required );
237# endif PC
238
239 case FUNC:
c4e911b6 240 case FFUNC:
28e6b83a
PK
241 /*
242 * Function call
243 */
244 pt = (int **)r[3];
245 if (pt != NIL) {
246 switch (pt[1][0]) {
247 case T_PTR:
248 case T_ARGL:
249 case T_ARY:
250 case T_FIELD:
251 error("Can't qualify a function result value");
252 return (NIL);
253 }
254 }
255# ifdef OBJ
256 q = p->type;
257 if (classify(q) == TSTR) {
258 c = width(q);
259 put(2, O_LVCON, even(c+1));
260 putstr("", c);
6cbd3a07 261 put(1, PTR_DUP);
28e6b83a
PK
262 p = funccod(r);
263 put(2, O_AS, c);
264 return(p);
265 }
266 p = funccod(r);
267 if (width(p) <= 2)
268 put(1, O_STOI);
269# endif OBJ
270# ifdef PC
271 p = pcfunccod( r );
272# endif PC
273 return (p);
274
275 case TYPE:
276 error("Type names (e.g. %s) allowed only in declarations", p->symbol);
277 return (NIL);
278
279 case PROC:
c4e911b6 280 case FPROC:
28e6b83a
PK
281 error("Procedure %s found where expression required", p->symbol);
282 return (NIL);
283 default:
284 panic("stkrvid");
285 }
28e6b83a
PK
286 case T_PLUS:
287 case T_MINUS:
288 case T_NOT:
289 case T_AND:
290 case T_OR:
291 case T_DIVD:
292 case T_MULT:
293 case T_SUB:
294 case T_ADD:
295 case T_MOD:
296 case T_DIV:
297 case T_EQ:
298 case T_NE:
299 case T_GE:
300 case T_LE:
301 case T_GT:
302 case T_LT:
303 case T_IN:
304 p = rvalue(r, contype , required );
305# ifdef OBJ
306 if (width(p) <= 2)
307 put(1, O_STOI);
308# endif OBJ
309 return (p);
a26d837a
PK
310 case T_CSET:
311 p = rvalue(r, contype , required );
312 return (p);
28e6b83a
PK
313 default:
314 if (r[2] == NIL)
315 return (NIL);
316 switch (r[0]) {
317 default:
318 panic("stkrval3");
319
320 /*
321 * An octal number
322 */
323 case T_BINT:
324 f = a8tol(r[2]);
325 goto conint;
326
327 /*
328 * A decimal number
329 */
330 case T_INT:
331 f = atof(r[2]);
332conint:
333 if (f > MAXINT || f < MININT) {
334 error("Constant too large for this implementation");
335 return (NIL);
336 }
337 l = f;
338 if (bytes(l, l) <= 2) {
339# ifdef OBJ
340 put(2, O_CON24, (short)l);
341# endif OBJ
342# ifdef PC
343 putleaf( P2ICON , (short) l , 0 , P2INT , 0 );
344# endif PC
345 return(nl+T4INT);
346 }
347# ifdef OBJ
348 put(2, O_CON4, l);
349# endif OBJ
350# ifdef PC
351 putleaf( P2ICON , l , 0 , P2INT , 0 );
352# endif PC
353 return (nl+T4INT);
354
355 /*
356 * A floating point number
357 */
358 case T_FINT:
359# ifdef OBJ
360 put(2, O_CON8, atof(r[2]));
361# endif OBJ
362# ifdef PC
363 putCON8( atof( r[2] ) );
364# endif PC
365 return (nl+TDOUBLE);
366
367 /*
368 * Constant strings. Note that constant characters
369 * are constant strings of length one; there is
370 * no constant string of length one.
371 */
372 case T_STRNG:
373 cp = r[2];
374 if (cp[1] == 0) {
375# ifdef OBJ
376 put(2, O_CONC4, cp[0]);
377# endif OBJ
378# ifdef PC
379 putleaf( P2ICON , cp[0] , 0 , P2CHAR , 0 );
380# endif PC
381 return(nl+T1CHAR);
382 }
383 goto cstrng;
384 }
385
386 }
387}