#include #include "1.incl.h" #include "def.h" recognize(type, ifflag) /* if ifflag = 1, statement is if()type; otherwise is type */ int type, ifflag; /* do whatever is needed for this statement */ { int *arctype, i, sp; VERT num, num1, nest, loophead; extern long label(); long *arclab; if (nlabs > 3) sp = nlabs; else sp = 3; arctype = challoc(sizeof(*arctype) * sp); arclab = challoc(sizeof(*arclab) * sp); for( i=0; i < endbuf; i++) {if (buffer[i] == '~') buffer[i] = ' ';} loophead = nest = innerdo(label(0)); if (DEFINED(nest)) { /* this statement is last line of do loop */ nest = ARC(nest,0); /* nest is ITERVX of the innermost do ending here */ } if (ifflag) { if (type == ungo) { arctype[0] = -2; arclab[0] = label(1); } else arctype[0] = 0; arctype[1] = (nest >= 0) ? nest : -2; arclab[1] = implicit; num1 = makenode(IFVX,TRUE,TRUE,label(0),2,arctype,arclab); PRED(num1) = pred; } arctype[0] = (nest >= 0) ? nest : -2; arclab[0] = implicit; switch(type) { case ungo: if (!ifflag) { connect(label(1),implicit); if (label(0) != implicit) connect(label(1),label(0)); } break; case RETVX: case STOPVX: if (type == RETVX) { if (retvert == UNDEFINED) retvert = makenode(type,FALSE,FALSE,implicit,0,arctype,arclab); num = retvert; } else { if (stopvert == UNDEFINED) stopvert = makenode(type,FALSE,FALSE,implicit,0,arctype,arclab); num = stopvert; } if (!ifflag) { fixvalue(implicit,num); clear(implicit); if (label(0) != implicit) fixvalue(label(0),num); } break; case contst: contin(label(0),loophead); break; case FMTVX: num = makenode(FMTVX,FALSE,TRUE,implicit,0,arctype,arclab); BEGCODE(num) = comchar + 1 - rtnbeg; if((unsigned)(BEGCODE(num))!=comchar+1-rtnbeg) faterr("program too long","",""); ONDISK(num) = endline - endcom; if (label(0) != implicit) fixvalue(label(0),num); FMTLST = append(num,FMTLST); break; case STLNVX: if (DEFINED(stflag) && !ifflag && (label(0) == implicit)) { ++CODELINES(stflag); ONDISK(stflag) += endline - begline + 1; } else { num = makenode(STLNVX,!ifflag,!ifflag,label(0),1,arctype,arclab); if (!ifflag) { stflag = num; BEGCODE(num) = comchar + 1 - rtnbeg; if((unsigned)(BEGCODE(num))!=comchar+1-rtnbeg) faterr("program too long","",""); ONDISK(num) = endline - endcom; CODELINES(num) = 1; } else { BEGCODE(num) = stcode; ONDISK(num) = FALSE; CODELINES(num) = 1; } } break; case DOVX: if (arctype[0] != -2) { error("illegal do range, ","",""); fprintf(stderr," between lines %d and %d\n",begline, endline); exit(1); } arctype[1] = UNDEFINED; num1 = makenode(DOVX,TRUE,TRUE,label(0),2,arctype,arclab); if (++doptr >= maxdo) { faterr("in parsing:\n","do loops nested deeper than allowed",""); } dostack[doptr] = label(1); doloc[doptr] = num1; /* stack link to node after loop */ INC(num1) = inc; num = makenode(ITERVX,TRUE,FALSE,implicit,1,arctype,arclab); ARC(num1,0) = num; FATH(num) = UNDEFINED; /* number of DOVX can change so leave UNDEFINED until later */ break; case arithif: if (label(1) == label(2) || label(1) == 0L) makeif(1,label(0),concat(pred," > 0"),label(3),label(2)); else if (label(1) == label(3) || label(3) == 0L) makeif(1,label(0),concat(pred," == 0"),label(2),label(1)); else if (label(2) == label(3) || label(2) == 0L) makeif(1,label(0),concat(pred," < 0"),label(1),label(3)); else { makeif(1,label(0),concat(pred," < 0"),label(1),implicit); makeif(1,implicit,concat(pred," == 0"),label(2),label(3)); } break; case IOVX: if (endlab) { arctype[1] = -2; arclab[1] = endlab->labelt; } else arctype[1] = UNDEFINED; if (errlab) { arctype[2] = -2; arclab[2] = errlab->labelt; } else arctype[2] = UNDEFINED; num = makenode(IOVX,!ifflag,!ifflag,label(0),3,arctype,arclab); PRERW(num) = prerw; POSTRW(num) = postrw; if (reflab) addref(reflab->labelt, &FMTREF(num)); else FMTREF(num) = UNDEFINED; break; case COMPVX: if (intcase) { num = compcase(ifflag); break; } case ASGOVX: for (i = 0; i < nlabs - 1; i++) { arctype[i] = -2; arclab[i] = label(nlabs-i-1); } num = makenode(type,!ifflag,!ifflag,label(0),nlabs - 1, arctype, arclab); EXP(num) = exp; break; case ASVX: num = makenode(ASVX,!ifflag,!ifflag,label(0),1,arctype,arclab); EXP(num) = exp; addref(label(1),&LABREF(num)); break; case entry: num = makenode(STLNVX,FALSE,TRUE,label(0),1,arctype,arclab); BEGCODE(num) = comchar + 1 - rtnbeg; if((unsigned)(BEGCODE(num))!=comchar+1-rtnbeg) faterr("program too long","",""); ONDISK(num) = endline - endcom; CODELINES(num) = 1; ENTLST = append(num,ENTLST); break; } if (ifflag && type != ungo) { ARC(num1,0) = num; } if (DEFINED(loophead)) nesteddo(label(0), loophead); if (ifflag || DEFINED(loophead) || type != STLNVX) stflag = UNDEFINED; chfree(arctype,sizeof(*arctype) * sp); chfree(arclab,sizeof(*arclab) * sp); if (debug) { fprintf(debfd,"line %d: ", begline); if (ifflag) fprintf(debfd,"if() "); switch(type) {case RETVX: fprintf(debfd,"return"); break; case STOPVX: fprintf(debfd,"stop"); break; case contst: fprintf(debfd,"continue"); break; case ungo: fprintf(debfd,"uncond. goto"); break; case COMPVX: fprintf(debfd,"comp. goto"); break; case ASGOVX: fprintf(debfd,"ass. goto, labs"); break; case ASVX: fprintf(debfd,"label assignment"); break; case STLNVX: fprintf(debfd,"simple statement"); break; case arithif: fprintf(debfd,"arith if"); break; case DOVX: fprintf(debfd,"do "); break; case FMTVX: fprintf(debfd,"format st"); break; case IOVX: fprintf(debfd,"IOVX statement "); break; case entry: fprintf(debfd,"entry statement "); break; } fprintf(debfd,"\n%s\n", buffer); } } makeif(first,labe,test,arc1,arc2) /* construct IFVX with arcs to labels arc1,arc2 */ int first; long labe, arc1,arc2; char *test; { int num, arctype[2]; long arclab[2]; arctype[0] = arctype[1] = -2; arclab[0] = arc1; arclab[1] = arc2; num = makenode(IFVX,first,first,labe,2,arctype,arclab); PRED(num) = test; return(num); } innerdo(labe) /* return number of DOVX associated with labe, or UNDEFINED */ long labe; { if (DEFINED(doptr)) {if (dostack[doptr] == labe) return(doloc[doptr--]); } return(UNDEFINED); } contin(labe,nest) /* handle continue statements */ long labe; int nest; { VERT y; if (!DEFINED(nest)) { /* not nested */ if (labe != implicit) connect(implicit,labe); /* labe pts to next node */ } else { /* nested */ y = ARC(nest,0); fixvalue(labe,y); /* labe pts to ITERVX */ fixvalue(implicit, y); /* implicit links pt to ITERVX */ clear(implicit); } } nesteddo(labe,v) /* if multiple do's end on same label, add arc from inner DOVX to enclosing DOVX; add implicit link out of outermost DOVX with this label */ long labe; int v; { while (DEFINED(doptr) && dostack[doptr] == labe) { ARC(v,1) = ARC(doloc[doptr],0); /*set inner DOVX to point to outer ITERVX */ v = doloc[doptr--]; } addref(implicit, &ARC(v,1)); } compcase(ifflag) /* turn computed goto into case statement */ LOGICAL ifflag; { int *arctype, i, num, d, arct; extern long label(); long *arclab; char *str; arctype = challoc(sizeof(*arctype) * nlabs); arclab = challoc (sizeof(*arclab) * nlabs); d = distinct(linelabs->nxtlab,arctype,arclab,nlabs-1); /* puts distinct labels in arclab, count of each in arctype */ arct = -2; for (i = 0; i < d; ++i) arctype[i] = makenode(ICASVX,FALSE,FALSE,implicit,1,&arct,&arclab[i]); num = makenode(SWCHVX,!ifflag,!ifflag,label(0),d,arctype,arclab); EXP(num) = exp; str = challoc(6*nlabs); /* 5 digits + , or \0 per label */ for (i = 0; i < d; ++i) /* construct list of values for each label */ EXP(arctype[i]) = stralloc(str,accum(str,linelabs->nxtlab,arclab[i])); chfree(str,6*nlabs); chfree(arctype,sizeof(*arctype) * nlabs); chfree(arclab,sizeof(*arclab) * nlabs); return(num); } accum(str,vlist,f) /* build string of indices in compnode corr. to label f */ char *str; long f; struct lablist *vlist; { int s,j; struct lablist *p; s = 0; j = 1; for (p = vlist; p ; p = p->nxtlab) /* search for occurrences of f */ { if (p->labelt ==f) { if (s) { str[s] = ','; ++s; } sprintf(&str[s],"%d",j); while (str[s] != '\0') ++s; } ++j; } return(s+1); } distinct(vlist,count,dlist,size) /* make dlist into list of distinct labels in vlist */ struct lablist *vlist; long dlist[]; /*count[] gets count of each label; d distinct labels */ int count[],size; {int d,i; d = 0; for(i = 0; i <= size; i++) count[i] = 0; for (;vlist && vlist->labelt != 0L; vlist = vlist ->nxtlab) { for (i = 0; ;i++) { if (i == d) dlist[d++] = vlist->labelt; if (dlist[i] == vlist->labelt) { ++count[i]; break; } } } return(d); }