xref: /original-bsd/usr.bin/struct/struct/3.flow.c (revision 92d3de31)
1 #ifndef lint
2 static char sccsid[] = "@(#)3.flow.c	4.1	(Berkeley)	02/11/83";
3 #endif not lint
4 
5 #include <stdio.h>
6 #
7 /*
8 correct the flow of control in the new program - use GOTO's which may
9 be changed later to NEXT, BREAK, etc.
10 */
11 #include "def.h"
12 #include "3.def.h"
13 
14 #define BRANCHTYPE(v)	(NTYPE(v) == GOVX )
15 #define HASLEX(t)	(t != GOVX && t != COMPVX && t != ASGOVX  && t != ITERVX )
16 			/* for these, control never flows directly to following statement */
17 
18 
19 getflow()
20 	{
21 	fixflow(START,UNDEFINED);
22 	}
23 
24 
25 fixflow(v,autolex)
26 VERT v;
27 VERT autolex;		/* lexical successor of v */
28 	{
29 	VERT lex,chlex,z,x,w;
30 	int i;
31 	lex = lexval(v,autolex);
32 	if (HASLEX(NTYPE(v)) && NTYPE(v) != ICASVX)
33 		if (DEFINED(REACH(v)) && REACH(v) != lex)
34 			insib(v,makebr(REACH(v)));
35 		else if (NTYPE(v) == DOVX && ARC(v,1) != lex)
36 			insib(v,makebr(ARC(v,1)));
37 	if (NTYPE(v) == ITERVX)
38 		{
39 		BRK(v) = autolex;
40 		chlex = v;
41 		}
42 	else
43 		chlex = lexval(v,autolex);
44 
45 	for (i = 0; i < CHILDNUM(v); ++i)
46 		{
47 		w = LCHILD(v,i);
48 		if (DEFINED(w))
49 			fixflow(w,chlex);
50 		else
51 			{
52 			ASSERT(i < ARCNUM(v),fixflow);
53 			z = ARC(v,i);
54 			ASSERT(DEFINED(z), fixflow);
55 			if (z != chlex)
56 				{
57 				x = makebr(z);
58 				LCHILD(v,i) = x;
59 				RSIB(x) = UNDEFINED;
60 				}
61 			}
62 		}
63 	if (DEFINED(RSIB(v)))
64 		fixflow(RSIB(v),autolex);
65 	}
66 
67 
68 lexval(v,lastlex)
69 VERT v,lastlex;
70 	{
71 	VERT sib;
72 	if (!HASLEX(NTYPE(v))) return(UNDEFINED);
73 	sib = RSIB(v);
74 	if (NTYPE(v) == ICASVX || NTYPE(v) == ACASVX)
75 		return(lastlex);
76 	else if (!DEFINED(sib))
77 		return(lastlex);
78 	else if (BRANCHTYPE(sib))
79 		return(ARC(sib,0));
80 	else return(sib);
81 	}
82 
83 
84 makebr(w)		/* make branching node leading to w */
85 VERT w;
86 	{
87 	VERT new;
88 	new = create(GOVX,1);
89 	ARC(new,0) = w;
90 	RSIB(new) = UNDEFINED;
91 	REACH(new) = UNDEFINED;
92 	return(new);
93 	}
94