|
|
1.1 ! root 1: /* Copyright (c) 1979 Regents of the University of California */ ! 2: # ! 3: /* ! 4: * pi - Pascal interpreter code translator ! 5: * ! 6: * Charles Haley, Bill Joy UCB ! 7: * Version 1.2 November 1978 ! 8: */ ! 9: ! 10: #include "whoami" ! 11: #include "0.h" ! 12: #include "tree.h" ! 13: #include "opcode.h" ! 14: ! 15: extern int flagwas; ! 16: /* ! 17: * Lvalue computes the address ! 18: * of a qualified name and ! 19: * leaves it on the stack. ! 20: */ ! 21: struct nl * ! 22: lvalue(r, modflag) ! 23: int *r, modflag; ! 24: { ! 25: register struct nl *p; ! 26: struct nl *firstp, *lastp; ! 27: register *c, *co; ! 28: int f, o; ! 29: /* ! 30: * Note that the local optimizations ! 31: * done here for offsets would more ! 32: * appropriately be done in put. ! 33: */ ! 34: int tr[2], trp[3]; ! 35: ! 36: if (r == NIL) ! 37: return (NIL); ! 38: if (nowexp(r)) ! 39: return (NIL); ! 40: if (r[0] != T_VAR) { ! 41: error("Variable required"); /* Pass mesgs down from pt of call ? */ ! 42: return (NIL); ! 43: } ! 44: firstp = p = lookup(r[2]); ! 45: if (p == NIL) ! 46: return (NIL); ! 47: c = r[3]; ! 48: if ((modflag & NOUSE) && !lptr(c)) ! 49: p->nl_flags = flagwas; ! 50: if (modflag & MOD) ! 51: p->nl_flags |= NMOD; ! 52: /* ! 53: * Only possibilities for p->class here ! 54: * are the named classes, i.e. CONST, TYPE ! 55: * VAR, PROC, FUNC, REF, or a WITHPTR. ! 56: */ ! 57: switch (p->class) { ! 58: case WITHPTR: ! 59: /* ! 60: * Construct the tree implied by ! 61: * the with statement ! 62: */ ! 63: trp[0] = T_LISTPP; ! 64: trp[1] = tr; ! 65: trp[2] = r[3]; ! 66: tr[0] = T_FIELD; ! 67: tr[1] = r[2]; ! 68: c = trp; ! 69: # ifdef PTREE ! 70: /* ! 71: * mung r[4] to say which field this T_VAR is ! 72: * for VarCopy ! 73: */ ! 74: r[4] = reclook( p -> type , r[2] ); ! 75: # endif ! 76: /* and fall through */ ! 77: case REF: ! 78: /* ! 79: * Obtain the indirect word ! 80: * of the WITHPTR or REF ! 81: * as the base of our lvalue ! 82: */ ! 83: # ifdef VAX ! 84: put2 ( O_RV4 | bn << 9 , p->value[0] ); ! 85: # endif ! 86: # ifdef PDP11 ! 87: put2(O_RV2 | bn << 9, p->value[0]); ! 88: # endif ! 89: f = 0; /* have an lv on stack */ ! 90: o = 0; ! 91: break; ! 92: case VAR: ! 93: f = 1; /* no lv on stack yet */ ! 94: o = p->value[0]; ! 95: break; ! 96: default: ! 97: error("%s %s found where variable required", classes[p->class], p->symbol); ! 98: return (NIL); ! 99: } ! 100: /* ! 101: * Loop and handle each ! 102: * qualification on the name ! 103: */ ! 104: if (c == NIL && (modflag&ASGN) && p->value[NL_FORV]) { ! 105: error("Can't modify the for variable %s in the range of the loop", p->symbol); ! 106: return (NIL); ! 107: } ! 108: for (; c != NIL; c = c[2]) { ! 109: co = c[1]; ! 110: if (co == NIL) ! 111: return (NIL); ! 112: lastp = p; ! 113: p = p->type; ! 114: if (p == NIL) ! 115: return (NIL); ! 116: switch (co[0]) { ! 117: case T_PTR: ! 118: /* ! 119: * Pointer qualification. ! 120: */ ! 121: lastp->nl_flags |= NUSED; ! 122: if (p->class != PTR && p->class != FILET) { ! 123: error("^ allowed only on files and pointers, not on %ss", nameof(p)); ! 124: goto bad; ! 125: } ! 126: if (f) ! 127: # ifdef VAX ! 128: put2 ( O_RV4 | bn << 9 , o ); ! 129: # endif ! 130: # ifdef PDP11 ! 131: put2(O_RV2 | bn<<9, o); ! 132: # endif ! 133: else { ! 134: if (o) ! 135: put2(O_OFF, o); ! 136: # ifdef VAX ! 137: put1 ( O_IND4 ); ! 138: # endif ! 139: # ifdef PDP11 ! 140: put1(O_IND2); ! 141: # endif ! 142: } ! 143: /* ! 144: * Pointer cannot be ! 145: * nil and file cannot ! 146: * be at end-of-file. ! 147: */ ! 148: put1(p->class == FILET ? O_FNIL : O_NIL); ! 149: f = o = 0; ! 150: continue; ! 151: case T_ARGL: ! 152: if (p->class != ARRAY) { ! 153: if (lastp == firstp) ! 154: error("%s is a %s, not a function", r[2], classes[firstp->class]); ! 155: else ! 156: error("Illegal function qualificiation"); ! 157: return (NIL); ! 158: } ! 159: recovered(); ! 160: error("Pascal uses [] for subscripting, not ()"); ! 161: case T_ARY: ! 162: if (p->class != ARRAY) { ! 163: error("Subscripting allowed only on arrays, not on %ss", nameof(p)); ! 164: goto bad; ! 165: } ! 166: if (f) ! 167: put2(O_LV | bn<<9, o); ! 168: else if (o) ! 169: put2(O_OFF, o); ! 170: switch (arycod(p, co[1])) { ! 171: case 0: ! 172: return (NIL); ! 173: case -1: ! 174: goto bad; ! 175: } ! 176: f = o = 0; ! 177: continue; ! 178: case T_FIELD: ! 179: /* ! 180: * Field names are just ! 181: * an offset with some ! 182: * semantic checking. ! 183: */ ! 184: if (p->class != RECORD) { ! 185: error(". allowed only on records, not on %ss", nameof(p)); ! 186: goto bad; ! 187: } ! 188: if (co[1] == NIL) ! 189: return (NIL); ! 190: p = reclook(p, co[1]); ! 191: if (p == NIL) { ! 192: error("%s is not a field in this record", co[1]); ! 193: goto bad; ! 194: } ! 195: # ifdef PTREE ! 196: /* ! 197: * mung co[3] to indicate which field ! 198: * this is for SelCopy ! 199: */ ! 200: co[3] = p; ! 201: # endif ! 202: if (modflag & MOD) ! 203: p->nl_flags |= NMOD; ! 204: if ((modflag & NOUSE) == 0 || lptr(c[2])) ! 205: p->nl_flags |= NUSED; ! 206: o += p->value[0]; ! 207: continue; ! 208: default: ! 209: panic("lval2"); ! 210: } ! 211: } ! 212: if (f) ! 213: put2(O_LV | bn<<9, o); ! 214: else if (o) ! 215: put2(O_OFF, o); ! 216: return (p->type); ! 217: bad: ! 218: cerror("Error occurred on qualification of %s", r[2]); ! 219: return (NIL); ! 220: } ! 221: ! 222: lptr(c) ! 223: register int *c; ! 224: { ! 225: register int *co; ! 226: ! 227: for (; c != NIL; c = c[2]) { ! 228: co = c[1]; ! 229: if (co == NIL) ! 230: return (NIL); ! 231: switch (co[0]) { ! 232: ! 233: case T_PTR: ! 234: return (1); ! 235: case T_ARGL: ! 236: return (0); ! 237: case T_ARY: ! 238: case T_FIELD: ! 239: continue; ! 240: default: ! 241: panic("lptr"); ! 242: } ! 243: } ! 244: return (0); ! 245: } ! 246: ! 247: /* ! 248: * Arycod does the ! 249: * code generation ! 250: * for subscripting. ! 251: */ ! 252: arycod(np, el) ! 253: struct nl *np; ! 254: int *el; ! 255: { ! 256: register struct nl *p, *ap; ! 257: int i, d, v, v1; ! 258: int w; ! 259: ! 260: p = np; ! 261: if (el == NIL) ! 262: return (0); ! 263: d = p->value[0]; ! 264: /* ! 265: * Check each subscript ! 266: */ ! 267: for (i = 1; i <= d; i++) { ! 268: if (el == NIL) { ! 269: error("Too few subscripts (%d given, %d required)", i-1, d); ! 270: return (-1); ! 271: } ! 272: p = p->chain; ! 273: ap = rvalue(el[1], NLNIL); ! 274: if (ap == NIL) ! 275: return (0); ! 276: if (incompat(ap, p->type, el[1])) { ! 277: cerror("Array index type incompatible with declared index type"); ! 278: if (d != 1) ! 279: cerror("Error occurred on index number %d", i); ! 280: return (-1); ! 281: } ! 282: w = aryconst(np, i); ! 283: if (opt('t') == 0) ! 284: switch (w) { ! 285: case 8: ! 286: w = 6; ! 287: case 4: ! 288: case 2: ! 289: case 1: ! 290: put2((width(ap) != 4 ? O_INX2P2 : O_INX4P2) | (w & ~1) << 7, ( short ) p->range[0]); ! 291: el = el[2]; ! 292: continue; ! 293: } ! 294: put(4, width(ap) != 4 ? O_INX2 : O_INX4,w,( short ) p->range[0], ! 295: ( short ) ( p->range[1] - p->range[0] ) ); ! 296: el = el[2]; ! 297: } ! 298: if (el != NIL) { ! 299: do { ! 300: el = el[2]; ! 301: i++; ! 302: } while (el != NIL); ! 303: error("Too many subscripts (%d given, %d required)", i-1, d); ! 304: return (-1); ! 305: } ! 306: return (1); ! 307: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.