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