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