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