|
|
1.1 ! root 1: /* Copyright (c) 1979 Regents of the University of California */ ! 2: ! 3: static char sccsid[] = "@(#)stkrval.c 1.7 2/9/83"; ! 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: return (stackRV(p)); ! 84: # endif OBJ ! 85: # ifdef PC ! 86: q = rvalue( r , contype , required ); ! 87: if (isa(q, "sbci")) { ! 88: sconv(p2type(q),P2INT); ! 89: } ! 90: return q; ! 91: # endif PC ! 92: ! 93: case WITHPTR: ! 94: case REF: ! 95: /* ! 96: * A stklval for these ! 97: * is actually what one ! 98: * might consider a rvalue. ! 99: */ ! 100: ind: ! 101: q = stklval(r, NOFLAGS); ! 102: if (q == NIL) ! 103: return (NIL); ! 104: if (classify(q) == TSTR) ! 105: return(q); ! 106: # ifdef OBJ ! 107: w = width(q); ! 108: switch (w) { ! 109: case 8: ! 110: put(1, O_IND8); ! 111: return(q); ! 112: case 4: ! 113: put(1, O_IND4); ! 114: return(q); ! 115: case 2: ! 116: put(1, O_IND24); ! 117: return(q); ! 118: case 1: ! 119: put(1, O_IND14); ! 120: return(q); ! 121: default: ! 122: put(2, O_IND, w); ! 123: return(q); ! 124: } ! 125: # endif OBJ ! 126: # ifdef PC ! 127: if ( required == RREQ ) { ! 128: putop( P2UNARY P2MUL , p2type( q ) ); ! 129: if (isa(q,"sbci")) { ! 130: sconv(p2type(q),P2INT); ! 131: } ! 132: } ! 133: return q; ! 134: # endif PC ! 135: ! 136: case CONST: ! 137: if (r[3] != NIL) { ! 138: error("%s is a constant and cannot be qualified", r[2]); ! 139: return (NIL); ! 140: } ! 141: q = p->type; ! 142: if (q == NIL) ! 143: return (NIL); ! 144: if (q == nl+TSTR) { ! 145: /* ! 146: * Find the size of the string ! 147: * constant if needed. ! 148: */ ! 149: cp = p->ptr[0]; ! 150: cstrng: ! 151: cp1 = cp; ! 152: for (c = 0; *cp++; c++) ! 153: continue; ! 154: w = c; ! 155: if (contype != NIL && !opt('s')) { ! 156: if (width(contype) < c && classify(contype) == TSTR) { ! 157: error("Constant string too long"); ! 158: return (NIL); ! 159: } ! 160: w = width(contype); ! 161: } ! 162: # ifdef OBJ ! 163: put(2, O_LVCON, lenstr(cp1, w - c)); ! 164: putstr(cp1, w - c); ! 165: # endif OBJ ! 166: # ifdef PC ! 167: putCONG( cp1 , w , LREQ ); ! 168: # endif PC ! 169: /* ! 170: * Define the string temporarily ! 171: * so later people can know its ! 172: * width. ! 173: * cleaned out by stat. ! 174: */ ! 175: q = defnl(0, STR, 0, w); ! 176: q->type = q; ! 177: return (q); ! 178: } ! 179: if (q == nl+T1CHAR) { ! 180: # ifdef OBJ ! 181: put(2, O_CONC4, (int)p->value[0]); ! 182: # endif OBJ ! 183: # ifdef PC ! 184: putleaf(P2ICON, p -> value[0], 0, P2INT, 0); ! 185: # endif PC ! 186: return(q); ! 187: } ! 188: /* ! 189: * Every other kind of constant here ! 190: */ ! 191: # ifdef OBJ ! 192: switch (width(q)) { ! 193: case 8: ! 194: #ifndef DEBUG ! 195: put(2, O_CON8, p->real); ! 196: return(q); ! 197: #else ! 198: if (hp21mx) { ! 199: f = p->real; ! 200: conv(&f); ! 201: l = f.plong; ! 202: put(2, O_CON4, l); ! 203: } else ! 204: put(2, O_CON8, p->real); ! 205: return(q); ! 206: #endif ! 207: case 4: ! 208: put(2, O_CON4, p->range[0]); ! 209: return(q); ! 210: case 2: ! 211: put(2, O_CON24, (short)p->range[0]); ! 212: return(q); ! 213: case 1: ! 214: put(2, O_CON14, p->value[0]); ! 215: return(q); ! 216: default: ! 217: panic("stkrval"); ! 218: } ! 219: # endif OBJ ! 220: # ifdef PC ! 221: q = rvalue( r , contype , required ); ! 222: if (isa(q,"sbci")) { ! 223: sconv(p2type(q),P2INT); ! 224: } ! 225: return q; ! 226: # endif PC ! 227: ! 228: case FUNC: ! 229: case FFUNC: ! 230: /* ! 231: * Function call ! 232: */ ! 233: pt = (int **)r[3]; ! 234: if (pt != NIL) { ! 235: switch (pt[1][0]) { ! 236: case T_PTR: ! 237: case T_ARGL: ! 238: case T_ARY: ! 239: case T_FIELD: ! 240: error("Can't qualify a function result value"); ! 241: return (NIL); ! 242: } ! 243: } ! 244: # ifdef OBJ ! 245: q = p->type; ! 246: if (classify(q) == TSTR) { ! 247: c = width(q); ! 248: put(2, O_LVCON, even(c+1)); ! 249: putstr("", c); ! 250: put(1, PTR_DUP); ! 251: p = funccod(r); ! 252: put(2, O_AS, c); ! 253: return(p); ! 254: } ! 255: p = funccod(r); ! 256: if (width(p) <= 2) ! 257: put(1, O_STOI); ! 258: # endif OBJ ! 259: # ifdef PC ! 260: p = pcfunccod( r ); ! 261: if (isa(p,"sbci")) { ! 262: sconv(p2type(p),P2INT); ! 263: } ! 264: # endif PC ! 265: return (p); ! 266: ! 267: case TYPE: ! 268: error("Type names (e.g. %s) allowed only in declarations", p->symbol); ! 269: return (NIL); ! 270: ! 271: case PROC: ! 272: case FPROC: ! 273: error("Procedure %s found where expression required", p->symbol); ! 274: return (NIL); ! 275: default: ! 276: panic("stkrvid"); ! 277: } ! 278: case T_PLUS: ! 279: case T_MINUS: ! 280: case T_NOT: ! 281: case T_AND: ! 282: case T_OR: ! 283: case T_DIVD: ! 284: case T_MULT: ! 285: case T_SUB: ! 286: case T_ADD: ! 287: case T_MOD: ! 288: case T_DIV: ! 289: case T_EQ: ! 290: case T_NE: ! 291: case T_GE: ! 292: case T_LE: ! 293: case T_GT: ! 294: case T_LT: ! 295: case T_IN: ! 296: p = rvalue(r, contype , required ); ! 297: # ifdef OBJ ! 298: if (width(p) <= 2) ! 299: put(1, O_STOI); ! 300: # endif OBJ ! 301: # ifdef PC ! 302: if (isa(p,"sbci")) { ! 303: sconv(p2type(p),P2INT); ! 304: } ! 305: # endif PC ! 306: return (p); ! 307: case T_CSET: ! 308: p = rvalue(r, contype , required ); ! 309: return (p); ! 310: default: ! 311: if (r[2] == NIL) ! 312: return (NIL); ! 313: switch (r[0]) { ! 314: default: ! 315: panic("stkrval3"); ! 316: ! 317: /* ! 318: * An octal number ! 319: */ ! 320: case T_BINT: ! 321: f = a8tol(r[2]); ! 322: goto conint; ! 323: ! 324: /* ! 325: * A decimal number ! 326: */ ! 327: case T_INT: ! 328: f = atof(r[2]); ! 329: conint: ! 330: if (f > MAXINT || f < MININT) { ! 331: error("Constant too large for this implementation"); ! 332: return (NIL); ! 333: } ! 334: l = f; ! 335: if (bytes(l, l) <= 2) { ! 336: # ifdef OBJ ! 337: put(2, O_CON24, (short)l); ! 338: # endif OBJ ! 339: # ifdef PC ! 340: putleaf( P2ICON , (short) l , 0 , P2INT , 0 ); ! 341: # endif PC ! 342: return(nl+T4INT); ! 343: } ! 344: # ifdef OBJ ! 345: put(2, O_CON4, l); ! 346: # endif OBJ ! 347: # ifdef PC ! 348: putleaf( P2ICON , l , 0 , P2INT , 0 ); ! 349: # endif PC ! 350: return (nl+T4INT); ! 351: ! 352: /* ! 353: * A floating point number ! 354: */ ! 355: case T_FINT: ! 356: # ifdef OBJ ! 357: put(2, O_CON8, atof(r[2])); ! 358: # endif OBJ ! 359: # ifdef PC ! 360: putCON8( atof( r[2] ) ); ! 361: # endif PC ! 362: return (nl+TDOUBLE); ! 363: ! 364: /* ! 365: * Constant strings. Note that constant characters ! 366: * are constant strings of length one; there is ! 367: * no constant string of length one. ! 368: */ ! 369: case T_STRNG: ! 370: cp = r[2]; ! 371: if (cp[1] == 0) { ! 372: # ifdef OBJ ! 373: put(2, O_CONC4, cp[0]); ! 374: # endif OBJ ! 375: # ifdef PC ! 376: putleaf( P2ICON , cp[0] , 0 , P2INT , 0 ); ! 377: # endif PC ! 378: return(nl+T1CHAR); ! 379: } ! 380: goto cstrng; ! 381: } ! 382: ! 383: } ! 384: } ! 385: ! 386: #ifdef OBJ ! 387: /* ! 388: * push a value onto the interpreter stack, longword aligned. ! 389: */ ! 390: stackRV(p) ! 391: struct nl *p; ! 392: { ! 393: struct nl *q; ! 394: int w, bn; ! 395: ! 396: q = p->type; ! 397: if (q == NIL) ! 398: return (NIL); ! 399: bn = BLOCKNO(p->nl_block); ! 400: w = width(q); ! 401: switch (w) { ! 402: case 8: ! 403: put(2, O_RV8 | bn << 8+INDX, (int)p->value[0]); ! 404: break; ! 405: case 4: ! 406: put(2, O_RV4 | bn << 8+INDX, (int)p->value[0]); ! 407: break; ! 408: case 2: ! 409: put(2, O_RV24 | bn << 8+INDX, (int)p->value[0]); ! 410: break; ! 411: case 1: ! 412: put(2, O_RV14 | bn << 8+INDX, (int)p->value[0]); ! 413: break; ! 414: default: ! 415: put(3, O_RV | bn << 8+INDX, (int)p->value[0], w); ! 416: break; ! 417: } ! 418: return (q); ! 419: } ! 420: #endif OBJ
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.