1771Speter /* Copyright (c) 1979 Regents of the University of California */ 2771Speter 315945Speter #ifndef lint 4*18468Sralph static char sccsid[] = "@(#)rval.c 2.3 03/20/85"; 515931Smckusick #endif 6771Speter 7771Speter #include "whoami.h" 8771Speter #include "0.h" 9771Speter #include "tree.h" 10771Speter #include "opcode.h" 11771Speter #include "objfmt.h" 12771Speter #ifdef PC 13771Speter # include "pc.h" 14*18468Sralph # include <pcc.h> 15771Speter #endif PC 1611328Speter #include "tmps.h" 1715931Smckusick #include "tree_ty.h" 18771Speter 19771Speter extern char *opnames[]; 20771Speter 211627Speter /* line number of the last record comparison warning */ 221627Speter short reccompline = 0; 233397Speter /* line number of the last non-standard set comparison */ 243397Speter short nssetline = 0; 251627Speter 26771Speter #ifdef PC 27771Speter char *relts[] = { 28771Speter "_RELEQ" , "_RELNE" , 29771Speter "_RELTLT" , "_RELTGT" , 30771Speter "_RELTLE" , "_RELTGE" 31771Speter }; 32771Speter char *relss[] = { 33771Speter "_RELEQ" , "_RELNE" , 34771Speter "_RELSLT" , "_RELSGT" , 35771Speter "_RELSLE" , "_RELSGE" 36771Speter }; 37771Speter long relops[] = { 38*18468Sralph PCC_EQ , PCC_NE , 39*18468Sralph PCC_LT , PCC_GT , 40*18468Sralph PCC_LE , PCC_GE 41771Speter }; 42*18468Sralph long mathop[] = { PCC_MUL , PCC_PLUS , PCC_MINUS }; 43771Speter char *setop[] = { "_MULT" , "_ADDT" , "_SUBT" }; 44771Speter #endif PC 45771Speter /* 46771Speter * Rvalue - an expression. 47771Speter * 48771Speter * Contype is the type that the caller would prefer, nand is important 4916273Speter * if constant strings are involved, because of string padding. 50771Speter * required is a flag whether an lvalue or an rvalue is required. 51771Speter * only VARs and structured things can have gt their lvalue this way. 52771Speter */ 5315931Smckusick /*ARGSUSED*/ 54771Speter struct nl * 55771Speter rvalue(r, contype , required ) 5615931Smckusick struct tnode *r; 57771Speter struct nl *contype; 58771Speter int required; 59771Speter { 60771Speter register struct nl *p, *p1; 61771Speter register struct nl *q; 6215931Smckusick int c, c1, w; 6315931Smckusick #ifdef OBJ 6415931Smckusick int g; 6515931Smckusick #endif 6615931Smckusick struct tnode *rt; 67771Speter char *cp, *cp1, *opname; 68771Speter long l; 6915931Smckusick union 7015931Smckusick { 7115931Smckusick long plong[2]; 7215931Smckusick double pdouble; 7315931Smckusick }f; 74771Speter extern int flagwas; 75771Speter struct csetstr csetd; 76771Speter # ifdef PC 77771Speter struct nl *rettype; 78771Speter long ctype; 793834Speter struct nl *tempnlp; 80771Speter # endif PC 81771Speter 8215931Smckusick if (r == TR_NIL) 8315931Smckusick return (NLNIL); 84771Speter if (nowexp(r)) 8515931Smckusick return (NLNIL); 86771Speter /* 87771Speter * Pick up the name of the operation 88771Speter * for future error messages. 89771Speter */ 9015931Smckusick if (r->tag <= T_IN) 9115931Smckusick opname = opnames[r->tag]; 92771Speter 93771Speter /* 94771Speter * The root of the tree tells us what sort of expression we have. 95771Speter */ 9615931Smckusick switch (r->tag) { 97771Speter 98771Speter /* 99771Speter * The constant nil 100771Speter */ 101771Speter case T_NIL: 102771Speter # ifdef OBJ 10315931Smckusick (void) put(2, O_CON2, 0); 104771Speter # endif OBJ 105771Speter # ifdef PC 106*18468Sralph putleaf( PCC_ICON , 0 , 0 , PCCTM_PTR|PCCT_UNDEF , (char *) 0 ); 107771Speter # endif PC 108771Speter return (nl+TNIL); 109771Speter 110771Speter /* 111771Speter * Function call with arguments. 112771Speter */ 113771Speter case T_FCALL: 114771Speter # ifdef OBJ 115771Speter return (funccod(r)); 116771Speter # endif OBJ 117771Speter # ifdef PC 118771Speter return (pcfunccod( r )); 119771Speter # endif PC 120771Speter 121771Speter case T_VAR: 12215931Smckusick p = lookup(r->var_node.cptr); 12315931Smckusick if (p == NLNIL || p->class == BADUSE) 12415931Smckusick return (NLNIL); 125771Speter switch (p->class) { 126771Speter case VAR: 127771Speter /* 128771Speter * If a variable is 129771Speter * qualified then get 130771Speter * the rvalue by a 131771Speter * lvalue and an ind. 132771Speter */ 13315931Smckusick if (r->var_node.qual != TR_NIL) 134771Speter goto ind; 135771Speter q = p->type; 136771Speter if (q == NIL) 13715931Smckusick return (NLNIL); 138771Speter # ifdef OBJ 139771Speter w = width(q); 140771Speter switch (w) { 141771Speter case 8: 14215931Smckusick (void) put(2, O_RV8 | bn << 8+INDX, 1433078Smckusic (int)p->value[0]); 144771Speter break; 145771Speter case 4: 14615931Smckusick (void) put(2, O_RV4 | bn << 8+INDX, 1473078Smckusic (int)p->value[0]); 148771Speter break; 149771Speter case 2: 15015931Smckusick (void) put(2, O_RV2 | bn << 8+INDX, 1513078Smckusic (int)p->value[0]); 152771Speter break; 153771Speter case 1: 15415931Smckusick (void) put(2, O_RV1 | bn << 8+INDX, 1553078Smckusic (int)p->value[0]); 156771Speter break; 157771Speter default: 15815931Smckusick (void) put(3, O_RV | bn << 8+INDX, 1593078Smckusic (int)p->value[0], w); 160771Speter } 161771Speter # endif OBJ 162771Speter # ifdef PC 163771Speter if ( required == RREQ ) { 1643834Speter putRV( p -> symbol , bn , p -> value[0] , 1653834Speter p -> extra_flags , p2type( q ) ); 166771Speter } else { 1673834Speter putLV( p -> symbol , bn , p -> value[0] , 1683834Speter p -> extra_flags , p2type( q ) ); 169771Speter } 170771Speter # endif PC 171771Speter return (q); 172771Speter 173771Speter case WITHPTR: 174771Speter case REF: 175771Speter /* 176771Speter * A lvalue for these 177771Speter * is actually what one 178771Speter * might consider a rvalue. 179771Speter */ 180771Speter ind: 181771Speter q = lvalue(r, NOFLAGS , LREQ ); 182771Speter if (q == NIL) 18315931Smckusick return (NLNIL); 184771Speter # ifdef OBJ 185771Speter w = width(q); 186771Speter switch (w) { 187771Speter case 8: 18815931Smckusick (void) put(1, O_IND8); 189771Speter break; 190771Speter case 4: 19115931Smckusick (void) put(1, O_IND4); 192771Speter break; 193771Speter case 2: 19415931Smckusick (void) put(1, O_IND2); 195771Speter break; 196771Speter case 1: 19715931Smckusick (void) put(1, O_IND1); 198771Speter break; 199771Speter default: 20015931Smckusick (void) put(2, O_IND, w); 201771Speter } 202771Speter # endif OBJ 203771Speter # ifdef PC 204771Speter if ( required == RREQ ) { 205*18468Sralph putop( PCCOM_UNARY PCC_MUL , p2type( q ) ); 206771Speter } 207771Speter # endif PC 208771Speter return (q); 209771Speter 210771Speter case CONST: 21115931Smckusick if (r->var_node.qual != TR_NIL) { 21215931Smckusick error("%s is a constant and cannot be qualified", r->var_node.cptr); 21315931Smckusick return (NLNIL); 214771Speter } 215771Speter q = p->type; 21615931Smckusick if (q == NLNIL) 21715931Smckusick return (NLNIL); 218771Speter if (q == nl+TSTR) { 219771Speter /* 220771Speter * Find the size of the string 221771Speter * constant if needed. 222771Speter */ 22315931Smckusick cp = (char *) p->ptr[0]; 224771Speter cstrng: 225771Speter cp1 = cp; 226771Speter for (c = 0; *cp++; c++) 227771Speter continue; 2283078Smckusic w = c; 229771Speter if (contype != NIL && !opt('s')) { 230771Speter if (width(contype) < c && classify(contype) == TSTR) { 231771Speter error("Constant string too long"); 23215931Smckusick return (NLNIL); 233771Speter } 2343078Smckusic w = width(contype); 235771Speter } 236771Speter # ifdef OBJ 23715931Smckusick (void) put(2, O_CONG, w); 2383078Smckusic putstr(cp1, w - c); 239771Speter # endif OBJ 240771Speter # ifdef PC 2413155Smckusic putCONG( cp1 , w , required ); 242771Speter # endif PC 243771Speter /* 244771Speter * Define the string temporarily 245771Speter * so later people can know its 246771Speter * width. 247771Speter * cleaned out by stat. 248771Speter */ 24915931Smckusick q = defnl((char *) 0, STR, NLNIL, w); 250771Speter q->type = q; 251771Speter return (q); 252771Speter } 253771Speter if (q == nl+T1CHAR) { 254771Speter # ifdef OBJ 25515931Smckusick (void) put(2, O_CONC, (int)p->value[0]); 256771Speter # endif OBJ 257771Speter # ifdef PC 258*18468Sralph putleaf( PCC_ICON , p -> value[0] , 0 259*18468Sralph , PCCT_CHAR , (char *) 0 ); 260771Speter # endif PC 261771Speter return (q); 262771Speter } 263771Speter /* 264771Speter * Every other kind of constant here 265771Speter */ 266771Speter switch (width(q)) { 267771Speter case 8: 268771Speter #ifndef DEBUG 269771Speter # ifdef OBJ 27015931Smckusick (void) put(2, O_CON8, p->real); 271771Speter # endif OBJ 272771Speter # ifdef PC 273771Speter putCON8( p -> real ); 274771Speter # endif PC 275771Speter #else 276771Speter if (hp21mx) { 27715931Smckusick f.pdouble = p->real; 27815931Smckusick conv((int *) (&f.pdouble)); 27915931Smckusick l = f.plong[1]; 28015931Smckusick (void) put(2, O_CON4, l); 281771Speter } else 282771Speter # ifdef OBJ 28315931Smckusick (void) put(2, O_CON8, p->real); 284771Speter # endif OBJ 285771Speter # ifdef PC 286771Speter putCON8( p -> real ); 287771Speter # endif PC 288771Speter #endif 289771Speter break; 290771Speter case 4: 291771Speter # ifdef OBJ 29215931Smckusick (void) put(2, O_CON4, p->range[0]); 293771Speter # endif OBJ 294771Speter # ifdef PC 295*18468Sralph putleaf( PCC_ICON , (int) p->range[0] , 0 296*18468Sralph , PCCT_INT , (char *) 0 ); 297771Speter # endif PC 298771Speter break; 299771Speter case 2: 300771Speter # ifdef OBJ 30115931Smckusick (void) put(2, O_CON2, (short)p->range[0]); 302771Speter # endif OBJ 303771Speter # ifdef PC 304*18468Sralph putleaf( PCC_ICON , (short) p -> range[0] 305*18468Sralph , 0 , PCCT_SHORT , (char *) 0 ); 306771Speter # endif PC 307771Speter break; 308771Speter case 1: 309771Speter # ifdef OBJ 31015931Smckusick (void) put(2, O_CON1, p->value[0]); 311771Speter # endif OBJ 312771Speter # ifdef PC 313*18468Sralph putleaf( PCC_ICON , p -> value[0] , 0 314*18468Sralph , PCCT_CHAR , (char *) 0 ); 315771Speter # endif PC 316771Speter break; 317771Speter default: 318771Speter panic("rval"); 319771Speter } 320771Speter return (q); 321771Speter 322771Speter case FUNC: 3231200Speter case FFUNC: 324771Speter /* 325771Speter * Function call with no arguments. 326771Speter */ 32715931Smckusick if (r->var_node.qual != TR_NIL) { 328771Speter error("Can't qualify a function result value"); 32915931Smckusick return (NLNIL); 330771Speter } 331771Speter # ifdef OBJ 33215931Smckusick return (funccod(r)); 333771Speter # endif OBJ 334771Speter # ifdef PC 335771Speter return (pcfunccod( r )); 336771Speter # endif PC 337771Speter 338771Speter case TYPE: 339771Speter error("Type names (e.g. %s) allowed only in declarations", p->symbol); 34015931Smckusick return (NLNIL); 341771Speter 342771Speter case PROC: 3431200Speter case FPROC: 344771Speter error("Procedure %s found where expression required", p->symbol); 34515931Smckusick return (NLNIL); 346771Speter default: 347771Speter panic("rvid"); 348771Speter } 349771Speter /* 350771Speter * Constant sets 351771Speter */ 352771Speter case T_CSET: 353771Speter # ifdef OBJ 354771Speter if ( precset( r , contype , &csetd ) ) { 355771Speter if ( csetd.csettype == NIL ) { 35615931Smckusick return (NLNIL); 357771Speter } 358771Speter postcset( r , &csetd ); 359771Speter } else { 36015931Smckusick (void) put( 2, O_PUSH, -lwidth(csetd.csettype)); 361771Speter postcset( r , &csetd ); 362771Speter setran( ( csetd.csettype ) -> type ); 36315931Smckusick (void) put( 2, O_CON24, set.uprbp); 36415931Smckusick (void) put( 2, O_CON24, set.lwrb); 36515931Smckusick (void) put( 2, O_CTTOT, 3663078Smckusic (int)(4 + csetd.singcnt + 2 * csetd.paircnt)); 367771Speter } 368771Speter return csetd.csettype; 369771Speter # endif OBJ 370771Speter # ifdef PC 371771Speter if ( precset( r , contype , &csetd ) ) { 372771Speter if ( csetd.csettype == NIL ) { 37315931Smckusick return (NLNIL); 374771Speter } 375771Speter postcset( r , &csetd ); 376771Speter } else { 377*18468Sralph putleaf( PCC_ICON , 0 , 0 378*18468Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 379771Speter , "_CTTOT" ); 380771Speter /* 381771Speter * allocate a temporary and use it 382771Speter */ 3833834Speter tempnlp = tmpalloc(lwidth(csetd.csettype), 3843227Smckusic csetd.csettype, NOREG); 38515931Smckusick putLV( (char *) 0 , cbn , tempnlp -> value[ NL_OFFS ] , 386*18468Sralph tempnlp -> extra_flags , PCCTM_PTR|PCCT_STRTY ); 387771Speter setran( ( csetd.csettype ) -> type ); 388*18468Sralph putleaf( PCC_ICON , set.lwrb , 0 , PCCT_INT , (char *) 0 ); 389*18468Sralph putop( PCC_CM , PCCT_INT ); 390*18468Sralph putleaf( PCC_ICON , set.uprbp , 0 , PCCT_INT , (char *) 0 ); 391*18468Sralph putop( PCC_CM , PCCT_INT ); 392771Speter postcset( r , &csetd ); 393*18468Sralph putop( PCC_CALL , PCCT_INT ); 394771Speter } 395771Speter return csetd.csettype; 396771Speter # endif PC 397771Speter 398771Speter /* 399771Speter * Unary plus and minus 400771Speter */ 401771Speter case T_PLUS: 402771Speter case T_MINUS: 40315931Smckusick q = rvalue(r->un_expr.expr, NLNIL , RREQ ); 40415931Smckusick if (q == NLNIL) 40515931Smckusick return (NLNIL); 406771Speter if (isnta(q, "id")) { 407771Speter error("Operand of %s must be integer or real, not %s", opname, nameof(q)); 40815931Smckusick return (NLNIL); 409771Speter } 41015931Smckusick if (r->tag == T_MINUS) { 411771Speter # ifdef OBJ 41215931Smckusick (void) put(1, O_NEG2 + (width(q) >> 2)); 41310670Speter return (isa(q, "d") ? q : nl+T4INT); 414771Speter # endif OBJ 415771Speter # ifdef PC 41610670Speter if (isa(q, "i")) { 417*18468Sralph sconv(p2type(q), PCCT_INT); 418*18468Sralph putop( PCCOM_UNARY PCC_MINUS, PCCT_INT); 41910670Speter return nl+T4INT; 42010670Speter } 421*18468Sralph putop( PCCOM_UNARY PCC_MINUS, PCCT_DOUBLE); 42210670Speter return nl+TDOUBLE; 423771Speter # endif PC 424771Speter } 425771Speter return (q); 426771Speter 427771Speter case T_NOT: 42815931Smckusick q = rvalue(r->un_expr.expr, NLNIL , RREQ ); 42915931Smckusick if (q == NLNIL) 43015931Smckusick return (NLNIL); 431771Speter if (isnta(q, "b")) { 432771Speter error("not must operate on a Boolean, not %s", nameof(q)); 43315931Smckusick return (NLNIL); 434771Speter } 435771Speter # ifdef OBJ 43615931Smckusick (void) put(1, O_NOT); 437771Speter # endif OBJ 438771Speter # ifdef PC 439*18468Sralph sconv(p2type(q), PCCT_INT); 440*18468Sralph putop( PCC_NOT , PCCT_INT); 441*18468Sralph sconv(PCCT_INT, p2type(q)); 442771Speter # endif PC 443771Speter return (nl+T1BOOL); 444771Speter 445771Speter case T_AND: 446771Speter case T_OR: 44715931Smckusick p = rvalue(r->expr_node.lhs, NLNIL , RREQ ); 44810364Smckusick # ifdef PC 449*18468Sralph sconv(p2type(p),PCCT_INT); 45010364Smckusick # endif PC 45115931Smckusick p1 = rvalue(r->expr_node.rhs, NLNIL , RREQ ); 45210364Smckusick # ifdef PC 453*18468Sralph sconv(p2type(p1),PCCT_INT); 45410364Smckusick # endif PC 45515931Smckusick if (p == NLNIL || p1 == NLNIL) 45615931Smckusick return (NLNIL); 457771Speter if (isnta(p, "b")) { 458771Speter error("Left operand of %s must be Boolean, not %s", opname, nameof(p)); 45915931Smckusick return (NLNIL); 460771Speter } 461771Speter if (isnta(p1, "b")) { 462771Speter error("Right operand of %s must be Boolean, not %s", opname, nameof(p1)); 46315931Smckusick return (NLNIL); 464771Speter } 465771Speter # ifdef OBJ 46615931Smckusick (void) put(1, r->tag == T_AND ? O_AND : O_OR); 467771Speter # endif OBJ 468771Speter # ifdef PC 469771Speter /* 470771Speter * note the use of & and | rather than && and || 471771Speter * to force evaluation of all the expressions. 472771Speter */ 473*18468Sralph putop( r->tag == T_AND ? PCC_AND : PCC_OR , PCCT_INT ); 474*18468Sralph sconv(PCCT_INT, p2type(p)); 475771Speter # endif PC 476771Speter return (nl+T1BOOL); 477771Speter 478771Speter case T_DIVD: 479771Speter # ifdef OBJ 48015931Smckusick p = rvalue(r->expr_node.lhs, NLNIL , RREQ ); 48115931Smckusick p1 = rvalue(r->expr_node.rhs, NLNIL , RREQ ); 482771Speter # endif OBJ 483771Speter # ifdef PC 484771Speter /* 485771Speter * force these to be doubles for the divide 486771Speter */ 48715931Smckusick p = rvalue( r->expr_node.lhs , NLNIL , RREQ ); 488*18468Sralph sconv(p2type(p), PCCT_DOUBLE); 48915931Smckusick p1 = rvalue( r->expr_node.rhs , NLNIL , RREQ ); 490*18468Sralph sconv(p2type(p1), PCCT_DOUBLE); 491771Speter # endif PC 49215931Smckusick if (p == NLNIL || p1 == NLNIL) 49315931Smckusick return (NLNIL); 494771Speter if (isnta(p, "id")) { 495771Speter error("Left operand of / must be integer or real, not %s", nameof(p)); 49615931Smckusick return (NLNIL); 497771Speter } 498771Speter if (isnta(p1, "id")) { 499771Speter error("Right operand of / must be integer or real, not %s", nameof(p1)); 50015931Smckusick return (NLNIL); 501771Speter } 502771Speter # ifdef OBJ 50315931Smckusick return gen(NIL, r->tag, width(p), width(p1)); 504771Speter # endif OBJ 505771Speter # ifdef PC 506*18468Sralph putop( PCC_DIV , PCCT_DOUBLE ); 507771Speter return nl + TDOUBLE; 508771Speter # endif PC 509771Speter 510771Speter case T_MULT: 511771Speter case T_ADD: 512771Speter case T_SUB: 513771Speter # ifdef OBJ 514771Speter /* 51516273Speter * get the type of the right hand side. 51616273Speter * if it turns out to be a set, 51716273Speter * use that type when getting 51816273Speter * the type of the left hand side. 51916273Speter * and then use the type of the left hand side 52016273Speter * when generating code. 52116273Speter * this will correctly decide the type of any 52216273Speter * empty sets in the tree, since if the empty set 52316273Speter * is on the left hand side it will inherit 52416273Speter * the type of the right hand side, 52516273Speter * and if it's on the right hand side, its type (intset) 52616273Speter * will be overridden by the type of the left hand side. 52716273Speter * this is an awful lot of tree traversing, 52816273Speter * but it works. 529771Speter */ 53016273Speter codeoff(); 53116273Speter p1 = rvalue( r->expr_node.rhs , NLNIL , RREQ ); 53216273Speter codeon(); 53316273Speter if ( p1 == NLNIL ) { 53415931Smckusick return NLNIL; 5351555Speter } 53616273Speter if (isa(p1, "t")) { 53716273Speter codeoff(); 53816273Speter contype = rvalue(r->expr_node.lhs, p1, RREQ); 53916273Speter codeon(); 54016273Speter if (contype == NLNIL) { 54116273Speter return NLNIL; 54216273Speter } 54316273Speter } 54415931Smckusick p = rvalue( r->expr_node.lhs , contype , RREQ ); 54515931Smckusick p1 = rvalue( r->expr_node.rhs , p , RREQ ); 54615937Smckusick if ( p == NLNIL || p1 == NLNIL ) 54715931Smckusick return NLNIL; 548771Speter if (isa(p, "id") && isa(p1, "id")) 54915931Smckusick return (gen(NIL, r->tag, width(p), width(p1))); 550771Speter if (isa(p, "t") && isa(p1, "t")) { 551771Speter if (p != p1) { 552771Speter error("Set types of operands of %s must be identical", opname); 55315931Smckusick return (NLNIL); 554771Speter } 55515931Smckusick (void) gen(TSET, r->tag, width(p), 0); 556771Speter return (p); 557771Speter } 558771Speter # endif OBJ 559771Speter # ifdef PC 560771Speter /* 561771Speter * the second pass can't do 562771Speter * long op double or double op long 56316273Speter * so we have to know the type of both operands. 56416273Speter * also, see the note for obj above on determining 56516273Speter * the type of empty sets. 566771Speter */ 567771Speter codeoff(); 56816273Speter p1 = rvalue(r->expr_node.rhs, NLNIL, RREQ); 569771Speter codeon(); 570771Speter if ( isa( p1 , "id" ) ) { 57115931Smckusick p = rvalue( r->expr_node.lhs , contype , RREQ ); 57215937Smckusick if ( ( p == NLNIL ) || ( p1 == NLNIL ) ) { 57315931Smckusick return NLNIL; 574771Speter } 57515931Smckusick tuac(p, p1, &rettype, (int *) (&ctype)); 57615931Smckusick p1 = rvalue( r->expr_node.rhs , contype , RREQ ); 57715931Smckusick tuac(p1, p, &rettype, (int *) (&ctype)); 578771Speter if ( isa( p , "id" ) ) { 57915931Smckusick putop( (int) mathop[r->tag - T_MULT], (int) ctype); 580771Speter return rettype; 581771Speter } 582771Speter } 583771Speter if ( isa( p1 , "t" ) ) { 584*18468Sralph putleaf( PCC_ICON , 0 , 0 585*18468Sralph , PCCM_ADDTYPE( PCCM_ADDTYPE( PCCTM_PTR | PCCT_STRTY , PCCTM_FTN ) 586*18468Sralph , PCCTM_PTR ) 58715931Smckusick , setop[ r->tag - T_MULT ] ); 58816273Speter codeoff(); 58916273Speter contype = rvalue( r->expr_node.lhs, p1 , LREQ ); 59016273Speter codeon(); 59115937Smckusick if ( contype == NLNIL ) { 59215931Smckusick return NLNIL; 5931555Speter } 5941555Speter /* 5951555Speter * allocate a temporary and use it 5961555Speter */ 5973834Speter tempnlp = tmpalloc(lwidth(contype), contype, NOREG); 59815931Smckusick putLV((char *) 0 , cbn , tempnlp -> value[ NL_OFFS ] , 599*18468Sralph tempnlp -> extra_flags , PCCTM_PTR|PCCT_STRTY ); 60015931Smckusick p = rvalue( r->expr_node.lhs , contype , LREQ ); 601771Speter if ( isa( p , "t" ) ) { 602*18468Sralph putop( PCC_CM , PCCT_INT ); 60315937Smckusick if ( p == NLNIL || p1 == NLNIL ) { 60415931Smckusick return NLNIL; 605771Speter } 60615931Smckusick p1 = rvalue( r->expr_node.rhs , p , LREQ ); 607771Speter if ( p != p1 ) { 608771Speter error("Set types of operands of %s must be identical", opname); 60915931Smckusick return NLNIL; 610771Speter } 611*18468Sralph putop( PCC_CM , PCCT_INT ); 612*18468Sralph putleaf( PCC_ICON , (int) (lwidth(p1)) / sizeof( long ) , 0 613*18468Sralph , PCCT_INT , (char *) 0 ); 614*18468Sralph putop( PCC_CM , PCCT_INT ); 615*18468Sralph putop( PCC_CALL , PCCTM_PTR | PCCT_STRTY ); 616771Speter return p; 617771Speter } 618771Speter } 619771Speter if ( isnta( p1 , "idt" ) ) { 620771Speter /* 621771Speter * find type of left operand for error message. 622771Speter */ 62315931Smckusick p = rvalue( r->expr_node.lhs , contype , RREQ ); 624771Speter } 625771Speter /* 626771Speter * don't give spurious error messages. 627771Speter */ 62815937Smckusick if ( p == NLNIL || p1 == NLNIL ) { 62915931Smckusick return NLNIL; 630771Speter } 631771Speter # endif PC 632771Speter if (isnta(p, "idt")) { 633771Speter error("Left operand of %s must be integer, real or set, not %s", opname, nameof(p)); 63415931Smckusick return (NLNIL); 635771Speter } 636771Speter if (isnta(p1, "idt")) { 637771Speter error("Right operand of %s must be integer, real or set, not %s", opname, nameof(p1)); 63815931Smckusick return (NLNIL); 639771Speter } 640771Speter error("Cannot mix sets with integers and reals as operands of %s", opname); 64115931Smckusick return (NLNIL); 642771Speter 643771Speter case T_MOD: 644771Speter case T_DIV: 64515931Smckusick p = rvalue(r->expr_node.lhs, NLNIL , RREQ ); 64610364Smckusick # ifdef PC 647*18468Sralph sconv(p2type(p), PCCT_INT); 64810364Smckusick # endif PC 64915931Smckusick p1 = rvalue(r->expr_node.rhs, NLNIL , RREQ ); 65010364Smckusick # ifdef PC 651*18468Sralph sconv(p2type(p1), PCCT_INT); 65210364Smckusick # endif PC 65315937Smckusick if (p == NLNIL || p1 == NLNIL) 65415931Smckusick return (NLNIL); 655771Speter if (isnta(p, "i")) { 656771Speter error("Left operand of %s must be integer, not %s", opname, nameof(p)); 65715931Smckusick return (NLNIL); 658771Speter } 659771Speter if (isnta(p1, "i")) { 660771Speter error("Right operand of %s must be integer, not %s", opname, nameof(p1)); 66115931Smckusick return (NLNIL); 662771Speter } 663771Speter # ifdef OBJ 66415931Smckusick return (gen(NIL, r->tag, width(p), width(p1))); 665771Speter # endif OBJ 666771Speter # ifdef PC 667*18468Sralph putop( r->tag == T_DIV ? PCC_DIV : PCC_MOD , PCCT_INT ); 668771Speter return ( nl + T4INT ); 669771Speter # endif PC 670771Speter 671771Speter case T_EQ: 672771Speter case T_NE: 673771Speter case T_LT: 674771Speter case T_GT: 675771Speter case T_LE: 676771Speter case T_GE: 677771Speter /* 678771Speter * Since there can be no, a priori, knowledge 679771Speter * of the context type should a constant string 680771Speter * or set arise, we must poke around to find such 681771Speter * a type if possible. Since constant strings can 682771Speter * always masquerade as identifiers, this is always 683771Speter * necessary. 68416273Speter * see the note in the obj section of case T_MULT above 68516273Speter * for the determination of the base type of empty sets. 686771Speter */ 687771Speter codeoff(); 68815931Smckusick p1 = rvalue(r->expr_node.rhs, NLNIL , RREQ ); 689771Speter codeon(); 69015931Smckusick if (p1 == NLNIL) 69115931Smckusick return (NLNIL); 692771Speter contype = p1; 693771Speter # ifdef OBJ 6941555Speter if (p1->class == STR) { 695771Speter /* 696771Speter * For constant strings we want 697771Speter * the longest type so as to be 698771Speter * able to do padding (more importantly 699771Speter * avoiding truncation). For clarity, 700771Speter * we get this length here. 701771Speter */ 702771Speter codeoff(); 70315931Smckusick p = rvalue(r->expr_node.lhs, NLNIL , RREQ ); 704771Speter codeon(); 70515931Smckusick if (p == NLNIL) 70615931Smckusick return (NLNIL); 7071555Speter if (width(p) > width(p1)) 708771Speter contype = p; 709771Speter } 71016273Speter if (isa(p1, "t")) { 71116273Speter codeoff(); 71216273Speter contype = rvalue(r->expr_node.lhs, p1, RREQ); 71316273Speter codeon(); 71416273Speter if (contype == NLNIL) { 71516273Speter return NLNIL; 71616273Speter } 71716273Speter } 718771Speter /* 719771Speter * Now we generate code for 720771Speter * the operands of the relational 721771Speter * operation. 722771Speter */ 72315931Smckusick p = rvalue(r->expr_node.lhs, contype , RREQ ); 72415931Smckusick if (p == NLNIL) 72515931Smckusick return (NLNIL); 72615931Smckusick p1 = rvalue(r->expr_node.rhs, p , RREQ ); 72715931Smckusick if (p1 == NLNIL) 72815931Smckusick return (NLNIL); 729771Speter # endif OBJ 730771Speter # ifdef PC 731771Speter c1 = classify( p1 ); 732771Speter if ( c1 == TSET || c1 == TSTR || c1 == TREC ) { 733*18468Sralph putleaf( PCC_ICON , 0 , 0 734*18468Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 73515931Smckusick , c1 == TSET ? relts[ r->tag - T_EQ ] 73615931Smckusick : relss[ r->tag - T_EQ ] ); 737771Speter /* 738771Speter * for [] and strings, comparisons are done on 739771Speter * the maximum width of the two sides. 740771Speter * for other sets, we have to ask the left side 741771Speter * what type it is based on the type of the right. 742771Speter * (this matters for intsets). 743771Speter */ 7441555Speter if ( c1 == TSTR ) { 745771Speter codeoff(); 74615931Smckusick p = rvalue( r->expr_node.lhs , NLNIL , LREQ ); 747771Speter codeon(); 74815931Smckusick if ( p == NLNIL ) { 74915931Smckusick return NLNIL; 7501555Speter } 7511555Speter if ( lwidth( p ) > lwidth( p1 ) ) { 752771Speter contype = p; 753771Speter } 7541555Speter } else if ( c1 == TSET ) { 75515937Smckusick codeoff(); 75616273Speter contype = rvalue(r->expr_node.lhs, p1, LREQ); 75715937Smckusick codeon(); 75816273Speter if (contype == NLNIL) { 75915937Smckusick return NLNIL; 7601555Speter } 7611627Speter } 762771Speter /* 763771Speter * put out the width of the comparison. 764771Speter */ 765*18468Sralph putleaf(PCC_ICON, (int) lwidth(contype), 0, PCCT_INT, (char *) 0); 766771Speter /* 767771Speter * and the left hand side, 768771Speter * for sets, strings, records 769771Speter */ 77015931Smckusick p = rvalue( r->expr_node.lhs , contype , LREQ ); 77115931Smckusick if ( p == NLNIL ) { 77215931Smckusick return NLNIL; 7735413Speter } 774*18468Sralph putop( PCC_CM , PCCT_INT ); 77515931Smckusick p1 = rvalue( r->expr_node.rhs , p , LREQ ); 77615931Smckusick if ( p1 == NLNIL ) { 77715931Smckusick return NLNIL; 7785413Speter } 779*18468Sralph putop( PCC_CM , PCCT_INT ); 780*18468Sralph putop( PCC_CALL , PCCT_INT ); 781771Speter } else { 782771Speter /* 783771Speter * the easy (scalar or error) case 784771Speter */ 78515931Smckusick p = rvalue( r->expr_node.lhs , contype , RREQ ); 78615931Smckusick if ( p == NLNIL ) { 78715931Smckusick return NLNIL; 7882056Speter } 789771Speter /* 790771Speter * since the second pass can't do 791771Speter * long op double or double op long 792771Speter * we may have to do some coercing. 793771Speter */ 79415931Smckusick tuac(p, p1, &rettype, (int *) (&ctype)); 79515931Smckusick p1 = rvalue( r->expr_node.rhs , p , RREQ ); 79615931Smckusick if ( p1 == NLNIL ) { 79715931Smckusick return NLNIL; 7985413Speter } 79915931Smckusick tuac(p1, p, &rettype, (int *) (&ctype)); 800*18468Sralph putop((int) relops[ r->tag - T_EQ ] , PCCT_INT ); 801*18468Sralph sconv(PCCT_INT, PCCT_CHAR); 802771Speter } 803771Speter # endif PC 804771Speter c = classify(p); 805771Speter c1 = classify(p1); 806771Speter if (nocomp(c) || nocomp(c1)) 80715931Smckusick return (NLNIL); 80815931Smckusick # ifdef OBJ 80915931Smckusick g = NIL; 81015931Smckusick # endif 811771Speter switch (c) { 812771Speter case TBOOL: 813771Speter case TCHAR: 814771Speter if (c != c1) 815771Speter goto clash; 816771Speter break; 817771Speter case TINT: 818771Speter case TDOUBLE: 819771Speter if (c1 != TINT && c1 != TDOUBLE) 820771Speter goto clash; 821771Speter break; 822771Speter case TSCAL: 823771Speter if (c1 != TSCAL) 824771Speter goto clash; 825771Speter if (scalar(p) != scalar(p1)) 826771Speter goto nonident; 827771Speter break; 828771Speter case TSET: 829771Speter if (c1 != TSET) 830771Speter goto clash; 8313397Speter if ( opt( 's' ) && 83215931Smckusick ( ( r->tag == T_LT) || (r->tag == T_GT) ) && 8333397Speter ( line != nssetline ) ) { 8343397Speter nssetline = line; 8353397Speter standard(); 8363397Speter error("%s comparison on sets is non-standard" , opname ); 8373397Speter } 838771Speter if (p != p1) 839771Speter goto nonident; 84015931Smckusick # ifdef OBJ 84115931Smckusick g = TSET; 84215931Smckusick # endif 843771Speter break; 844771Speter case TREC: 845771Speter if ( c1 != TREC ) { 846771Speter goto clash; 847771Speter } 848771Speter if ( p != p1 ) { 849771Speter goto nonident; 850771Speter } 85115931Smckusick if (r->tag != T_EQ && r->tag != T_NE) { 852771Speter error("%s not allowed on records - only allow = and <>" , opname ); 85315931Smckusick return (NLNIL); 854771Speter } 85515931Smckusick # ifdef OBJ 85615931Smckusick g = TREC; 85715931Smckusick # endif 858771Speter break; 859771Speter case TPTR: 860771Speter case TNIL: 861771Speter if (c1 != TPTR && c1 != TNIL) 862771Speter goto clash; 86315931Smckusick if (r->tag != T_EQ && r->tag != T_NE) { 864771Speter error("%s not allowed on pointers - only allow = and <>" , opname ); 86515931Smckusick return (NLNIL); 866771Speter } 86715937Smckusick if (p != nl+TNIL && p1 != nl+TNIL && p != p1) 86815937Smckusick goto nonident; 869771Speter break; 870771Speter case TSTR: 871771Speter if (c1 != TSTR) 872771Speter goto clash; 873771Speter if (width(p) != width(p1)) { 874771Speter error("Strings not same length in %s comparison", opname); 87515931Smckusick return (NLNIL); 876771Speter } 87715931Smckusick # ifdef OBJ 87815931Smckusick g = TSTR; 87915931Smckusick # endif OBJ 880771Speter break; 881771Speter default: 882771Speter panic("rval2"); 883771Speter } 884771Speter # ifdef OBJ 88515931Smckusick return (gen(g, r->tag, width(p), width(p1))); 886771Speter # endif OBJ 887771Speter # ifdef PC 888771Speter return nl + TBOOL; 889771Speter # endif PC 890771Speter clash: 891771Speter error("%ss and %ss cannot be compared - operator was %s", clnames[c], clnames[c1], opname); 89215931Smckusick return (NLNIL); 893771Speter nonident: 894771Speter error("%s types must be identical in comparisons - operator was %s", clnames[c1], opname); 89515931Smckusick return (NLNIL); 896771Speter 897771Speter case T_IN: 89815931Smckusick rt = r->expr_node.rhs; 899771Speter # ifdef OBJ 90015931Smckusick if (rt != TR_NIL && rt->tag == T_CSET) { 90115931Smckusick (void) precset( rt , NLNIL , &csetd ); 902771Speter p1 = csetd.csettype; 90315931Smckusick if (p1 == NLNIL) 90415931Smckusick return NLNIL; 905771Speter postcset( rt, &csetd); 906771Speter } else { 90715931Smckusick p1 = stkrval(r->expr_node.rhs, NLNIL , (long) RREQ ); 90815931Smckusick rt = TR_NIL; 909771Speter } 910771Speter # endif OBJ 911771Speter # ifdef PC 91215931Smckusick if (rt != TR_NIL && rt->tag == T_CSET) { 91315931Smckusick if ( precset( rt , NLNIL , &csetd ) ) { 914*18468Sralph putleaf( PCC_ICON , 0 , 0 915*18468Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 9161555Speter , "_IN" ); 917771Speter } else { 918*18468Sralph putleaf( PCC_ICON , 0 , 0 919*18468Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 920771Speter , "_INCT" ); 921771Speter } 922771Speter p1 = csetd.csettype; 923771Speter if (p1 == NIL) 92415931Smckusick return NLNIL; 925771Speter } else { 926*18468Sralph putleaf( PCC_ICON , 0 , 0 927*18468Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 928771Speter , "_IN" ); 929771Speter codeoff(); 93015931Smckusick p1 = rvalue(r->expr_node.rhs, NLNIL , LREQ ); 931771Speter codeon(); 932771Speter } 933771Speter # endif PC 93415931Smckusick p = stkrval(r->expr_node.lhs, NLNIL , (long) RREQ ); 935771Speter if (p == NIL || p1 == NIL) 93615931Smckusick return (NLNIL); 93715931Smckusick if (p1->class != (char) SET) { 938771Speter error("Right operand of 'in' must be a set, not %s", nameof(p1)); 93915931Smckusick return (NLNIL); 940771Speter } 94115931Smckusick if (incompat(p, p1->type, r->expr_node.lhs)) { 942771Speter cerror("Index type clashed with set component type for 'in'"); 94315931Smckusick return (NLNIL); 944771Speter } 945771Speter setran(p1->type); 946771Speter # ifdef OBJ 94715931Smckusick if (rt == TR_NIL || csetd.comptime) 94815931Smckusick (void) put(4, O_IN, width(p1), set.lwrb, set.uprbp); 949771Speter else 95015931Smckusick (void) put(2, O_INCT, 9513078Smckusic (int)(3 + csetd.singcnt + 2*csetd.paircnt)); 952771Speter # endif OBJ 953771Speter # ifdef PC 95415931Smckusick if ( rt == TR_NIL || rt->tag != T_CSET ) { 955*18468Sralph putleaf( PCC_ICON , set.lwrb , 0 , PCCT_INT , (char *) 0 ); 956*18468Sralph putop( PCC_CM , PCCT_INT ); 957*18468Sralph putleaf( PCC_ICON , set.uprbp , 0 , PCCT_INT , (char *) 0 ); 958*18468Sralph putop( PCC_CM , PCCT_INT ); 95915931Smckusick p1 = rvalue( r->expr_node.rhs , NLNIL , LREQ ); 96015931Smckusick if ( p1 == NLNIL ) { 96115931Smckusick return NLNIL; 9625413Speter } 963*18468Sralph putop( PCC_CM , PCCT_INT ); 964771Speter } else if ( csetd.comptime ) { 965*18468Sralph putleaf( PCC_ICON , set.lwrb , 0 , PCCT_INT , (char *) 0 ); 966*18468Sralph putop( PCC_CM , PCCT_INT ); 967*18468Sralph putleaf( PCC_ICON , set.uprbp , 0 , PCCT_INT , (char *) 0 ); 968*18468Sralph putop( PCC_CM , PCCT_INT ); 96915931Smckusick postcset( r->expr_node.rhs , &csetd ); 970*18468Sralph putop( PCC_CM , PCCT_INT ); 971771Speter } else { 97215931Smckusick postcset( r->expr_node.rhs , &csetd ); 973771Speter } 974*18468Sralph putop( PCC_CALL , PCCT_INT ); 975*18468Sralph sconv(PCCT_INT, PCCT_CHAR); 976771Speter # endif PC 977771Speter return (nl+T1BOOL); 978771Speter default: 97915931Smckusick if (r->expr_node.lhs == TR_NIL) 98015931Smckusick return (NLNIL); 98115931Smckusick switch (r->tag) { 982771Speter default: 983771Speter panic("rval3"); 984771Speter 985771Speter 986771Speter /* 987771Speter * An octal number 988771Speter */ 989771Speter case T_BINT: 99015931Smckusick f.pdouble = a8tol(r->const_node.cptr); 991771Speter goto conint; 992771Speter 993771Speter /* 994771Speter * A decimal number 995771Speter */ 996771Speter case T_INT: 99715931Smckusick f.pdouble = atof(r->const_node.cptr); 998771Speter conint: 99915931Smckusick if (f.pdouble > MAXINT || f.pdouble < MININT) { 1000771Speter error("Constant too large for this implementation"); 100115931Smckusick return (NLNIL); 1002771Speter } 100315931Smckusick l = f.pdouble; 100410364Smckusick # ifdef OBJ 100510364Smckusick if (bytes(l, l) <= 2) { 100615931Smckusick (void) put(2, O_CON2, ( short ) l); 100710364Smckusick return (nl+T2INT); 100810364Smckusick } 100915931Smckusick (void) put(2, O_CON4, l); 101010364Smckusick return (nl+T4INT); 1011771Speter # endif OBJ 1012771Speter # ifdef PC 101310364Smckusick switch (bytes(l, l)) { 101410364Smckusick case 1: 1015*18468Sralph putleaf(PCC_ICON, (int) l, 0, PCCT_CHAR, 101615931Smckusick (char *) 0); 101710364Smckusick return nl+T1INT; 101810364Smckusick case 2: 1019*18468Sralph putleaf(PCC_ICON, (int) l, 0, PCCT_SHORT, 102015931Smckusick (char *) 0); 102110364Smckusick return nl+T2INT; 102210364Smckusick case 4: 1023*18468Sralph putleaf(PCC_ICON, (int) l, 0, PCCT_INT, 102415931Smckusick (char *) 0); 102510364Smckusick return nl+T4INT; 102610364Smckusick } 1027771Speter # endif PC 1028771Speter 1029771Speter /* 1030771Speter * A floating point number 1031771Speter */ 1032771Speter case T_FINT: 1033771Speter # ifdef OBJ 103415931Smckusick (void) put(2, O_CON8, atof(r->const_node.cptr)); 1035771Speter # endif OBJ 1036771Speter # ifdef PC 103715931Smckusick putCON8( atof( r->const_node.cptr ) ); 1038771Speter # endif PC 1039771Speter return (nl+TDOUBLE); 1040771Speter 1041771Speter /* 1042771Speter * Constant strings. Note that constant characters 1043771Speter * are constant strings of length one; there is 1044771Speter * no constant string of length one. 1045771Speter */ 1046771Speter case T_STRNG: 104715931Smckusick cp = r->const_node.cptr; 1048771Speter if (cp[1] == 0) { 1049771Speter # ifdef OBJ 105015931Smckusick (void) put(2, O_CONC, cp[0]); 1051771Speter # endif OBJ 1052771Speter # ifdef PC 1053*18468Sralph putleaf( PCC_ICON , cp[0] , 0 , PCCT_CHAR , 105415931Smckusick (char *) 0 ); 1055771Speter # endif PC 1056771Speter return (nl+T1CHAR); 1057771Speter } 1058771Speter goto cstrng; 1059771Speter } 1060771Speter 1061771Speter } 1062771Speter } 1063771Speter 1064771Speter /* 1065771Speter * Can a class appear 1066771Speter * in a comparison ? 1067771Speter */ 1068771Speter nocomp(c) 1069771Speter int c; 1070771Speter { 1071771Speter 1072771Speter switch (c) { 1073771Speter case TREC: 10741627Speter if ( line != reccompline ) { 10751627Speter reccompline = line; 10761627Speter warning(); 10771627Speter if ( opt( 's' ) ) { 10781627Speter standard(); 10791627Speter } 1080771Speter error("record comparison is non-standard"); 1081771Speter } 1082771Speter break; 1083771Speter case TFILE: 1084771Speter case TARY: 1085771Speter error("%ss may not participate in comparisons", clnames[c]); 1086771Speter return (1); 1087771Speter } 1088771Speter return (NIL); 1089771Speter } 1090771Speter 1091771Speter /* 1092771Speter * this is sort of like gconst, except it works on expression trees 1093771Speter * rather than declaration trees, and doesn't give error messages for 1094771Speter * non-constant things. 1095771Speter * as a side effect this fills in the con structure that gconst uses. 1096771Speter * this returns TRUE or FALSE. 1097771Speter */ 109815931Smckusick 109915931Smckusick bool 1100771Speter constval(r) 110115931Smckusick register struct tnode *r; 1102771Speter { 1103771Speter register struct nl *np; 110415931Smckusick register struct tnode *cn; 1105771Speter char *cp; 1106771Speter int negd, sgnd; 1107771Speter long ci; 1108771Speter 1109771Speter con.ctype = NIL; 1110771Speter cn = r; 1111771Speter negd = sgnd = 0; 1112771Speter loop: 1113771Speter /* 1114771Speter * cn[2] is nil if error recovery generated a T_STRNG 1115771Speter */ 111615931Smckusick if (cn == TR_NIL || cn->expr_node.lhs == TR_NIL) 1117771Speter return FALSE; 111815931Smckusick switch (cn->tag) { 1119771Speter default: 1120771Speter return FALSE; 1121771Speter case T_MINUS: 1122771Speter negd = 1 - negd; 1123771Speter /* and fall through */ 1124771Speter case T_PLUS: 1125771Speter sgnd++; 112615931Smckusick cn = cn->un_expr.expr; 1127771Speter goto loop; 1128771Speter case T_NIL: 1129771Speter con.cpval = NIL; 1130771Speter con.cival = 0; 1131771Speter con.crval = con.cival; 1132771Speter con.ctype = nl + TNIL; 1133771Speter break; 1134771Speter case T_VAR: 113515931Smckusick np = lookup(cn->var_node.cptr); 113615931Smckusick if (np == NLNIL || np->class != CONST) { 1137771Speter return FALSE; 1138771Speter } 113915931Smckusick if ( cn->var_node.qual != TR_NIL ) { 1140771Speter return FALSE; 1141771Speter } 1142771Speter con.ctype = np->type; 1143771Speter switch (classify(np->type)) { 1144771Speter case TINT: 1145771Speter con.crval = np->range[0]; 1146771Speter break; 1147771Speter case TDOUBLE: 1148771Speter con.crval = np->real; 1149771Speter break; 1150771Speter case TBOOL: 1151771Speter case TCHAR: 1152771Speter case TSCAL: 1153771Speter con.cival = np->value[0]; 1154771Speter con.crval = con.cival; 1155771Speter break; 1156771Speter case TSTR: 115715931Smckusick con.cpval = (char *) np->ptr[0]; 1158771Speter break; 1159771Speter default: 1160771Speter con.ctype = NIL; 1161771Speter return FALSE; 1162771Speter } 1163771Speter break; 1164771Speter case T_BINT: 116515931Smckusick con.crval = a8tol(cn->const_node.cptr); 1166771Speter goto restcon; 1167771Speter case T_INT: 116815931Smckusick con.crval = atof(cn->const_node.cptr); 1169771Speter if (con.crval > MAXINT || con.crval < MININT) { 1170771Speter derror("Constant too large for this implementation"); 1171771Speter con.crval = 0; 1172771Speter } 1173771Speter restcon: 1174771Speter ci = con.crval; 1175771Speter #ifndef PI0 1176771Speter if (bytes(ci, ci) <= 2) 1177771Speter con.ctype = nl+T2INT; 1178771Speter else 1179771Speter #endif 1180771Speter con.ctype = nl+T4INT; 1181771Speter break; 1182771Speter case T_FINT: 1183771Speter con.ctype = nl+TDOUBLE; 118415931Smckusick con.crval = atof(cn->const_node.cptr); 1185771Speter break; 1186771Speter case T_STRNG: 118715931Smckusick cp = cn->const_node.cptr; 1188771Speter if (cp[1] == 0) { 1189771Speter con.ctype = nl+T1CHAR; 1190771Speter con.cival = cp[0]; 1191771Speter con.crval = con.cival; 1192771Speter break; 1193771Speter } 1194771Speter con.ctype = nl+TSTR; 1195771Speter con.cpval = cp; 1196771Speter break; 1197771Speter } 1198771Speter if (sgnd) { 1199771Speter if (isnta(con.ctype, "id")) { 1200771Speter derror("%s constants cannot be signed", nameof(con.ctype)); 1201771Speter return FALSE; 1202771Speter } else if (negd) 1203771Speter con.crval = -con.crval; 1204771Speter } 1205771Speter return TRUE; 1206771Speter } 1207