xref: /csrg-svn/usr.bin/pascal/src/rval.c (revision 771)
1*771Speter /* Copyright (c) 1979 Regents of the University of California */
2*771Speter 
3*771Speter static	char sccsid[] = "@(#)rval.c 1.1 08/27/80";
4*771Speter 
5*771Speter #include "whoami.h"
6*771Speter #include "0.h"
7*771Speter #include "tree.h"
8*771Speter #include "opcode.h"
9*771Speter #include "objfmt.h"
10*771Speter #ifdef PC
11*771Speter #   include	"pc.h"
12*771Speter #   include "pcops.h"
13*771Speter #endif PC
14*771Speter 
15*771Speter extern	char *opnames[];
16*771Speter bool	inempty = FALSE;
17*771Speter 
18*771Speter #ifdef PC
19*771Speter     char	*relts[] =  {
20*771Speter 				"_RELEQ" , "_RELNE" ,
21*771Speter 				"_RELTLT" , "_RELTGT" ,
22*771Speter 				"_RELTLE" , "_RELTGE"
23*771Speter 			    };
24*771Speter     char	*relss[] =  {
25*771Speter 				"_RELEQ" , "_RELNE" ,
26*771Speter 				"_RELSLT" , "_RELSGT" ,
27*771Speter 				"_RELSLE" , "_RELSGE"
28*771Speter 			    };
29*771Speter     long	relops[] =  {
30*771Speter 				P2EQ , P2NE ,
31*771Speter 				P2LT , P2GT ,
32*771Speter 				P2LE , P2GE
33*771Speter 			    };
34*771Speter     long	mathop[] =  {	P2MUL , P2PLUS , P2MINUS };
35*771Speter     char	*setop[] =  {	"_MULT" , "_ADDT" , "_SUBT" };
36*771Speter #endif PC
37*771Speter /*
38*771Speter  * Rvalue - an expression.
39*771Speter  *
40*771Speter  * Contype is the type that the caller would prefer, nand is important
41*771Speter  * if constant sets or constant strings are involved, the latter
42*771Speter  * because of string padding.
43*771Speter  * required is a flag whether an lvalue or an rvalue is required.
44*771Speter  * only VARs and structured things can have gt their lvalue this way.
45*771Speter  */
46*771Speter struct nl *
47*771Speter rvalue(r, contype , required )
48*771Speter 	int *r;
49*771Speter 	struct nl *contype;
50*771Speter 	int	required;
51*771Speter {
52*771Speter 	register struct nl *p, *p1;
53*771Speter 	register struct nl *q;
54*771Speter 	int c, c1, *rt, w, g;
55*771Speter 	char *cp, *cp1, *opname;
56*771Speter 	long l;
57*771Speter 	double f;
58*771Speter 	extern int	flagwas;
59*771Speter 	struct csetstr	csetd;
60*771Speter #	ifdef PC
61*771Speter 	    struct nl	*rettype;
62*771Speter 	    long	ctype;
63*771Speter 	    long	tempoff;
64*771Speter #	endif PC
65*771Speter 
66*771Speter 	if (r == NIL)
67*771Speter 		return (NIL);
68*771Speter 	if (nowexp(r))
69*771Speter 		return (NIL);
70*771Speter 	/*
71*771Speter 	 * Pick up the name of the operation
72*771Speter 	 * for future error messages.
73*771Speter 	 */
74*771Speter 	if (r[0] <= T_IN)
75*771Speter 		opname = opnames[r[0]];
76*771Speter 
77*771Speter 	/*
78*771Speter 	 * The root of the tree tells us what sort of expression we have.
79*771Speter 	 */
80*771Speter 	switch (r[0]) {
81*771Speter 
82*771Speter 	/*
83*771Speter 	 * The constant nil
84*771Speter 	 */
85*771Speter 	case T_NIL:
86*771Speter #		ifdef OBJ
87*771Speter 		    put(2, O_CON2, 0);
88*771Speter #		endif OBJ
89*771Speter #		ifdef PC
90*771Speter 		    putleaf( P2ICON , 0 , 0 , P2PTR|P2UNDEFINED , 0 );
91*771Speter #		endif PC
92*771Speter 		return (nl+TNIL);
93*771Speter 
94*771Speter 	/*
95*771Speter 	 * Function call with arguments.
96*771Speter 	 */
97*771Speter 	case T_FCALL:
98*771Speter #	    ifdef OBJ
99*771Speter 		return (funccod(r));
100*771Speter #	    endif OBJ
101*771Speter #	    ifdef PC
102*771Speter 		return (pcfunccod( r ));
103*771Speter #	    endif PC
104*771Speter 
105*771Speter 	case T_VAR:
106*771Speter 		p = lookup(r[2]);
107*771Speter 		if (p == NIL || p->class == BADUSE)
108*771Speter 			return (NIL);
109*771Speter 		switch (p->class) {
110*771Speter 		    case VAR:
111*771Speter 			    /*
112*771Speter 			     * If a variable is
113*771Speter 			     * qualified then get
114*771Speter 			     * the rvalue by a
115*771Speter 			     * lvalue and an ind.
116*771Speter 			     */
117*771Speter 			    if (r[3] != NIL)
118*771Speter 				    goto ind;
119*771Speter 			    q = p->type;
120*771Speter 			    if (q == NIL)
121*771Speter 				    return (NIL);
122*771Speter #			    ifdef OBJ
123*771Speter 				w = width(q);
124*771Speter 				switch (w) {
125*771Speter 				    case 8:
126*771Speter 					put(2, O_RV8 | bn << 8+INDX, p->value[0]);
127*771Speter 					break;
128*771Speter 				    case 4:
129*771Speter 					put(2, O_RV4 | bn << 8+INDX, p->value[0]);
130*771Speter 					break;
131*771Speter 				    case 2:
132*771Speter 					put(2, O_RV2 | bn << 8+INDX, p->value[0]);
133*771Speter 					break;
134*771Speter 				    case 1:
135*771Speter 					put(2, O_RV1 | bn << 8+INDX, p->value[0]);
136*771Speter 					break;
137*771Speter 				    default:
138*771Speter 					put(3, O_RV | bn << 8+INDX, p->value[0], w);
139*771Speter 				}
140*771Speter #			   endif OBJ
141*771Speter #			   ifdef PC
142*771Speter 				if ( required == RREQ ) {
143*771Speter 				    putRV( p -> symbol , bn , p -> value[0]
144*771Speter 					    , p2type( q ) );
145*771Speter 				} else {
146*771Speter 				    putLV( p -> symbol , bn , p -> value[0]
147*771Speter 					    , p2type( q ) );
148*771Speter 				}
149*771Speter #			   endif PC
150*771Speter 			   return (q);
151*771Speter 
152*771Speter 		    case WITHPTR:
153*771Speter 		    case REF:
154*771Speter 			    /*
155*771Speter 			     * A lvalue for these
156*771Speter 			     * is actually what one
157*771Speter 			     * might consider a rvalue.
158*771Speter 			     */
159*771Speter ind:
160*771Speter 			    q = lvalue(r, NOFLAGS , LREQ );
161*771Speter 			    if (q == NIL)
162*771Speter 				    return (NIL);
163*771Speter #			    ifdef OBJ
164*771Speter 				w = width(q);
165*771Speter 				switch (w) {
166*771Speter 				    case 8:
167*771Speter 					    put(1, O_IND8);
168*771Speter 					    break;
169*771Speter 				    case 4:
170*771Speter 					    put(1, O_IND4);
171*771Speter 					    break;
172*771Speter 				    case 2:
173*771Speter 					    put(1, O_IND2);
174*771Speter 					    break;
175*771Speter 				    case 1:
176*771Speter 					    put(1, O_IND1);
177*771Speter 					    break;
178*771Speter 				    default:
179*771Speter 					    put(2, O_IND, w);
180*771Speter 				}
181*771Speter #			    endif OBJ
182*771Speter #			    ifdef PC
183*771Speter 				if ( required == RREQ ) {
184*771Speter 				    putop( P2UNARY P2MUL , p2type( q ) );
185*771Speter 				}
186*771Speter #			    endif PC
187*771Speter 			    return (q);
188*771Speter 
189*771Speter 		    case CONST:
190*771Speter 			    if (r[3] != NIL) {
191*771Speter 				error("%s is a constant and cannot be qualified", r[2]);
192*771Speter 				return (NIL);
193*771Speter 			    }
194*771Speter 			    q = p->type;
195*771Speter 			    if (q == NIL)
196*771Speter 				    return (NIL);
197*771Speter 			    if (q == nl+TSTR) {
198*771Speter 				    /*
199*771Speter 				     * Find the size of the string
200*771Speter 				     * constant if needed.
201*771Speter 				     */
202*771Speter 				    cp = p->ptr[0];
203*771Speter cstrng:
204*771Speter 				    cp1 = cp;
205*771Speter 				    for (c = 0; *cp++; c++)
206*771Speter 					    continue;
207*771Speter 				    if (contype != NIL && !opt('s')) {
208*771Speter 					    if (width(contype) < c && classify(contype) == TSTR) {
209*771Speter 						    error("Constant string too long");
210*771Speter 						    return (NIL);
211*771Speter 					    }
212*771Speter 					    c = width(contype);
213*771Speter 				    }
214*771Speter #				    ifdef OBJ
215*771Speter 					put( 2 + (sizeof(char *)/sizeof(short))
216*771Speter 						, O_CONG, c, cp1);
217*771Speter #				    endif OBJ
218*771Speter #				    ifdef PC
219*771Speter 					putCONG( cp1 , c , required );
220*771Speter #				    endif PC
221*771Speter 				    /*
222*771Speter 				     * Define the string temporarily
223*771Speter 				     * so later people can know its
224*771Speter 				     * width.
225*771Speter 				     * cleaned out by stat.
226*771Speter 				     */
227*771Speter 				    q = defnl(0, STR, 0, c);
228*771Speter 				    q->type = q;
229*771Speter 				    return (q);
230*771Speter 			    }
231*771Speter 			    if (q == nl+T1CHAR) {
232*771Speter #				    ifdef OBJ
233*771Speter 					put(2, O_CONC, p->value[0]);
234*771Speter #				    endif OBJ
235*771Speter #				    ifdef PC
236*771Speter 					putleaf( P2ICON , p -> value[0] , 0
237*771Speter 						, P2CHAR , 0 );
238*771Speter #				    endif PC
239*771Speter 				    return (q);
240*771Speter 			    }
241*771Speter 			    /*
242*771Speter 			     * Every other kind of constant here
243*771Speter 			     */
244*771Speter 			    switch (width(q)) {
245*771Speter 			    case 8:
246*771Speter #ifndef DEBUG
247*771Speter #				    ifdef OBJ
248*771Speter 					put(2, O_CON8, p->real);
249*771Speter #				    endif OBJ
250*771Speter #				    ifdef PC
251*771Speter 					putCON8( p -> real );
252*771Speter #				    endif PC
253*771Speter #else
254*771Speter 				    if (hp21mx) {
255*771Speter 					    f = p->real;
256*771Speter 					    conv(&f);
257*771Speter 					    l = f.plong;
258*771Speter 					    put(2, O_CON4, l);
259*771Speter 				    } else
260*771Speter #					    ifdef OBJ
261*771Speter 						put(2, O_CON8, p->real);
262*771Speter #					    endif OBJ
263*771Speter #					    ifdef PC
264*771Speter 						putCON8( p -> real );
265*771Speter #					    endif PC
266*771Speter #endif
267*771Speter 				    break;
268*771Speter 			    case 4:
269*771Speter #				    ifdef OBJ
270*771Speter 					put(2, O_CON4, p->range[0]);
271*771Speter #				    endif OBJ
272*771Speter #				    ifdef PC
273*771Speter 					putleaf( P2ICON , p -> range[0] , 0
274*771Speter 						, P2INT , 0 );
275*771Speter #				    endif PC
276*771Speter 				    break;
277*771Speter 			    case 2:
278*771Speter #				    ifdef OBJ
279*771Speter 					put(2, O_CON2, ( short ) p->range[0]);
280*771Speter #				    endif OBJ
281*771Speter #				    ifdef PC
282*771Speter 					    /*
283*771Speter 					     * make short constants ints
284*771Speter 					     */
285*771Speter 					putleaf( P2ICON , (short) p -> range[0]
286*771Speter 						, 0 , P2INT , 0 );
287*771Speter #				    endif PC
288*771Speter 				    break;
289*771Speter 			    case 1:
290*771Speter #				    ifdef OBJ
291*771Speter 					put(2, O_CON1, p->value[0]);
292*771Speter #				    endif OBJ
293*771Speter #				    ifdef PC
294*771Speter 					    /*
295*771Speter 					     * make char constants ints
296*771Speter 					     */
297*771Speter 					putleaf( P2ICON , p -> value[0] , 0
298*771Speter 						, P2INT , 0 );
299*771Speter #				    endif PC
300*771Speter 				    break;
301*771Speter 			    default:
302*771Speter 				    panic("rval");
303*771Speter 			    }
304*771Speter 			    return (q);
305*771Speter 
306*771Speter 		    case FUNC:
307*771Speter 			    /*
308*771Speter 			     * Function call with no arguments.
309*771Speter 			     */
310*771Speter 			    if (r[3]) {
311*771Speter 				    error("Can't qualify a function result value");
312*771Speter 				    return (NIL);
313*771Speter 			    }
314*771Speter #			    ifdef OBJ
315*771Speter 				return (funccod((int *) r));
316*771Speter #			    endif OBJ
317*771Speter #			    ifdef PC
318*771Speter 				return (pcfunccod( r ));
319*771Speter #			    endif PC
320*771Speter 
321*771Speter 		    case TYPE:
322*771Speter 			    error("Type names (e.g. %s) allowed only in declarations", p->symbol);
323*771Speter 			    return (NIL);
324*771Speter 
325*771Speter 		    case PROC:
326*771Speter 			    error("Procedure %s found where expression required", p->symbol);
327*771Speter 			    return (NIL);
328*771Speter 		    default:
329*771Speter 			    panic("rvid");
330*771Speter 		}
331*771Speter 	/*
332*771Speter 	 * Constant sets
333*771Speter 	 */
334*771Speter 	case T_CSET:
335*771Speter #		ifdef OBJ
336*771Speter 		    if ( precset( r , contype , &csetd ) ) {
337*771Speter 			if ( csetd.csettype == NIL ) {
338*771Speter 			    return NIL;
339*771Speter 			}
340*771Speter 			postcset( r , &csetd );
341*771Speter 		    } else {
342*771Speter 			put( 2, O_PUSH, -width(csetd.csettype));
343*771Speter 			postcset( r , &csetd );
344*771Speter 			setran( ( csetd.csettype ) -> type );
345*771Speter 			put( 2, O_CON24, set.uprbp);
346*771Speter 			put( 2, O_CON24, set.lwrb);
347*771Speter 			put( 2, O_CTTOT, 5 + csetd.singcnt + 2 * csetd.paircnt);
348*771Speter 		    }
349*771Speter 		    return csetd.csettype;
350*771Speter #		endif OBJ
351*771Speter #		ifdef PC
352*771Speter 		    if ( precset( r , contype , &csetd ) ) {
353*771Speter 			if ( csetd.csettype == NIL ) {
354*771Speter 			    return NIL;
355*771Speter 			}
356*771Speter 			postcset( r , &csetd );
357*771Speter 		    } else {
358*771Speter 			putleaf( P2ICON , 0 , 0
359*771Speter 				, ADDTYPE( P2FTN | P2INT , P2PTR )
360*771Speter 				, "_CTTOT" );
361*771Speter 			/*
362*771Speter 			 *	allocate a temporary and use it
363*771Speter 			 */
364*771Speter 			sizes[ cbn ].om_off -= lwidth( csetd.csettype );
365*771Speter 			tempoff = sizes[ cbn ].om_off;
366*771Speter 			putlbracket( ftnno , -tempoff );
367*771Speter 			if ( tempoff < sizes[ cbn ].om_max ) {
368*771Speter 			    sizes[ cbn ].om_max = tempoff;
369*771Speter 			}
370*771Speter 			putLV( 0 , cbn , tempoff , P2PTR|P2STRTY );
371*771Speter 			setran( ( csetd.csettype ) -> type );
372*771Speter 			putleaf( P2ICON , set.lwrb , 0 , P2INT , 0 );
373*771Speter 			putop( P2LISTOP , P2INT );
374*771Speter 			putleaf( P2ICON , set.uprbp , 0 , P2INT , 0 );
375*771Speter 			putop( P2LISTOP , P2INT );
376*771Speter 			postcset( r , &csetd );
377*771Speter 			putop( P2CALL , P2INT );
378*771Speter 		    }
379*771Speter 		    return csetd.csettype;
380*771Speter #		endif PC
381*771Speter 
382*771Speter 	/*
383*771Speter 	 * Unary plus and minus
384*771Speter 	 */
385*771Speter 	case T_PLUS:
386*771Speter 	case T_MINUS:
387*771Speter 		q = rvalue(r[2], NIL , RREQ );
388*771Speter 		if (q == NIL)
389*771Speter 			return (NIL);
390*771Speter 		if (isnta(q, "id")) {
391*771Speter 			error("Operand of %s must be integer or real, not %s", opname, nameof(q));
392*771Speter 			return (NIL);
393*771Speter 		}
394*771Speter 		if (r[0] == T_MINUS) {
395*771Speter #		    ifdef OBJ
396*771Speter 			put(1, O_NEG2 + (width(q) >> 2));
397*771Speter #		    endif OBJ
398*771Speter #		    ifdef PC
399*771Speter 			putop( P2UNARY P2MINUS , p2type( q ) );
400*771Speter #		    endif PC
401*771Speter 		    return (isa(q, "d") ? q : nl+T4INT);
402*771Speter 		}
403*771Speter 		return (q);
404*771Speter 
405*771Speter 	case T_NOT:
406*771Speter 		q = rvalue(r[2], NIL , RREQ );
407*771Speter 		if (q == NIL)
408*771Speter 			return (NIL);
409*771Speter 		if (isnta(q, "b")) {
410*771Speter 			error("not must operate on a Boolean, not %s", nameof(q));
411*771Speter 			return (NIL);
412*771Speter 		}
413*771Speter #		ifdef OBJ
414*771Speter 		    put(1, O_NOT);
415*771Speter #		endif OBJ
416*771Speter #		ifdef PC
417*771Speter 		    putop( P2NOT , P2INT );
418*771Speter #		endif PC
419*771Speter 		return (nl+T1BOOL);
420*771Speter 
421*771Speter 	case T_AND:
422*771Speter 	case T_OR:
423*771Speter 		p = rvalue(r[2], NIL , RREQ );
424*771Speter 		p1 = rvalue(r[3], NIL , RREQ );
425*771Speter 		if (p == NIL || p1 == NIL)
426*771Speter 			return (NIL);
427*771Speter 		if (isnta(p, "b")) {
428*771Speter 			error("Left operand of %s must be Boolean, not %s", opname, nameof(p));
429*771Speter 			return (NIL);
430*771Speter 		}
431*771Speter 		if (isnta(p1, "b")) {
432*771Speter 			error("Right operand of %s must be Boolean, not %s", opname, nameof(p1));
433*771Speter 			return (NIL);
434*771Speter 		}
435*771Speter #		ifdef OBJ
436*771Speter 		    put(1, r[0] == T_AND ? O_AND : O_OR);
437*771Speter #		endif OBJ
438*771Speter #		ifdef PC
439*771Speter 			/*
440*771Speter 			 * note the use of & and | rather than && and ||
441*771Speter 			 * to force evaluation of all the expressions.
442*771Speter 			 */
443*771Speter 		    putop( r[ 0 ] == T_AND ? P2AND : P2OR , P2INT );
444*771Speter #		endif PC
445*771Speter 		return (nl+T1BOOL);
446*771Speter 
447*771Speter 	case T_DIVD:
448*771Speter #		ifdef OBJ
449*771Speter 		    p = rvalue(r[2], NIL , RREQ );
450*771Speter 		    p1 = rvalue(r[3], NIL , RREQ );
451*771Speter #		endif OBJ
452*771Speter #		ifdef PC
453*771Speter 			/*
454*771Speter 			 *	force these to be doubles for the divide
455*771Speter 			 */
456*771Speter 		    p = rvalue( r[ 2 ] , NIL , RREQ );
457*771Speter 		    if ( isnta( p , "d" ) ) {
458*771Speter 			putop( P2SCONV , P2DOUBLE );
459*771Speter 		    }
460*771Speter 		    p1 = rvalue( r[ 3 ] , NIL , RREQ );
461*771Speter 		    if ( isnta( p1 , "d" ) ) {
462*771Speter 			putop( P2SCONV , P2DOUBLE );
463*771Speter 		    }
464*771Speter #		endif PC
465*771Speter 		if (p == NIL || p1 == NIL)
466*771Speter 			return (NIL);
467*771Speter 		if (isnta(p, "id")) {
468*771Speter 			error("Left operand of / must be integer or real, not %s", nameof(p));
469*771Speter 			return (NIL);
470*771Speter 		}
471*771Speter 		if (isnta(p1, "id")) {
472*771Speter 			error("Right operand of / must be integer or real, not %s", nameof(p1));
473*771Speter 			return (NIL);
474*771Speter 		}
475*771Speter #		ifdef OBJ
476*771Speter 		    return gen(NIL, r[0], width(p), width(p1));
477*771Speter #		endif OBJ
478*771Speter #		ifdef PC
479*771Speter 		    putop( P2DIV , P2DOUBLE );
480*771Speter 		    return nl + TDOUBLE;
481*771Speter #		endif PC
482*771Speter 
483*771Speter 	case T_MULT:
484*771Speter 	case T_ADD:
485*771Speter 	case T_SUB:
486*771Speter #		ifdef OBJ
487*771Speter 		    /*
488*771Speter 		     * If the context hasn't told us
489*771Speter 		     * the type and a constant set is
490*771Speter 		     * present on the left we need to infer
491*771Speter 		     * the type from the right if possible
492*771Speter 		     * before generating left side code.
493*771Speter 		     */
494*771Speter 		    if (contype == NIL && (rt = r[2]) != NIL && rt[1] == SAWCON) {
495*771Speter 			    codeoff();
496*771Speter 			    contype = rvalue(r[3], NIL , RREQ );
497*771Speter 			    codeon();
498*771Speter 			    if (contype == NIL)
499*771Speter 				    return (NIL);
500*771Speter 		    }
501*771Speter 		    p = rvalue(r[2], contype , RREQ );
502*771Speter 		    p1 = rvalue(r[3], p , RREQ );
503*771Speter 		    if (p == NIL || p1 == NIL)
504*771Speter 			    return (NIL);
505*771Speter 		    if (isa(p, "id") && isa(p1, "id"))
506*771Speter 			return (gen(NIL, r[0], width(p), width(p1)));
507*771Speter 		    if (isa(p, "t") && isa(p1, "t")) {
508*771Speter 			    if (p != p1) {
509*771Speter 				    error("Set types of operands of %s must be identical", opname);
510*771Speter 				    return (NIL);
511*771Speter 			    }
512*771Speter 			    gen(TSET, r[0], width(p), 0);
513*771Speter 			    return (p);
514*771Speter 		    }
515*771Speter #		endif OBJ
516*771Speter #		ifdef PC
517*771Speter 			/*
518*771Speter 			 * the second pass can't do
519*771Speter 			 *	long op double  or  double op long
520*771Speter 			 * so we have to know the type of both operands
521*771Speter 			 * also, it gets tricky for sets, which are done
522*771Speter 			 * by function calls.
523*771Speter 			 */
524*771Speter 		    codeoff();
525*771Speter 		    p1 = rvalue( r[ 3 ] , contype , RREQ );
526*771Speter 		    codeon();
527*771Speter 		    if ( isa( p1 , "id" ) ) {
528*771Speter 			p = rvalue( r[ 2 ] , contype , RREQ );
529*771Speter 			if ( ( p == NIL ) || ( p1 == NIL ) ) {
530*771Speter 			    return NIL;
531*771Speter 			}
532*771Speter 			if ( isa( p , "i" ) && isa( p1 , "d" ) ) {
533*771Speter 			    putop( P2SCONV , P2DOUBLE );
534*771Speter 			}
535*771Speter 			p1 = rvalue( r[ 3 ] , contype , RREQ );
536*771Speter 			if ( isa( p , "d" ) && isa( p1 , "i" ) ) {
537*771Speter 			    putop( P2SCONV , P2DOUBLE );
538*771Speter 			}
539*771Speter 			if ( isa( p , "id" ) ) {
540*771Speter 			    if ( isa( p , "d" ) || isa( p1 , "d" ) ) {
541*771Speter 				ctype = P2DOUBLE;
542*771Speter 				rettype = nl + TDOUBLE;
543*771Speter 			    } else {
544*771Speter 				ctype = P2INT;
545*771Speter 				rettype = nl + T4INT;
546*771Speter 			    }
547*771Speter 			    putop( mathop[ r[0] - T_MULT ] , ctype );
548*771Speter 			    return rettype;
549*771Speter 			}
550*771Speter 		    }
551*771Speter 		    if ( isa( p1 , "t" ) ) {
552*771Speter 			putleaf( P2ICON , 0 , 0
553*771Speter 			    , ADDTYPE( ADDTYPE( P2PTR | P2STRTY , P2FTN )
554*771Speter 					, P2PTR )
555*771Speter 			    , setop[ r[0] - T_MULT ] );
556*771Speter 			/*
557*771Speter 			 *	allocate a temporary and use it
558*771Speter 			 */
559*771Speter 			sizes[ cbn ].om_off -= lwidth( p1 );
560*771Speter 			tempoff = sizes[ cbn ].om_off;
561*771Speter 			putlbracket( ftnno , -tempoff );
562*771Speter 			if ( tempoff < sizes[ cbn ].om_max ) {
563*771Speter 			    sizes[ cbn ].om_max = tempoff;
564*771Speter 			}
565*771Speter 			putLV( 0 , cbn , tempoff , P2PTR|P2STRTY );
566*771Speter 			p = rvalue( r[2] , p1 , LREQ );
567*771Speter 			if ( isa( p , "t" ) ) {
568*771Speter 			    putop( P2LISTOP , P2INT );
569*771Speter 			    if ( p == NIL || p1 == NIL ) {
570*771Speter 				return NIL;
571*771Speter 			    }
572*771Speter 			    p1 = rvalue( r[3] , p , LREQ );
573*771Speter 			    if ( p != p1 ) {
574*771Speter 				error("Set types of operands of %s must be identical", opname);
575*771Speter 				return NIL;
576*771Speter 			    }
577*771Speter 			    putop( P2LISTOP , P2INT );
578*771Speter 			    putleaf( P2ICON , lwidth( p1 ) / sizeof( long ) , 0
579*771Speter 				    , P2INT , 0 );
580*771Speter 			    putop( P2LISTOP , P2INT );
581*771Speter 			    putop( P2CALL , P2PTR | P2STRTY );
582*771Speter 			    return p;
583*771Speter 			}
584*771Speter 		    }
585*771Speter 		    if ( isnta( p1 , "idt" ) ) {
586*771Speter 			    /*
587*771Speter 			     *	find type of left operand for error message.
588*771Speter 			     */
589*771Speter 			p = rvalue( r[2] , contype , RREQ );
590*771Speter 		    }
591*771Speter 			/*
592*771Speter 			 *	don't give spurious error messages.
593*771Speter 			 */
594*771Speter 		    if ( p == NIL || p1 == NIL ) {
595*771Speter 			return NIL;
596*771Speter 		    }
597*771Speter #		endif PC
598*771Speter 		if (isnta(p, "idt")) {
599*771Speter 			error("Left operand of %s must be integer, real or set, not %s", opname, nameof(p));
600*771Speter 			return (NIL);
601*771Speter 		}
602*771Speter 		if (isnta(p1, "idt")) {
603*771Speter 			error("Right operand of %s must be integer, real or set, not %s", opname, nameof(p1));
604*771Speter 			return (NIL);
605*771Speter 		}
606*771Speter 		error("Cannot mix sets with integers and reals as operands of %s", opname);
607*771Speter 		return (NIL);
608*771Speter 
609*771Speter 	case T_MOD:
610*771Speter 	case T_DIV:
611*771Speter 		p = rvalue(r[2], NIL , RREQ );
612*771Speter 		p1 = rvalue(r[3], NIL , RREQ );
613*771Speter 		if (p == NIL || p1 == NIL)
614*771Speter 			return (NIL);
615*771Speter 		if (isnta(p, "i")) {
616*771Speter 			error("Left operand of %s must be integer, not %s", opname, nameof(p));
617*771Speter 			return (NIL);
618*771Speter 		}
619*771Speter 		if (isnta(p1, "i")) {
620*771Speter 			error("Right operand of %s must be integer, not %s", opname, nameof(p1));
621*771Speter 			return (NIL);
622*771Speter 		}
623*771Speter #		ifdef OBJ
624*771Speter 		    return (gen(NIL, r[0], width(p), width(p1)));
625*771Speter #		endif OBJ
626*771Speter #		ifdef PC
627*771Speter 		    putop( r[ 0 ] == T_DIV ? P2DIV : P2MOD , P2INT );
628*771Speter 		    return ( nl + T4INT );
629*771Speter #		endif PC
630*771Speter 
631*771Speter 	case T_EQ:
632*771Speter 	case T_NE:
633*771Speter 	case T_LT:
634*771Speter 	case T_GT:
635*771Speter 	case T_LE:
636*771Speter 	case T_GE:
637*771Speter 		/*
638*771Speter 		 * Since there can be no, a priori, knowledge
639*771Speter 		 * of the context type should a constant string
640*771Speter 		 * or set arise, we must poke around to find such
641*771Speter 		 * a type if possible.  Since constant strings can
642*771Speter 		 * always masquerade as identifiers, this is always
643*771Speter 		 * necessary.
644*771Speter 		 */
645*771Speter 		codeoff();
646*771Speter 		p1 = rvalue(r[3], NIL , RREQ );
647*771Speter 		codeon();
648*771Speter 		if (p1 == NIL)
649*771Speter 			return (NIL);
650*771Speter 		contype = p1;
651*771Speter #		ifdef OBJ
652*771Speter 		    if (p1 == nl+TSET || p1->class == STR) {
653*771Speter 			    /*
654*771Speter 			     * For constant strings we want
655*771Speter 			     * the longest type so as to be
656*771Speter 			     * able to do padding (more importantly
657*771Speter 			     * avoiding truncation). For clarity,
658*771Speter 			     * we get this length here.
659*771Speter 			     */
660*771Speter 			    codeoff();
661*771Speter 			    p = rvalue(r[2], NIL , RREQ );
662*771Speter 			    codeon();
663*771Speter 			    if (p == NIL)
664*771Speter 				    return (NIL);
665*771Speter 			    if (p1 == nl+TSET || width(p) > width(p1))
666*771Speter 				    contype = p;
667*771Speter 		    }
668*771Speter 		    /*
669*771Speter 		     * Now we generate code for
670*771Speter 		     * the operands of the relational
671*771Speter 		     * operation.
672*771Speter 		     */
673*771Speter 		    p = rvalue(r[2], contype , RREQ );
674*771Speter 		    if (p == NIL)
675*771Speter 			    return (NIL);
676*771Speter 		    p1 = rvalue(r[3], p , RREQ );
677*771Speter 		    if (p1 == NIL)
678*771Speter 			    return (NIL);
679*771Speter #		endif OBJ
680*771Speter #		ifdef PC
681*771Speter 		    c1 = classify( p1 );
682*771Speter 		    if ( c1 == TSET || c1 == TSTR || c1 == TREC ) {
683*771Speter 			putleaf( P2ICON , 0 , 0
684*771Speter 				, ADDTYPE( P2FTN | P2INT , P2PTR )
685*771Speter 				, c1 == TSET  ? relts[ r[0] - T_EQ ]
686*771Speter 					      : relss[ r[0] - T_EQ ] );
687*771Speter 			    /*
688*771Speter 			     *	for [] and strings, comparisons are done on
689*771Speter 			     *	the maximum width of the two sides.
690*771Speter 			     *	for other sets, we have to ask the left side
691*771Speter 			     *	what type it is based on the type of the right.
692*771Speter 			     *	(this matters for intsets).
693*771Speter 			     */
694*771Speter 			if ( p1 == nl + TSET || c1 == TSTR ) {
695*771Speter 			    codeoff();
696*771Speter 			    p = rvalue( r[ 2 ] , NIL , LREQ );
697*771Speter 			    codeon();
698*771Speter 			    if (   p1 == nl + TSET
699*771Speter 				|| lwidth( p ) > lwidth( p1 ) ) {
700*771Speter 				contype = p;
701*771Speter 			    }
702*771Speter 			} else {
703*771Speter 			    codeoff();
704*771Speter 			    p = rvalue( r[ 2 ] , contype , LREQ );
705*771Speter 			    codeon();
706*771Speter 			    contype = p;
707*771Speter 			}
708*771Speter 			if ( p == NIL ) {
709*771Speter 			    return NIL;
710*771Speter 			}
711*771Speter 			    /*
712*771Speter 			     *	put out the width of the comparison.
713*771Speter 			     */
714*771Speter 			putleaf( P2ICON , lwidth( contype ) , 0 , P2INT , 0 );
715*771Speter 			    /*
716*771Speter 			     *	and the left hand side,
717*771Speter 			     *	for sets, strings, records
718*771Speter 			     */
719*771Speter 			p = rvalue( r[ 2 ] , contype , LREQ );
720*771Speter 			putop( P2LISTOP , P2INT );
721*771Speter 			p1 = rvalue( r[ 3 ] , p , LREQ );
722*771Speter 			putop( P2LISTOP , P2INT );
723*771Speter 			putop( P2CALL , P2INT );
724*771Speter 		    } else {
725*771Speter 			    /*
726*771Speter 			     *	the easy (scalar or error) case
727*771Speter 			     */
728*771Speter 			p = rvalue( r[ 2 ] , contype , RREQ );
729*771Speter 			if ( p == NIL ) {
730*771Speter 			    return NIL;
731*771Speter 			    /*
732*771Speter 			     * since the second pass can't do
733*771Speter 			     *	long op double  or  double op long
734*771Speter 			     * we may have to do some coercing.
735*771Speter 			     */
736*771Speter 			if ( isa( p , "i" ) && isa( p1 , "d" ) )
737*771Speter 			    putop( P2SCONV , P2DOUBLE );
738*771Speter 			}
739*771Speter 			p1 = rvalue( r[ 3 ] , p , RREQ );
740*771Speter 			if ( isa( p , "d" ) && isa( p1 , "i" ) )
741*771Speter 			    putop( P2SCONV , P2DOUBLE );
742*771Speter 			putop( relops[ r[0] - T_EQ ] , P2INT );
743*771Speter 		    }
744*771Speter #		endif PC
745*771Speter 		c = classify(p);
746*771Speter 		c1 = classify(p1);
747*771Speter 		if (nocomp(c) || nocomp(c1))
748*771Speter 			return (NIL);
749*771Speter 		g = NIL;
750*771Speter 		switch (c) {
751*771Speter 			case TBOOL:
752*771Speter 			case TCHAR:
753*771Speter 				if (c != c1)
754*771Speter 					goto clash;
755*771Speter 				break;
756*771Speter 			case TINT:
757*771Speter 			case TDOUBLE:
758*771Speter 				if (c1 != TINT && c1 != TDOUBLE)
759*771Speter 					goto clash;
760*771Speter 				break;
761*771Speter 			case TSCAL:
762*771Speter 				if (c1 != TSCAL)
763*771Speter 					goto clash;
764*771Speter 				if (scalar(p) != scalar(p1))
765*771Speter 					goto nonident;
766*771Speter 				break;
767*771Speter 			case TSET:
768*771Speter 				if (c1 != TSET)
769*771Speter 					goto clash;
770*771Speter 				if (p != p1)
771*771Speter 					goto nonident;
772*771Speter 				g = TSET;
773*771Speter 				break;
774*771Speter 			case TREC:
775*771Speter 				if ( c1 != TREC ) {
776*771Speter 				    goto clash;
777*771Speter 				}
778*771Speter 				if ( p != p1 ) {
779*771Speter 				    goto nonident;
780*771Speter 				}
781*771Speter 				if (r[0] != T_EQ && r[0] != T_NE) {
782*771Speter 					error("%s not allowed on records - only allow = and <>" , opname );
783*771Speter 					return (NIL);
784*771Speter 				}
785*771Speter 				g = TREC;
786*771Speter 				break;
787*771Speter 			case TPTR:
788*771Speter 			case TNIL:
789*771Speter 				if (c1 != TPTR && c1 != TNIL)
790*771Speter 					goto clash;
791*771Speter 				if (r[0] != T_EQ && r[0] != T_NE) {
792*771Speter 					error("%s not allowed on pointers - only allow = and <>" , opname );
793*771Speter 					return (NIL);
794*771Speter 				}
795*771Speter 				break;
796*771Speter 			case TSTR:
797*771Speter 				if (c1 != TSTR)
798*771Speter 					goto clash;
799*771Speter 				if (width(p) != width(p1)) {
800*771Speter 					error("Strings not same length in %s comparison", opname);
801*771Speter 					return (NIL);
802*771Speter 				}
803*771Speter 				g = TSTR;
804*771Speter 				break;
805*771Speter 			default:
806*771Speter 				panic("rval2");
807*771Speter 		}
808*771Speter #		ifdef OBJ
809*771Speter 		    return (gen(g, r[0], width(p), width(p1)));
810*771Speter #		endif OBJ
811*771Speter #		ifdef PC
812*771Speter 		    return nl + TBOOL;
813*771Speter #		endif PC
814*771Speter clash:
815*771Speter 		error("%ss and %ss cannot be compared - operator was %s", clnames[c], clnames[c1], opname);
816*771Speter 		return (NIL);
817*771Speter nonident:
818*771Speter 		error("%s types must be identical in comparisons - operator was %s", clnames[c1], opname);
819*771Speter 		return (NIL);
820*771Speter 
821*771Speter 	case T_IN:
822*771Speter 	    rt = r[3];
823*771Speter #	    ifdef OBJ
824*771Speter 		if (rt != NIL && rt[0] == T_CSET) {
825*771Speter 			precset( rt , NIL , &csetd );
826*771Speter 			p1 = csetd.csettype;
827*771Speter 			if (p1 == NIL)
828*771Speter 			    return NIL;
829*771Speter 			if (p1 == nl+TSET) {
830*771Speter 			    if ( !inempty ) {
831*771Speter 				warning();
832*771Speter 				error("... in [] makes little sense, since it is always false!");
833*771Speter 				inempty = TRUE;
834*771Speter 			    }
835*771Speter 			    put(1, O_CON1, 0);
836*771Speter 			    return (nl+T1BOOL);
837*771Speter 			}
838*771Speter 			postcset( rt, &csetd);
839*771Speter 		    } else {
840*771Speter 			p1 = stkrval(r[3], NIL , RREQ );
841*771Speter 			rt = NIL;
842*771Speter 		    }
843*771Speter #		endif OBJ
844*771Speter #		ifdef PC
845*771Speter 		    if (rt != NIL && rt[0] == T_CSET) {
846*771Speter 			if ( precset( rt , NIL , &csetd ) ) {
847*771Speter 			    if ( csetd.csettype != nl + TSET ) {
848*771Speter 				putleaf( P2ICON , 0 , 0
849*771Speter 					, ADDTYPE( P2FTN | P2INT , P2PTR )
850*771Speter 					, "_IN" );
851*771Speter 			    }
852*771Speter 			} else {
853*771Speter 			    putleaf( P2ICON , 0 , 0
854*771Speter 				    , ADDTYPE( P2FTN | P2INT , P2PTR )
855*771Speter 				    , "_INCT" );
856*771Speter 			}
857*771Speter 			p1 = csetd.csettype;
858*771Speter 			if (p1 == NIL)
859*771Speter 			    return NIL;
860*771Speter 			if ( p1 == nl + TSET ) {
861*771Speter 			    if ( !inempty ) {
862*771Speter 				warning();
863*771Speter 				error("... in [] makes little sense, since it is always false!");
864*771Speter 				inempty = TRUE;
865*771Speter 			    }
866*771Speter 			    putleaf( P2ICON , 0 , 0 , P2INT , 0 );
867*771Speter 			    return (nl+T1BOOL);
868*771Speter 			}
869*771Speter 		    } else {
870*771Speter 			putleaf( P2ICON , 0 , 0
871*771Speter 				, ADDTYPE( P2FTN | P2INT , P2PTR )
872*771Speter 				, "_IN" );
873*771Speter 			codeoff();
874*771Speter 			p1 = rvalue(r[3], NIL , LREQ );
875*771Speter 			codeon();
876*771Speter 		    }
877*771Speter #		endif PC
878*771Speter 		p = stkrval(r[2], NIL , RREQ );
879*771Speter 		if (p == NIL || p1 == NIL)
880*771Speter 			return (NIL);
881*771Speter 		if (p1->class != SET) {
882*771Speter 			error("Right operand of 'in' must be a set, not %s", nameof(p1));
883*771Speter 			return (NIL);
884*771Speter 		}
885*771Speter 		if (incompat(p, p1->type, r[2])) {
886*771Speter 			cerror("Index type clashed with set component type for 'in'");
887*771Speter 			return (NIL);
888*771Speter 		}
889*771Speter 		setran(p1->type);
890*771Speter #		ifdef OBJ
891*771Speter 		    if (rt == NIL || csetd.comptime)
892*771Speter 			    put(4, O_IN, width(p1), set.lwrb, set.uprbp);
893*771Speter 		    else
894*771Speter 			    put(2, O_INCT, 3 + csetd.singcnt + 2*csetd.paircnt);
895*771Speter #		endif OBJ
896*771Speter #		ifdef PC
897*771Speter 		    if ( rt == NIL || rt[0] != T_CSET ) {
898*771Speter 			putleaf( P2ICON , set.lwrb , 0 , P2INT , 0 );
899*771Speter 			putop( P2LISTOP , P2INT );
900*771Speter 			putleaf( P2ICON , set.uprbp , 0 , P2INT , 0 );
901*771Speter 			putop( P2LISTOP , P2INT );
902*771Speter 			p1 = rvalue( r[3] , NIL , LREQ );
903*771Speter 			putop( P2LISTOP , P2INT );
904*771Speter 		    } else if ( csetd.comptime ) {
905*771Speter 			putleaf( P2ICON , set.lwrb , 0 , P2INT , 0 );
906*771Speter 			putop( P2LISTOP , P2INT );
907*771Speter 			putleaf( P2ICON , set.uprbp , 0 , P2INT , 0 );
908*771Speter 			putop( P2LISTOP , P2INT );
909*771Speter 			postcset( r[3] , &csetd );
910*771Speter 			putop( P2LISTOP , P2INT );
911*771Speter 		    } else {
912*771Speter 			postcset( r[3] , &csetd );
913*771Speter 		    }
914*771Speter 		    putop( P2CALL , P2INT );
915*771Speter #		endif PC
916*771Speter 		return (nl+T1BOOL);
917*771Speter 	default:
918*771Speter 		if (r[2] == NIL)
919*771Speter 			return (NIL);
920*771Speter 		switch (r[0]) {
921*771Speter 		default:
922*771Speter 			panic("rval3");
923*771Speter 
924*771Speter 
925*771Speter 		/*
926*771Speter 		 * An octal number
927*771Speter 		 */
928*771Speter 		case T_BINT:
929*771Speter 			f = a8tol(r[2]);
930*771Speter 			goto conint;
931*771Speter 
932*771Speter 		/*
933*771Speter 		 * A decimal number
934*771Speter 		 */
935*771Speter 		case T_INT:
936*771Speter 			f = atof(r[2]);
937*771Speter conint:
938*771Speter 			if (f > MAXINT || f < MININT) {
939*771Speter 				error("Constant too large for this implementation");
940*771Speter 				return (NIL);
941*771Speter 			}
942*771Speter 			l = f;
943*771Speter 			if (bytes(l, l) <= 2) {
944*771Speter #				ifdef OBJ
945*771Speter 				    put(2, O_CON2, ( short ) l);
946*771Speter #				endif OBJ
947*771Speter #				ifdef PC
948*771Speter 				        /*
949*771Speter 					 * short constants are ints
950*771Speter 					 */
951*771Speter 				    putleaf( P2ICON , l , 0 , P2INT , 0 );
952*771Speter #				endif PC
953*771Speter 				return (nl+T2INT);
954*771Speter 			}
955*771Speter #			ifdef OBJ
956*771Speter 			    put(2, O_CON4, l);
957*771Speter #			endif OBJ
958*771Speter #			ifdef PC
959*771Speter 			    putleaf( P2ICON , l , 0 , P2INT , 0 );
960*771Speter #			endif PC
961*771Speter 			return (nl+T4INT);
962*771Speter 
963*771Speter 		/*
964*771Speter 		 * A floating point number
965*771Speter 		 */
966*771Speter 		case T_FINT:
967*771Speter #			ifdef OBJ
968*771Speter 			    put(2, O_CON8, atof(r[2]));
969*771Speter #			endif OBJ
970*771Speter #			ifdef PC
971*771Speter 			    putCON8( atof( r[2] ) );
972*771Speter #			endif PC
973*771Speter 			return (nl+TDOUBLE);
974*771Speter 
975*771Speter 		/*
976*771Speter 		 * Constant strings.  Note that constant characters
977*771Speter 		 * are constant strings of length one; there is
978*771Speter 		 * no constant string of length one.
979*771Speter 		 */
980*771Speter 		case T_STRNG:
981*771Speter 			cp = r[2];
982*771Speter 			if (cp[1] == 0) {
983*771Speter #				ifdef OBJ
984*771Speter 				    put(2, O_CONC, cp[0]);
985*771Speter #				endif OBJ
986*771Speter #				ifdef PC
987*771Speter 				    putleaf( P2ICON , cp[0] , 0 , P2CHAR , 0 );
988*771Speter #				endif PC
989*771Speter 				return (nl+T1CHAR);
990*771Speter 			}
991*771Speter 			goto cstrng;
992*771Speter 		}
993*771Speter 
994*771Speter 	}
995*771Speter }
996*771Speter 
997*771Speter /*
998*771Speter  * Can a class appear
999*771Speter  * in a comparison ?
1000*771Speter  */
1001*771Speter nocomp(c)
1002*771Speter 	int c;
1003*771Speter {
1004*771Speter 
1005*771Speter 	switch (c) {
1006*771Speter 		case TREC:
1007*771Speter 			if ( opt( 's' ) ) {
1008*771Speter 			    standard();
1009*771Speter 			    error("record comparison is non-standard");
1010*771Speter 			}
1011*771Speter 			break;
1012*771Speter 		case TFILE:
1013*771Speter 		case TARY:
1014*771Speter 			error("%ss may not participate in comparisons", clnames[c]);
1015*771Speter 			return (1);
1016*771Speter 	}
1017*771Speter 	return (NIL);
1018*771Speter }
1019*771Speter 
1020*771Speter     /*
1021*771Speter      *	this is sort of like gconst, except it works on expression trees
1022*771Speter      *	rather than declaration trees, and doesn't give error messages for
1023*771Speter      *	non-constant things.
1024*771Speter      *	as a side effect this fills in the con structure that gconst uses.
1025*771Speter      *	this returns TRUE or FALSE.
1026*771Speter      */
1027*771Speter constval(r)
1028*771Speter 	register int *r;
1029*771Speter {
1030*771Speter 	register struct nl *np;
1031*771Speter 	register *cn;
1032*771Speter 	char *cp;
1033*771Speter 	int negd, sgnd;
1034*771Speter 	long ci;
1035*771Speter 
1036*771Speter 	con.ctype = NIL;
1037*771Speter 	cn = r;
1038*771Speter 	negd = sgnd = 0;
1039*771Speter loop:
1040*771Speter 	    /*
1041*771Speter 	     *	cn[2] is nil if error recovery generated a T_STRNG
1042*771Speter 	     */
1043*771Speter 	if (cn == NIL || cn[2] == NIL)
1044*771Speter 		return FALSE;
1045*771Speter 	switch (cn[0]) {
1046*771Speter 		default:
1047*771Speter 			return FALSE;
1048*771Speter 		case T_MINUS:
1049*771Speter 			negd = 1 - negd;
1050*771Speter 			/* and fall through */
1051*771Speter 		case T_PLUS:
1052*771Speter 			sgnd++;
1053*771Speter 			cn = cn[2];
1054*771Speter 			goto loop;
1055*771Speter 		case T_NIL:
1056*771Speter 			con.cpval = NIL;
1057*771Speter 			con.cival = 0;
1058*771Speter 			con.crval = con.cival;
1059*771Speter 			con.ctype = nl + TNIL;
1060*771Speter 			break;
1061*771Speter 		case T_VAR:
1062*771Speter 			np = lookup(cn[2]);
1063*771Speter 			if (np == NIL || np->class != CONST) {
1064*771Speter 				return FALSE;
1065*771Speter 			}
1066*771Speter 			if ( cn[3] != NIL ) {
1067*771Speter 				return FALSE;
1068*771Speter 			}
1069*771Speter 			con.ctype = np->type;
1070*771Speter 			switch (classify(np->type)) {
1071*771Speter 				case TINT:
1072*771Speter 					con.crval = np->range[0];
1073*771Speter 					break;
1074*771Speter 				case TDOUBLE:
1075*771Speter 					con.crval = np->real;
1076*771Speter 					break;
1077*771Speter 				case TBOOL:
1078*771Speter 				case TCHAR:
1079*771Speter 				case TSCAL:
1080*771Speter 					con.cival = np->value[0];
1081*771Speter 					con.crval = con.cival;
1082*771Speter 					break;
1083*771Speter 				case TSTR:
1084*771Speter 					con.cpval = np->ptr[0];
1085*771Speter 					break;
1086*771Speter 				default:
1087*771Speter 					con.ctype = NIL;
1088*771Speter 					return FALSE;
1089*771Speter 			}
1090*771Speter 			break;
1091*771Speter 		case T_BINT:
1092*771Speter 			con.crval = a8tol(cn[2]);
1093*771Speter 			goto restcon;
1094*771Speter 		case T_INT:
1095*771Speter 			con.crval = atof(cn[2]);
1096*771Speter 			if (con.crval > MAXINT || con.crval < MININT) {
1097*771Speter 				derror("Constant too large for this implementation");
1098*771Speter 				con.crval = 0;
1099*771Speter 			}
1100*771Speter restcon:
1101*771Speter 			ci = con.crval;
1102*771Speter #ifndef PI0
1103*771Speter 			if (bytes(ci, ci) <= 2)
1104*771Speter 				con.ctype = nl+T2INT;
1105*771Speter 			else
1106*771Speter #endif
1107*771Speter 				con.ctype = nl+T4INT;
1108*771Speter 			break;
1109*771Speter 		case T_FINT:
1110*771Speter 			con.ctype = nl+TDOUBLE;
1111*771Speter 			con.crval = atof(cn[2]);
1112*771Speter 			break;
1113*771Speter 		case T_STRNG:
1114*771Speter 			cp = cn[2];
1115*771Speter 			if (cp[1] == 0) {
1116*771Speter 				con.ctype = nl+T1CHAR;
1117*771Speter 				con.cival = cp[0];
1118*771Speter 				con.crval = con.cival;
1119*771Speter 				break;
1120*771Speter 			}
1121*771Speter 			con.ctype = nl+TSTR;
1122*771Speter 			con.cpval = cp;
1123*771Speter 			break;
1124*771Speter 	}
1125*771Speter 	if (sgnd) {
1126*771Speter 		if (isnta(con.ctype, "id")) {
1127*771Speter 			derror("%s constants cannot be signed", nameof(con.ctype));
1128*771Speter 			return FALSE;
1129*771Speter 		} else if (negd)
1130*771Speter 			con.crval = -con.crval;
1131*771Speter 	}
1132*771Speter 	return TRUE;
1133*771Speter }
1134