xref: /csrg-svn/usr.bin/struct/beautify/tree.c (revision 10988)
1*10988Srrh #ifndef lint
2*10988Srrh static char sccsid[] = "@(#)tree.c	4.1	(Berkeley)	02/11/83";
3*10988Srrh #endif not lint
4*10988Srrh 
5*10988Srrh # include "y.tab.h"
6*10988Srrh #include "b.h"
7*10988Srrh #include <stdio.h>
8*10988Srrh 
9*10988Srrh 
10*10988Srrh addroot(string,type,n1,n2)
11*10988Srrh char *string;
12*10988Srrh int type;
13*10988Srrh struct node *n1, *n2;
14*10988Srrh 	{
15*10988Srrh 	struct node *p;
16*10988Srrh 	p = malloc(sizeof(*p));
17*10988Srrh 	p->left = n1;
18*10988Srrh 	p->right = n2;
19*10988Srrh 	p->op = type;
20*10988Srrh 	p->lit = malloc(slength(string) + 1);
21*10988Srrh 	str_copy(string,p->lit,slength(string) + 1);
22*10988Srrh 	return(p);
23*10988Srrh 	}
24*10988Srrh 
25*10988Srrh 
26*10988Srrh freetree(tree)
27*10988Srrh struct node *tree;
28*10988Srrh 	{
29*10988Srrh 	if (tree)
30*10988Srrh 		{freetree(tree->left);
31*10988Srrh 		freetree(tree->right);
32*10988Srrh 		freenode(tree);
33*10988Srrh 		}
34*10988Srrh 	}
35*10988Srrh 
36*10988Srrh freenode(treenode)
37*10988Srrh struct node *treenode;
38*10988Srrh 	{
39*10988Srrh 	free(treenode->lit);
40*10988Srrh 	free(treenode);
41*10988Srrh 	}
42*10988Srrh 
43*10988Srrh int compop[]	{	'&',	'|',	'<',	'>',	xxeq,	xxle,	xxne,	xxge};
44*10988Srrh int notop[]	{	'|',	'&',	xxge,	xxle,	xxne,	'>',	xxeq,	'<'};
45*10988Srrh char *opstring[]	{ "||",  "&&",	">=",	"<=", "!=",	">",	"==",	"<"};
46*10988Srrh 
47*10988Srrh checkneg(tree,neg)		/* eliminate nots if possible */
48*10988Srrh struct node *tree;
49*10988Srrh int neg;
50*10988Srrh 	{
51*10988Srrh 	int i;
52*10988Srrh 	struct node *t;
53*10988Srrh 	if (!tree) return(0);
54*10988Srrh 	for (i =  0; i < 8; ++i)
55*10988Srrh 		if (tree->op == compop[i]) break;
56*10988Srrh 	if (i > 1 && i <  8 && tree ->left ->op == '-' && str_eq(tree->right->lit,"0"))
57*10988Srrh 		{
58*10988Srrh 		t = tree->right;
59*10988Srrh 		tree->right = tree->left->right;
60*10988Srrh 		freenode(t);
61*10988Srrh 		t = tree->left;
62*10988Srrh 		tree->left = tree->left->left;
63*10988Srrh 		freenode(t);
64*10988Srrh 		}
65*10988Srrh 
66*10988Srrh 
67*10988Srrh 	if (neg)
68*10988Srrh 		{
69*10988Srrh 		if (tree ->op == '!')
70*10988Srrh 			{
71*10988Srrh 			t = tree->left;
72*10988Srrh 			freenode(tree);
73*10988Srrh 			return(checkneg(t,0));
74*10988Srrh 			}
75*10988Srrh 			if (i < 8)
76*10988Srrh 				{
77*10988Srrh 				tree->op = notop[i];
78*10988Srrh 				free(tree->lit);
79*10988Srrh 				tree->lit = malloc(slength(opstring[i])+1);
80*10988Srrh 				str_copy(opstring[i],tree->lit, slength(opstring[i])+1);
81*10988Srrh 				if (tree->op == '&' || tree->op == '|')
82*10988Srrh 					{
83*10988Srrh 					tree->left = checkneg(tree->left,1);
84*10988Srrh 					tree->right = checkneg(tree->right,1);
85*10988Srrh 					}
86*10988Srrh 				return(tree);
87*10988Srrh 				}
88*10988Srrh 		if (tree->op == xxident && str_eq(tree->lit,".false."))
89*10988Srrh 			str_copy(".true.",tree->lit, slength(".true.")+1);
90*10988Srrh 		else if (tree->op == xxident && str_eq(tree->lit,".true."))
91*10988Srrh 			{
92*10988Srrh 			free(tree->lit);
93*10988Srrh 			tree->lit = malloc(slength(".false.")+1);
94*10988Srrh 			str_copy(".false.",tree->lit, slength(".false.")+1);
95*10988Srrh 			}
96*10988Srrh 		else
97*10988Srrh 			{
98*10988Srrh 			tree = addroot("!",'!',tree,0);
99*10988Srrh 			tree->lit = malloc(2);
100*10988Srrh 			str_copy("!",tree->lit, slength("!")+1);
101*10988Srrh 			}
102*10988Srrh 		return(tree);
103*10988Srrh 		}
104*10988Srrh 	else
105*10988Srrh 		if (tree->op == '!')
106*10988Srrh 			{
107*10988Srrh 			t = tree;
108*10988Srrh 			tree = tree->left;
109*10988Srrh 			freenode(t);
110*10988Srrh 			return(checkneg(tree,1));
111*10988Srrh 			}
112*10988Srrh 	else
113*10988Srrh 		{tree->left = checkneg(tree->left,0);
114*10988Srrh 		tree->right = checkneg(tree->right,0);
115*10988Srrh 		return(tree);
116*10988Srrh 		}
117*10988Srrh 	}
118*10988Srrh 
119*10988Srrh yield(tree,fprec)
120*10988Srrh struct node *tree;
121*10988Srrh int fprec;				/* fprec is precedence of father of this node */
122*10988Srrh 	{
123*10988Srrh 	int paren,p;
124*10988Srrh 	static int oplast;			/* oplast = 1 iff last char printed was operator */
125*10988Srrh 	if (!tree) return;
126*10988Srrh 	p = prec(tree ->op);
127*10988Srrh 	paren = (p < fprec || (oplast && tree->op == xxuminus)) ? 1 : 0;
128*10988Srrh 
129*10988Srrh 	if (paren)
130*10988Srrh 		{
131*10988Srrh 		putout('(',"(");
132*10988Srrh 		oplast = 0;
133*10988Srrh 		}
134*10988Srrh 
135*10988Srrh 	switch(tree->op)
136*10988Srrh 		{
137*10988Srrh 		case xxuminus:
138*10988Srrh 			tree->op = '-';
139*10988Srrh 		case '!':
140*10988Srrh 			putout(tree->op,tree->lit);
141*10988Srrh 			oplast = 1;
142*10988Srrh 			yield(tree->left,p);
143*10988Srrh 			break;
144*10988Srrh 		case '&':
145*10988Srrh 		case '|':
146*10988Srrh 		case '<':
147*10988Srrh 		case '>':
148*10988Srrh 		case xxeq:
149*10988Srrh 		case xxle:
150*10988Srrh 		case xxge:
151*10988Srrh 		case '+':
152*10988Srrh 		case '-':
153*10988Srrh 		case '*':
154*10988Srrh 		case '/':
155*10988Srrh 		case '^':
156*10988Srrh 			yield(tree->left,p);
157*10988Srrh 			putout(tree->op, tree->lit);
158*10988Srrh 			oplast = 1;
159*10988Srrh 			yield(tree->right,p);
160*10988Srrh 			break;
161*10988Srrh 		case xxidpar:
162*10988Srrh 			yield(tree->left,0);
163*10988Srrh 			putout('(',"(");
164*10988Srrh 			oplast = 0;
165*10988Srrh 			yield(tree->right,0);
166*10988Srrh 			putout('(',")");
167*10988Srrh 			oplast = 0;
168*10988Srrh 			break;
169*10988Srrh 		default:
170*10988Srrh 			yield(tree->left,p);
171*10988Srrh 			putout(tree->op, tree->lit);
172*10988Srrh 			oplast = 0;
173*10988Srrh 			yield(tree->right,p);
174*10988Srrh 			break;
175*10988Srrh 		}
176*10988Srrh 	if (paren)
177*10988Srrh 		{
178*10988Srrh 		putout(')',")");
179*10988Srrh 		oplast = 0;
180*10988Srrh 		}
181*10988Srrh 	}
182*10988Srrh 
183*10988Srrh puttree(tree)
184*10988Srrh struct node *tree;
185*10988Srrh 	{
186*10988Srrh 	yield(tree,0);
187*10988Srrh 	freetree(tree);
188*10988Srrh 	}
189*10988Srrh 
190*10988Srrh 
191*10988Srrh prec(oper)
192*10988Srrh int oper;
193*10988Srrh 	{
194*10988Srrh 	switch(oper)
195*10988Srrh 		{
196*10988Srrh 		case ',':		return(0);
197*10988Srrh 		case '|':	return(1);
198*10988Srrh 		case '&':	return(2);
199*10988Srrh 		case '!':	return(3);
200*10988Srrh 
201*10988Srrh 		case '<':		case '>':		case xxeq:
202*10988Srrh 		case xxne:	case xxle:	case xxge:
203*10988Srrh 				return(4);
204*10988Srrh 		case '+':
205*10988Srrh 	case '-':		return(5);
206*10988Srrh 		case '*':
207*10988Srrh 	case '/':		return(6);
208*10988Srrh 		case xxuminus:	return(7);
209*10988Srrh 		case '^':	return(8);
210*10988Srrh 		default:	return(9);
211*10988Srrh 		}
212*10988Srrh 	}
213*10988Srrh str_copy(s,ptr,length)	/* copy s at ptr, return length of s */
214*10988Srrh char *s, *ptr;
215*10988Srrh int length;
216*10988Srrh 	{int i;
217*10988Srrh 	for (i = 0; i < length; i++)
218*10988Srrh 		{
219*10988Srrh 		ptr[i] = s[i];
220*10988Srrh 		if (ptr[i] == '\0')
221*10988Srrh 			return(i + 1);
222*10988Srrh 		}
223*10988Srrh 	fprintf(2,"string %s too long to be copied by str_copy at address %d\n",
224*10988Srrh 			*s,ptr);
225*10988Srrh 	exit(1);
226*10988Srrh 	}
227*10988Srrh str_eq(s,t)
228*10988Srrh char s[],t[];
229*10988Srrh 	{int j;
230*10988Srrh 	for (j = 0; s[j] == t[j]; j++)
231*10988Srrh 		{if (s[j] == '\0') return(1);}
232*10988Srrh 	return(0);
233*10988Srrh 	}
234*10988Srrh 
235*10988Srrh slength(s)			/* return number of chars in s, not counting '\0' */
236*10988Srrh char *s;
237*10988Srrh 	{
238*10988Srrh 	int i;
239*10988Srrh 	if (!s) return(-1);
240*10988Srrh 	for (i = 0; s[i] != '\0'; i++);
241*10988Srrh 	return(i);
242*10988Srrh 	}
243