home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #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);
- }
-
-
-