|
|
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[] = "@(#)case.c 5.2 (Berkeley) 6/5/85"; ! 9: #endif not lint ! 10: ! 11: #include "whoami.h" ! 12: #include "0.h" ! 13: #include "tree.h" ! 14: #include "opcode.h" ! 15: #include "tree_ty.h" ! 16: ! 17: /* ! 18: * The structure used to ! 19: * hold information about ! 20: * each case label. ! 21: */ ! 22: struct ct { ! 23: long clong; ! 24: int cline; ! 25: }; ! 26: ! 27: #ifdef OBJ ! 28: /* ! 29: * Caseop generates the ! 30: * pascal case statement code ! 31: */ ! 32: caseop(rnode) ! 33: WHI_CAS *rnode; ! 34: { ! 35: register struct nl *p; ! 36: register struct ct *ctab; ! 37: register struct tnode *cs; ! 38: extern char *lc; ! 39: double low, high; ! 40: short *brtab; ! 41: char *brtab0; ! 42: char *csend; ! 43: int w, j, m, n; ! 44: int goc; ! 45: bool nr; ! 46: ! 47: goc = gocnt; ! 48: /* ! 49: * Obtain selector attributes: ! 50: * p type ! 51: * w width ! 52: * low lwb(p) ! 53: * high upb(p) ! 54: */ ! 55: p = rvalue(rnode->expr, NLNIL , RREQ ); ! 56: ! 57: { ! 58: register struct nl *cl; ! 59: ! 60: if (p != NLNIL) { ! 61: if (isnta(p, "bcsi")) { ! 62: error("Case selectors cannot be %ss", nameof(p)); ! 63: p = NLNIL; ! 64: } else { ! 65: cl = p; ! 66: if (p->class != (char) RANGE) ! 67: cl = p->type; ! 68: if (cl == NLNIL) ! 69: p = NLNIL; ! 70: else { ! 71: w = width(p); ! 72: #ifdef DEBUG ! 73: if (hp21mx) ! 74: w = 2; ! 75: #endif ! 76: low = cl->range[0]; ! 77: high = cl->range[1]; ! 78: } ! 79: } ! 80: } ! 81: } /* local declaration */ ! 82: { ! 83: struct tnode *cl; /* list node */ ! 84: /* ! 85: * Count # of cases ! 86: */ ! 87: n = 0; ! 88: for (cl = rnode->stmnt_list; cl != TR_NIL; ! 89: cl = cl->list_node.next) { ! 90: cs = cl->list_node.list;; ! 91: if (cs == TR_NIL) ! 92: continue; ! 93: for (cs = cs->c_stmnt.const_list; cs != TR_NIL; ! 94: cs = cs->list_node.next) ! 95: n++; ! 96: } ! 97: } /* local declaration */ ! 98: /* ! 99: * Allocate case table space ! 100: */ ! 101: { ! 102: char *i; ! 103: i = malloc((unsigned) n * sizeof *ctab); ! 104: if (i == 0) { ! 105: error("Ran out of memory (case)"); ! 106: pexit(DIED); ! 107: } ! 108: ctab = (struct ct *) i; ! 109: } ! 110: /* ! 111: * Check the legality of the ! 112: * labels and count the number ! 113: * of good labels ! 114: */ ! 115: { ! 116: register struct tnode *cl; ! 117: m = 0; ! 118: for (cl = rnode->stmnt_list; cl != TR_NIL; ! 119: cl = cl->list_node.next) { ! 120: cs = cl->list_node.list; ! 121: if (cs == TR_NIL) ! 122: continue; ! 123: line = cs->c_stmnt.line_no; ! 124: for (cs = cs->c_stmnt.const_list; cs != TR_NIL; ! 125: cs = cs->list_node.next) { ! 126: gconst(cs->list_node.list); ! 127: if (p == NLNIL || con.ctype == NIL) ! 128: continue; ! 129: if (incompat(con.ctype, p, TR_NIL )) { ! 130: cerror("Case label type clashed with case selector expression type"); ! 131: continue; ! 132: } ! 133: if (con.crval < low || con.crval > high) { ! 134: error("Case label out of range"); ! 135: continue; ! 136: } ! 137: ctab[m].clong = con.crval; ! 138: ctab[m].cline = line; ! 139: m++; ! 140: } ! 141: } ! 142: } /* decl of cl */ ! 143: { ! 144: register int i; ! 145: /* ! 146: * Check for duplicate labels ! 147: */ ! 148: for (i = 0; i < m; i++) ! 149: for (j = 0; j < m; j++) ! 150: if (ctab[i].clong == ctab[j].clong) { ! 151: if (i == j) ! 152: continue; ! 153: if (j < i) ! 154: break; ! 155: error("Multiply defined label in case, lines %d and %d", (char *) ctab[i].cline, (char *) ctab[j].cline); ! 156: } ! 157: } ! 158: /* ! 159: * Put out case operator and ! 160: * leave space for the ! 161: * branch table ! 162: */ ! 163: if (p != NLNIL) { ! 164: (void) put(2, O_CASE1OP + (w >> 1), n); ! 165: brtab0 = lc; ! 166: brtab = ((short *) brtab0); ! 167: putspace(n * 2); ! 168: (void) put(1, O_CASEBEG); ! 169: { ! 170: int i; ! 171: for (i=0; i<m; i++) ! 172: if (w <= 2) ! 173: (void) put(2 ,O_CASE1 + (w >> 1), (int)ctab[i].clong); ! 174: else ! 175: (void) put(2 ,O_CASE4, ctab[i].clong); ! 176: } ! 177: (void) put(1, O_CASEEND); ! 178: } ! 179: csend = getlab(); ! 180: (void) put(2, O_TRA, csend); ! 181: /* ! 182: * Free the case ! 183: * table space. ! 184: */ ! 185: free((char *) ctab); ! 186: /* ! 187: * Generate code for each ! 188: * statement. Patch branch ! 189: * table to beginning of each ! 190: * statement and follow each ! 191: * statement with a branch back ! 192: * to the TRA above. ! 193: */ ! 194: { ! 195: register struct tnode *cl; ! 196: nr = TRUE; ! 197: for (cl = rnode->stmnt_list; cl != TR_NIL; ! 198: cl = cl->list_node.next) { ! 199: cs = cl->list_node.list; ! 200: if (cs == TR_NIL) ! 201: continue; ! 202: if (p != NLNIL) ! 203: for (cs = cs->c_stmnt.const_list; cs != TR_NIL; ! 204: cs = cs->list_node.next) { ! 205: #ifdef ADDR16 ! 206: patchfil(((char *) (brtab - 1)), ! 207: (long)(lc - brtab0), 1); ! 208: #endif ADDR16 ! 209: #ifdef ADDR32 ! 210: ! 211: patchfil( ((unsigned long) (brtab - 1)), ! 212: (long)(lc - brtab0), 1); ! 213: #endif ADDR32 ! 214: brtab++; ! 215: } ! 216: cs = cl->list_node.list; ! 217: putcnt(); ! 218: level++; ! 219: statement(cs->c_stmnt.stmnt); ! 220: nr = (bool)(noreach && nr); ! 221: noreach = FALSE; ! 222: (void) put(2, O_TRA, csend); ! 223: level--; ! 224: if (gotos[cbn]) ! 225: ungoto(); ! 226: } ! 227: } /* decl of cl */ ! 228: /* ! 229: * Patch the termination branch ! 230: */ ! 231: #ifdef ADDR16 ! 232: patch((char *) csend); ! 233: #endif ADDR16 ! 234: #ifdef ADDR32 ! 235: patch((unsigned long) csend); ! 236: #endif ADDR32 ! 237: noreach = nr; ! 238: if (goc != gocnt) ! 239: putcnt(); ! 240: } ! 241: #endif OBJ
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.