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