static char sccsid
[] = "@(#)3.loop.c 4.1 (Berkeley) 2/11/83";
#define ARCCOUNT(v) REACH(v)
newhd
= (NTYPE(v
) == ITERVX
) ? v
: hd
;
for (i
= 0; i
< CHILDNUM(v
); ++i
)
for (w
= LCHILD(v
,i
); DEFINED(w
); w
= RSIB(w
))
cntarcs() /* count arcs entering each node */
for (v
= 0; v
< nodenum
; ++v
)
for (v
= 0; v
< nodenum
; ++v
)
for (i
= 0; i
< ARCNUM(v
); ++i
)
if (!DEFINED(w
)) continue;
fixloop(v
) /* find WHILE loops */
ASSERT(DEFINED(ARC(v
,0)),fixloop
);
NXT(ARC(v
,0)) = ARC(v
,0);
else if (NTYPE(v
) == IFVX
&& arbcase
)
ASSERT(DEFINED(ARC(v
,0)),fixloop
);
RECURSE(fixloop
,v
,recvar
);
VERT vchild
, vgrand
,vgreat
;
ASSERT(NTYPE(v
) == LOOPVX
,getwh
);
ASSERT(DEFINED(vchild
),getwh
);
ASSERT(NTYPE(vchild
) == ITERVX
,getwh
);
vgrand
= LCHILD(vchild
,0);
if (!DEFINED(vgrand
) || !IFTHEN(vgrand
) )
vgreat
= LCHILD(vgrand
,THEN
);
if (DEFINED(vgreat
) && NTYPE(vgreat
) == GOVX
&& ARC(vgreat
,0) == BRK(vchild
))
NEG(vgrand
) = !NEG(vgrand
);
LCHILD(vchild
,0) = RSIB(vgrand
);
RSIB(vgrand
) = UNDEFINED
;
getun(v
) /* change loop to REPEAT UNTIL if possible */
VERT vchild
, vgrand
, vgreat
, before
, ch
;
ASSERT(NTYPE(v
) == LOOPVX
,getun
);
ASSERT(DEFINED(vchild
), getun
);
if (ARCCOUNT(vchild
) > 2)
return(FALSE
); /* loop can be iterated without passing through predicate of UNTIL */
for (ch
= vgrand
,before
= UNDEFINED
; DEFINED(RSIB(ch
)); ch
= RSIB(ch
))
vgreat
= LCHILD(ch
,THEN
);
if (DEFINED(vgreat
) && NTYPE(vgreat
) == GOVX
&& ARC(vgreat
,0) == BRK(vchild
))
RSIB(before
) = UNDEFINED
;
#define FORMCASE(w) (DEFINED(w) && !DEFINED(RSIB(w)) && NTYPE(w) == IFVX && ARCCOUNT(w) == 1)
/* must be of form if ... else if ... else if ... */
if (NTYPE(v
) != IFVX
) return(FALSE
);
if (!FORMCASE(ch
)) return(FALSE
);
if (!FORMCASE(grand
)) return(FALSE
);
exchange(&graph
[temp
],&graph
[v
]); /* want arcs to enter switch, not first case*/
RSIB(v
) = RSIB(temp
); /* statements which followed IFVX should follow switch */
for (ch
= LCHILD(temp
,ELSE
); FORMCASE(ch
); )
LCHILD(temp
,ELSE
) = UNDEFINED
;
ASSERT(!DEFINED(RSIB(temp
)),getswitch
);