1: #include <stdio.h> 2: #include "1.incl.h" 3: #include "def.h" 4: 5: 6: recognize(type, ifflag) /* if ifflag = 1, statement is if()type; otherwise is type */ 7: int type, ifflag; /* do whatever is needed for this statement */ 8: { 9: int *arctype, i, sp; 10: VERT num, num1, nest, loophead; 11: extern long label(); 12: long *arclab; 13: if (nlabs > 3) sp = nlabs; else sp = 3; 14: arctype = challoc(sizeof(*arctype) * sp); arclab = challoc(sizeof(*arclab) * sp); 15: for( i=0; i < endbuf; i++) {if (buffer[i] == '~') buffer[i] = ' ';} 16: loophead = nest = innerdo(label(0)); 17: if (DEFINED(nest)) 18: { 19: /* this statement is last line of do loop */ 20: nest = ARC(nest,0); /* nest is ITERVX of the innermost do ending here */ 21: } 22: 23: 24: if (ifflag) 25: { 26: if (type == ungo) 27: { 28: arctype[0] = -2; 29: arclab[0] = label(1); 30: } 31: else 32: arctype[0] = 0; 33: 34: arctype[1] = (nest >= 0) ? nest : -2; 35: arclab[1] = implicit; 36: num1 = makenode(IFVX,TRUE,TRUE,label(0),2,arctype,arclab); 37: PRED(num1) = pred; 38: } 39: 40: arctype[0] = (nest >= 0) ? nest : -2; 41: arclab[0] = implicit; 42: 43: switch(type) 44: { 45: case ungo: 46: if (!ifflag) 47: { 48: connect(label(1),implicit); 49: if (label(0) != implicit) connect(label(1),label(0)); 50: } 51: break; 52: case RETVX: 53: case STOPVX: 54: if (type == RETVX) 55: { 56: if (retvert == UNDEFINED) 57: retvert = makenode(type,FALSE,FALSE,implicit,0,arctype,arclab); 58: num = retvert; 59: } 60: else 61: { 62: if (stopvert == UNDEFINED) 63: stopvert = makenode(type,FALSE,FALSE,implicit,0,arctype,arclab); 64: num = stopvert; 65: } 66: if (!ifflag) 67: { 68: fixvalue(implicit,num); 69: clear(implicit); 70: if (label(0) != implicit) fixvalue(label(0),num); 71: } 72: break; 73: 74: 75: case contst: 76: contin(label(0),loophead); 77: break; 78: 79: case FMTVX: 80: num = makenode(FMTVX,FALSE,TRUE,implicit,0,arctype,arclab); 81: BEGCODE(num) = comchar + 1 - rtnbeg; 82: if((unsigned)(BEGCODE(num))!=comchar+1-rtnbeg) 83: faterr("program too long","",""); 84: ONDISK(num) = endline - endcom; 85: if (label(0) != implicit) 86: fixvalue(label(0),num); 87: FMTLST = append(num,FMTLST); 88: break; 89: case STLNVX: 90: if (DEFINED(stflag) && !ifflag && (label(0) == implicit)) 91: { 92: ++CODELINES(stflag); 93: ONDISK(stflag) += endline - begline + 1; 94: } 95: else 96: { 97: num = makenode(STLNVX,!ifflag,!ifflag,label(0),1,arctype,arclab); 98: if (!ifflag) 99: { 100: stflag = num; 101: BEGCODE(num) = comchar + 1 - rtnbeg; 102: if((unsigned)(BEGCODE(num))!=comchar+1-rtnbeg) 103: faterr("program too long","",""); 104: ONDISK(num) = endline - endcom; 105: CODELINES(num) = 1; 106: } 107: else 108: { 109: BEGCODE(num) = stcode; 110: ONDISK(num) = FALSE; 111: CODELINES(num) = 1; 112: } 113: } 114: break; 115: 116: case DOVX: 117: if (arctype[0] != -2) 118: { 119: error("illegal do range, ","",""); 120: fprintf(stderr," between lines %d and %d\n",begline, endline); 121: exit(1); 122: } 123: arctype[1] = UNDEFINED; 124: num1 = makenode(DOVX,TRUE,TRUE,label(0),2,arctype,arclab); 125: if (++doptr >= maxdo) 126: { 127: faterr("in parsing:\n","do loops nested deeper than allowed",""); 128: } 129: dostack[doptr] = label(1); 130: doloc[doptr] = num1; /* stack link to node after loop */ 131: INC(num1) = inc; 132: num = makenode(ITERVX,TRUE,FALSE,implicit,1,arctype,arclab); 133: ARC(num1,0) = num; 134: FATH(num) = UNDEFINED; /* number of DOVX can change so leave UNDEFINED until later */ 135: break; 136: case arithif: 137: if (label(1) == label(2) || label(1) == 0L) 138: makeif(1,label(0),concat(pred," > 0"),label(3),label(2)); 139: else if (label(1) == label(3) || label(3) == 0L) 140: makeif(1,label(0),concat(pred," == 0"),label(2),label(1)); 141: else if (label(2) == label(3) || label(2) == 0L) 142: makeif(1,label(0),concat(pred," < 0"),label(1),label(3)); 143: else 144: { 145: makeif(1,label(0),concat(pred," < 0"),label(1),implicit); 146: makeif(1,implicit,concat(pred," == 0"),label(2),label(3)); 147: } 148: break; 149: 150: case IOVX: 151: if (endlab) 152: { 153: arctype[1] = -2; 154: arclab[1] = endlab->labelt; 155: } 156: else 157: arctype[1] = UNDEFINED; 158: if (errlab) 159: { 160: arctype[2] = -2; 161: arclab[2] = errlab->labelt; 162: } 163: else 164: arctype[2] = UNDEFINED; 165: num = makenode(IOVX,!ifflag,!ifflag,label(0),3,arctype,arclab); 166: PRERW(num) = prerw; 167: POSTRW(num) = postrw; 168: if (reflab) 169: addref(reflab->labelt, &FMTREF(num)); 170: else 171: FMTREF(num) = UNDEFINED; 172: break; 173: 174: case COMPVX: 175: if (intcase) 176: { 177: num = compcase(ifflag); 178: break; 179: } 180: case ASGOVX: 181: for (i = 0; i < nlabs - 1; i++) 182: { 183: arctype[i] = -2; 184: arclab[i] = label(nlabs-i-1); 185: } 186: num = makenode(type,!ifflag,!ifflag,label(0),nlabs - 1, arctype, arclab); 187: EXP(num) = exp; 188: break; 189: case ASVX: 190: num = makenode(ASVX,!ifflag,!ifflag,label(0),1,arctype,arclab); 191: EXP(num) = exp; 192: addref(label(1),&LABREF(num)); 193: break; 194: case entry: 195: num = makenode(STLNVX,FALSE,TRUE,label(0),1,arctype,arclab); 196: BEGCODE(num) = comchar + 1 - rtnbeg; 197: if((unsigned)(BEGCODE(num))!=comchar+1-rtnbeg) 198: faterr("program too long","",""); 199: ONDISK(num) = endline - endcom; 200: CODELINES(num) = 1; 201: ENTLST = append(num,ENTLST); 202: break; 203: } 204: if (ifflag && type != ungo) 205: { 206: ARC(num1,0) = num; 207: } 208: if (DEFINED(loophead)) nesteddo(label(0), loophead); 209: if (ifflag || DEFINED(loophead) || type != STLNVX) stflag = UNDEFINED; 210: 211: 212: chfree(arctype,sizeof(*arctype) * sp); chfree(arclab,sizeof(*arclab) * sp); 213: if (debug) 214: { 215: fprintf(debfd,"line %d: ", begline); 216: if (ifflag) fprintf(debfd,"if() "); 217: switch(type) 218: {case RETVX: fprintf(debfd,"return"); break; 219: case STOPVX: fprintf(debfd,"stop"); break; 220: case contst: fprintf(debfd,"continue"); break; 221: case ungo: fprintf(debfd,"uncond. goto"); break; 222: case COMPVX: fprintf(debfd,"comp. goto"); break; 223: case ASGOVX: fprintf(debfd,"ass. goto, labs"); break; 224: case ASVX: fprintf(debfd,"label assignment"); break; 225: case STLNVX: fprintf(debfd,"simple statement"); break; 226: case arithif: fprintf(debfd,"arith if"); break; 227: case DOVX: fprintf(debfd,"do "); break; 228: case FMTVX: fprintf(debfd,"format st"); break; 229: case IOVX: fprintf(debfd,"IOVX statement "); break; 230: case entry: fprintf(debfd,"entry statement "); break; 231: } 232: fprintf(debfd,"\n%s\n", buffer); 233: } 234: } 235: 236: 237: 238: makeif(first,labe,test,arc1,arc2) /* construct IFVX with arcs to labels arc1,arc2 */ 239: int first; 240: long labe, arc1,arc2; 241: char *test; 242: { 243: int num, arctype[2]; 244: long arclab[2]; 245: arctype[0] = arctype[1] = -2; 246: arclab[0] = arc1; 247: arclab[1] = arc2; 248: num = makenode(IFVX,first,first,labe,2,arctype,arclab); 249: PRED(num) = test; 250: return(num); 251: } 252: 253: 254: innerdo(labe) /* return number of DOVX associated with labe, or UNDEFINED */ 255: long labe; 256: { 257: if (DEFINED(doptr)) 258: {if (dostack[doptr] == labe) 259: return(doloc[doptr--]); 260: } 261: return(UNDEFINED); 262: } 263: 264: 265: 266: 267: contin(labe,nest) /* handle continue statements */ 268: long labe; 269: int nest; 270: { 271: VERT y; 272: 273: if (!DEFINED(nest)) 274: { /* not nested */ 275: if (labe != implicit) connect(implicit,labe); /* labe pts to next node */ 276: } 277: else 278: { /* nested */ 279: y = ARC(nest,0); 280: fixvalue(labe,y); /* labe pts to ITERVX */ 281: fixvalue(implicit, y); /* implicit links pt to ITERVX */ 282: clear(implicit); 283: } 284: } 285: 286: 287: 288: 289: nesteddo(labe,v) 290: /* if multiple do's end on same label, add arc from inner DOVX 291: to enclosing DOVX; 292: add implicit link out of outermost DOVX with this label */ 293: long labe; 294: int v; 295: { 296: 297: while (DEFINED(doptr) && dostack[doptr] == labe) 298: { 299: ARC(v,1) = ARC(doloc[doptr],0); /*set inner DOVX to point to outer ITERVX */ 300: v = doloc[doptr--]; 301: } 302: addref(implicit, &ARC(v,1)); 303: } 304: 305: 306: 307: compcase(ifflag) /* turn computed goto into case statement */ 308: LOGICAL ifflag; 309: { 310: int *arctype, i, num, d, arct; 311: extern long label(); 312: long *arclab; 313: char *str; 314: arctype = challoc(sizeof(*arctype) * nlabs); 315: arclab = challoc (sizeof(*arclab) * nlabs); 316: 317: d = distinct(linelabs->nxtlab,arctype,arclab,nlabs-1); 318: /* puts distinct labels in arclab, count of each in arctype */ 319: arct = -2; 320: for (i = 0; i < d; ++i) 321: arctype[i] = makenode(ICASVX,FALSE,FALSE,implicit,1,&arct,&arclab[i]); 322: num = makenode(SWCHVX,!ifflag,!ifflag,label(0),d,arctype,arclab); 323: EXP(num) = exp; 324: 325: str = challoc(6*nlabs); /* 5 digits + , or \0 per label */ 326: for (i = 0; i < d; ++i) /* construct list of values for each label */ 327: EXP(arctype[i]) = stralloc(str,accum(str,linelabs->nxtlab,arclab[i])); 328: chfree(str,6*nlabs); 329: chfree(arctype,sizeof(*arctype) * nlabs); chfree(arclab,sizeof(*arclab) * nlabs); 330: return(num); 331: } 332: 333: 334: accum(str,vlist,f) /* build string of indices in compnode corr. to label f */ 335: char *str; long f; struct lablist *vlist; 336: { 337: int s,j; struct lablist *p; 338: 339: s = 0; 340: j = 1; 341: for (p = vlist; p ; p = p->nxtlab) /* search for occurrences of f */ 342: { 343: if (p->labelt ==f) 344: { 345: if (s) 346: { 347: str[s] = ','; 348: ++s; 349: } 350: sprintf(&str[s],"%d",j); 351: while (str[s] != '\0') ++s; 352: } 353: ++j; 354: } 355: return(s+1); 356: } 357: 358: 359: distinct(vlist,count,dlist,size) /* make dlist into list of distinct labels in vlist */ 360: struct lablist *vlist; long dlist[]; /*count[] gets count of each label; d distinct labels */ 361: int count[],size; 362: {int d,i; 363: d = 0; 364: for(i = 0; i <= size; i++) count[i] = 0; 365: 366: for (;vlist && vlist->labelt != 0L; vlist = vlist ->nxtlab) 367: { 368: for (i = 0; ;i++) 369: { 370: if (i == d) dlist[d++] = vlist->labelt; 371: if (dlist[i] == vlist->labelt) 372: { 373: ++count[i]; break; 374: } 375: } 376: } 377: return(d); 378: }