1775Speter /* Copyright (c) 1979 Regents of the University of California */ 2775Speter 3*10360Smckusick static char sccsid[] = "@(#)stkrval.c 1.5 01/17/83"; 4775Speter 5775Speter #include "whoami.h" 6775Speter #include "0.h" 7775Speter #include "tree.h" 8775Speter #include "opcode.h" 9775Speter #include "objfmt.h" 10775Speter #ifdef PC 11775Speter # include "pcops.h" 12775Speter #endif PC 13775Speter 14775Speter /* 15775Speter * stkrval Rvalue - an expression, and coerce it to be a stack quantity. 16775Speter * 17775Speter * Contype is the type that the caller would prefer, nand is important 18775Speter * if constant sets or constant strings are involved, the latter 19775Speter * because of string padding. 20775Speter */ 21775Speter /* 22775Speter * for the obj version, this is a copy of rvalue hacked to use fancy new 23775Speter * push-onto-stack-and-convert opcodes. 24775Speter * for the pc version, i just call rvalue and convert if i have to, 25775Speter * based on the return type of rvalue. 26775Speter */ 27775Speter struct nl * 28775Speter stkrval(r, contype , required ) 29775Speter register int *r; 30775Speter struct nl *contype; 31775Speter long required; 32775Speter { 33775Speter register struct nl *p; 34775Speter register struct nl *q; 35775Speter register char *cp, *cp1; 36775Speter register int c, w; 37775Speter int **pt; 38775Speter long l; 39775Speter double f; 40775Speter 41775Speter if (r == NIL) 42775Speter return (NIL); 43775Speter if (nowexp(r)) 44775Speter return (NIL); 45775Speter /* 46775Speter * The root of the tree tells us what sort of expression we have. 47775Speter */ 48775Speter switch (r[0]) { 49775Speter 50775Speter /* 51775Speter * The constant nil 52775Speter */ 53775Speter case T_NIL: 54775Speter # ifdef OBJ 55775Speter put(2, O_CON14, 0); 56775Speter # endif OBJ 57775Speter # ifdef PC 58775Speter putleaf( P2ICON , 0 , 0 , P2INT , 0 ); 59775Speter # endif PC 60775Speter return (nl+TNIL); 61775Speter 62775Speter case T_FCALL: 63775Speter case T_VAR: 64775Speter p = lookup(r[2]); 65775Speter if (p == NIL || p->class == BADUSE) 66775Speter return (NIL); 67775Speter switch (p->class) { 68775Speter case VAR: 69775Speter /* 703080Smckusic * if a variable is 71775Speter * qualified then get 72775Speter * the rvalue by a 73775Speter * stklval and an ind. 74775Speter */ 75775Speter if (r[3] != NIL) 76775Speter goto ind; 77775Speter q = p->type; 78775Speter if (q == NIL) 79775Speter return (NIL); 80775Speter if (classify(q) == TSTR) 81775Speter return(stklval(r, NOFLAGS)); 82775Speter # ifdef OBJ 83775Speter w = width(q); 84775Speter switch (w) { 85775Speter case 8: 863080Smckusic put(2, O_RV8 | bn << 8+INDX, 873080Smckusic (int)p->value[0]); 88775Speter return(q); 89775Speter case 4: 903080Smckusic put(2, O_RV4 | bn << 8+INDX, 913080Smckusic (int)p->value[0]); 92775Speter return(q); 93775Speter case 2: 943080Smckusic put(2, O_RV24 | bn << 8+INDX, 953080Smckusic (int)p->value[0]); 96775Speter return(q); 97775Speter case 1: 983080Smckusic put(2, O_RV14 | bn << 8+INDX, 993080Smckusic (int)p->value[0]); 100775Speter return(q); 101775Speter default: 1023080Smckusic put(3, O_RV | bn << 8+INDX, 1033080Smckusic (int)p->value[0], w); 104775Speter return(q); 105775Speter } 106775Speter # endif OBJ 107775Speter # ifdef PC 108*10360Smckusick q = rvalue( r , contype , required ); 109*10360Smckusick if (isa(q, "sbci")) { 110*10360Smckusick sconv(p2type(q),P2INT); 111*10360Smckusick } 112*10360Smckusick return q; 113775Speter # endif PC 114775Speter 115775Speter case WITHPTR: 116775Speter case REF: 117775Speter /* 118775Speter * A stklval for these 119775Speter * is actually what one 120775Speter * might consider a rvalue. 121775Speter */ 122775Speter ind: 123775Speter q = stklval(r, NOFLAGS); 124775Speter if (q == NIL) 125775Speter return (NIL); 126775Speter if (classify(q) == TSTR) 127775Speter return(q); 128775Speter # ifdef OBJ 129775Speter w = width(q); 130775Speter switch (w) { 131775Speter case 8: 132775Speter put(1, O_IND8); 133775Speter return(q); 134775Speter case 4: 135775Speter put(1, O_IND4); 136775Speter return(q); 137775Speter case 2: 138775Speter put(1, O_IND24); 139775Speter return(q); 140775Speter case 1: 141775Speter put(1, O_IND14); 142775Speter return(q); 143775Speter default: 144775Speter put(2, O_IND, w); 145775Speter return(q); 146775Speter } 147775Speter # endif OBJ 148775Speter # ifdef PC 149775Speter if ( required == RREQ ) { 150775Speter putop( P2UNARY P2MUL , p2type( q ) ); 151*10360Smckusick if (isa(q,"sbci")) { 152*10360Smckusick sconv(p2type(q),P2INT); 153*10360Smckusick } 154775Speter } 155775Speter return q; 156775Speter # endif PC 157775Speter 158775Speter case CONST: 159775Speter if (r[3] != NIL) { 160775Speter error("%s is a constant and cannot be qualified", r[2]); 161775Speter return (NIL); 162775Speter } 163775Speter q = p->type; 164775Speter if (q == NIL) 165775Speter return (NIL); 166775Speter if (q == nl+TSTR) { 167775Speter /* 168775Speter * Find the size of the string 169775Speter * constant if needed. 170775Speter */ 171775Speter cp = p->ptr[0]; 172775Speter cstrng: 173775Speter cp1 = cp; 174775Speter for (c = 0; *cp++; c++) 175775Speter continue; 176775Speter w = 0; 177775Speter if (contype != NIL && !opt('s')) { 178775Speter if (width(contype) < c && classify(contype) == TSTR) { 179775Speter error("Constant string too long"); 180775Speter return (NIL); 181775Speter } 182775Speter w = width(contype) - c; 183775Speter } 184775Speter # ifdef OBJ 185775Speter put(2, O_LVCON, lenstr(cp1, w)); 186775Speter putstr(cp1, w); 187775Speter # endif OBJ 188775Speter # ifdef PC 189775Speter putCONG( cp1 , c + w , LREQ ); 190775Speter # endif PC 191775Speter /* 192775Speter * Define the string temporarily 193775Speter * so later people can know its 194775Speter * width. 195775Speter * cleaned out by stat. 196775Speter */ 197775Speter q = defnl(0, STR, 0, c); 198775Speter q->type = q; 199775Speter return (q); 200775Speter } 201775Speter if (q == nl+T1CHAR) { 202775Speter # ifdef OBJ 2033080Smckusic put(2, O_CONC4, (int)p->value[0]); 204775Speter # endif OBJ 205775Speter # ifdef PC 206*10360Smckusick putleaf(P2ICON, p -> value[0], 0, P2INT, 0); 207775Speter # endif PC 208775Speter return(q); 209775Speter } 210775Speter /* 211775Speter * Every other kind of constant here 212775Speter */ 213775Speter # ifdef OBJ 214775Speter switch (width(q)) { 215775Speter case 8: 216775Speter #ifndef DEBUG 217775Speter put(2, O_CON8, p->real); 218775Speter return(q); 219775Speter #else 220775Speter if (hp21mx) { 221775Speter f = p->real; 222775Speter conv(&f); 223775Speter l = f.plong; 224775Speter put(2, O_CON4, l); 225775Speter } else 226775Speter put(2, O_CON8, p->real); 227775Speter return(q); 228775Speter #endif 229775Speter case 4: 230775Speter put(2, O_CON4, p->range[0]); 231775Speter return(q); 232775Speter case 2: 233775Speter put(2, O_CON24, (short)p->range[0]); 234775Speter return(q); 235775Speter case 1: 2363080Smckusic put(2, O_CON14, p->value[0]); 237775Speter return(q); 238775Speter default: 239775Speter panic("stkrval"); 240775Speter } 241775Speter # endif OBJ 242775Speter # ifdef PC 243*10360Smckusick q = rvalue( r , contype , required ); 244*10360Smckusick if (isa(q,"sbci")) { 245*10360Smckusick sconv(p2type(q),P2INT); 246*10360Smckusick } 247*10360Smckusick return q; 248775Speter # endif PC 249775Speter 250775Speter case FUNC: 2511201Speter case FFUNC: 252775Speter /* 253775Speter * Function call 254775Speter */ 255775Speter pt = (int **)r[3]; 256775Speter if (pt != NIL) { 257775Speter switch (pt[1][0]) { 258775Speter case T_PTR: 259775Speter case T_ARGL: 260775Speter case T_ARY: 261775Speter case T_FIELD: 262775Speter error("Can't qualify a function result value"); 263775Speter return (NIL); 264775Speter } 265775Speter } 266775Speter # ifdef OBJ 267775Speter q = p->type; 268775Speter if (classify(q) == TSTR) { 269775Speter c = width(q); 270775Speter put(2, O_LVCON, even(c+1)); 271775Speter putstr("", c); 2723080Smckusic put(1, PTR_DUP); 273775Speter p = funccod(r); 274775Speter put(2, O_AS, c); 275775Speter return(p); 276775Speter } 277775Speter p = funccod(r); 278775Speter if (width(p) <= 2) 279775Speter put(1, O_STOI); 280775Speter # endif OBJ 281775Speter # ifdef PC 282775Speter p = pcfunccod( r ); 283*10360Smckusick if (isa(p,"sbci")) { 284*10360Smckusick sconv(p2type(p),P2INT); 285*10360Smckusick } 286775Speter # endif PC 287775Speter return (p); 288775Speter 289775Speter case TYPE: 290775Speter error("Type names (e.g. %s) allowed only in declarations", p->symbol); 291775Speter return (NIL); 292775Speter 293775Speter case PROC: 2941201Speter case FPROC: 295775Speter error("Procedure %s found where expression required", p->symbol); 296775Speter return (NIL); 297775Speter default: 298775Speter panic("stkrvid"); 299775Speter } 300775Speter case T_PLUS: 301775Speter case T_MINUS: 302775Speter case T_NOT: 303775Speter case T_AND: 304775Speter case T_OR: 305775Speter case T_DIVD: 306775Speter case T_MULT: 307775Speter case T_SUB: 308775Speter case T_ADD: 309775Speter case T_MOD: 310775Speter case T_DIV: 311775Speter case T_EQ: 312775Speter case T_NE: 313775Speter case T_GE: 314775Speter case T_LE: 315775Speter case T_GT: 316775Speter case T_LT: 317775Speter case T_IN: 318775Speter p = rvalue(r, contype , required ); 319775Speter # ifdef OBJ 320775Speter if (width(p) <= 2) 321775Speter put(1, O_STOI); 322775Speter # endif OBJ 323*10360Smckusick # ifdef PC 324*10360Smckusick if (isa(p,"sbci")) { 325*10360Smckusick sconv(p2type(p),P2INT); 326*10360Smckusick } 327*10360Smckusick # endif PC 328775Speter return (p); 329909Speter case T_CSET: 330909Speter p = rvalue(r, contype , required ); 331909Speter return (p); 332775Speter default: 333775Speter if (r[2] == NIL) 334775Speter return (NIL); 335775Speter switch (r[0]) { 336775Speter default: 337775Speter panic("stkrval3"); 338775Speter 339775Speter /* 340775Speter * An octal number 341775Speter */ 342775Speter case T_BINT: 343775Speter f = a8tol(r[2]); 344775Speter goto conint; 345775Speter 346775Speter /* 347775Speter * A decimal number 348775Speter */ 349775Speter case T_INT: 350775Speter f = atof(r[2]); 351775Speter conint: 352775Speter if (f > MAXINT || f < MININT) { 353775Speter error("Constant too large for this implementation"); 354775Speter return (NIL); 355775Speter } 356775Speter l = f; 357775Speter if (bytes(l, l) <= 2) { 358775Speter # ifdef OBJ 359775Speter put(2, O_CON24, (short)l); 360775Speter # endif OBJ 361775Speter # ifdef PC 362775Speter putleaf( P2ICON , (short) l , 0 , P2INT , 0 ); 363775Speter # endif PC 364775Speter return(nl+T4INT); 365775Speter } 366775Speter # ifdef OBJ 367775Speter put(2, O_CON4, l); 368775Speter # endif OBJ 369775Speter # ifdef PC 370775Speter putleaf( P2ICON , l , 0 , P2INT , 0 ); 371775Speter # endif PC 372775Speter return (nl+T4INT); 373775Speter 374775Speter /* 375775Speter * A floating point number 376775Speter */ 377775Speter case T_FINT: 378775Speter # ifdef OBJ 379775Speter put(2, O_CON8, atof(r[2])); 380775Speter # endif OBJ 381775Speter # ifdef PC 382775Speter putCON8( atof( r[2] ) ); 383775Speter # endif PC 384775Speter return (nl+TDOUBLE); 385775Speter 386775Speter /* 387775Speter * Constant strings. Note that constant characters 388775Speter * are constant strings of length one; there is 389775Speter * no constant string of length one. 390775Speter */ 391775Speter case T_STRNG: 392775Speter cp = r[2]; 393775Speter if (cp[1] == 0) { 394775Speter # ifdef OBJ 395775Speter put(2, O_CONC4, cp[0]); 396775Speter # endif OBJ 397775Speter # ifdef PC 398*10360Smckusick putleaf( P2ICON , cp[0] , 0 , P2INT , 0 ); 399775Speter # endif PC 400775Speter return(nl+T1CHAR); 401775Speter } 402775Speter goto cstrng; 403775Speter } 404775Speter 405775Speter } 406775Speter } 407