recognize(type
, ifflag
) /* if ifflag = 1, statement is if()type; otherwise is type */
int type
, ifflag
; /* do whatever is needed for this statement */
VERT num
, num1
, nest
, loophead
;
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));
/* this statement is last line of do loop */
nest
= ARC(nest
,0); /* nest is ITERVX of the innermost do ending here */
arctype
[1] = (nest
>= 0) ? nest
: -2;
num1
= makenode(IFVX
,TRUE
,TRUE
,label(0),2,arctype
,arclab
);
arctype
[0] = (nest
>= 0) ? nest
: -2;
connect(label(1),implicit
);
if (label(0) != implicit
) connect(label(1),label(0));
if (retvert
== UNDEFINED
)
retvert
= makenode(type
,FALSE
,FALSE
,implicit
,0,arctype
,arclab
);
if (stopvert
== UNDEFINED
)
stopvert
= makenode(type
,FALSE
,FALSE
,implicit
,0,arctype
,arclab
);
if (label(0) != implicit
) fixvalue(label(0),num
);
contin(label(0),loophead
);
num
= makenode(FMTVX
,FALSE
,TRUE
,implicit
,0,arctype
,arclab
);
BEGCODE(num
) = comchar
+ 1 - rtnbeg
;
ONDISK(num
) = endline
- endcom
;
if (label(0) != implicit
)
FMTLST
= append(num
,FMTLST
);
if (DEFINED(stflag
) && !ifflag
&& (label(0) == implicit
))
ONDISK(stflag
) += endline
- begline
+ 1;
num
= makenode(STLNVX
,!ifflag
,!ifflag
,label(0),1,arctype
,arclab
);
BEGCODE(num
) = comchar
+ 1 - rtnbeg
;
ONDISK(num
) = endline
- endcom
;
error("illegal do range, ","","");
fprintf(stderr
," between lines %d and %d\n",begline
, endline
);
num1
= makenode(DOVX
,TRUE
,TRUE
,label(0),2,arctype
,arclab
);
faterr("in parsing:\n","do loops nested deeper than allowed","");
dostack
[doptr
] = label(1);
doloc
[doptr
] = num1
; /* stack link to node after loop */
num
= makenode(ITERVX
,TRUE
,FALSE
,implicit
,1,arctype
,arclab
);
FATH(num
) = UNDEFINED
; /* number of DOVX can change so leave UNDEFINED until later */
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));
makeif(1,label(0),concat(pred
," < 0"),label(1),implicit
);
makeif(1,implicit
,concat(pred
," == 0"),label(2),label(3));
arclab
[1] = endlab
->labelt
;
arclab
[2] = errlab
->labelt
;
num
= makenode(IOVX
,!ifflag
,!ifflag
,label(0),3,arctype
,arclab
);
addref(reflab
->labelt
, &FMTREF(num
));
for (i
= 0; i
< nlabs
- 1; i
++)
arclab
[i
] = label(nlabs
-i
-1);
num
= makenode(type
,!ifflag
,!ifflag
,label(0),nlabs
- 1, arctype
, arclab
);
num
= makenode(ASVX
,!ifflag
,!ifflag
,label(0),1,arctype
,arclab
);
addref(label(1),&LABREF(num
));
num
= makenode(STLNVX
,FALSE
,TRUE
,label(0),1,arctype
,arclab
);
BEGCODE(num
) = comchar
+ 1 - rtnbeg
;
ONDISK(num
) = endline
- endcom
;
ENTLST
= append(num
,ENTLST
);
if (ifflag
&& type
!= ungo
)
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
);
fprintf(debfd
,"line %d: ", begline
);
if (ifflag
) fprintf(debfd
,"if() ");
{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 */
arctype
[0] = arctype
[1] = -2;
num
= makenode(IFVX
,first
,first
,labe
,2,arctype
,arclab
);
innerdo(labe
) /* return number of DOVX associated with labe, or UNDEFINED */
{if (dostack
[doptr
] == labe
)
contin(labe
,nest
) /* handle continue statements */
if (labe
!= implicit
) connect(implicit
,labe
); /* labe pts to next node */
fixvalue(labe
,y
); /* labe pts to ITERVX */
fixvalue(implicit
, y
); /* implicit links pt to ITERVX */
/* if multiple do's end on same label, add arc from inner DOVX
add implicit link out of outermost DOVX with this label */
while (DEFINED(doptr
) && dostack
[doptr
] == labe
)
ARC(v
,1) = ARC(doloc
[doptr
],0); /*set inner DOVX to point to outer ITERVX */
addref(implicit
, &ARC(v
,1));
compcase(ifflag
) /* turn computed goto into case statement */
int *arctype
, i
, num
, d
, arct
;
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 */
arctype
[i
] = makenode(ICASVX
,FALSE
,FALSE
,implicit
,1,&arct
,&arclab
[i
]);
num
= makenode(SWCHVX
,!ifflag
,!ifflag
,label(0),d
,arctype
,arclab
);
str
= challoc(6*(nlabs
-1)); /* 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(arctype
,sizeof(*arctype
) * nlabs
); chfree(arclab
,sizeof(*arclab
) * nlabs
);
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
;
for (p
= vlist
; p
; p
= p
->nxtlab
) /* search for occurrences of f */
while (str
[s
] != '\0') ++s
;
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 */
for(i
= 0; i
< size
; i
++) count
[i
] = 0;
for (;vlist
&& vlist
->labelt
!= 0L; vlist
= vlist
->nxtlab
)
if (i
== d
) dlist
[d
++] = vlist
->labelt
;
if (dlist
[i
] == vlist
->labelt
)