xref: /csrg-svn/usr.bin/struct/beautify/tree.c (revision 35274)
110988Srrh #ifndef lint
2*35274Sbostic static char sccsid[] = "@(#)tree.c	4.3	(Berkeley)	07/22/88";
310988Srrh #endif not lint
410988Srrh 
510988Srrh # include "y.tab.h"
610988Srrh #include "b.h"
710988Srrh #include <stdio.h>
810988Srrh 
9*35274Sbostic extern char *malloc();
1010988Srrh 
11*35274Sbostic struct node *
1210988Srrh addroot(string,type,n1,n2)
1310988Srrh char *string;
1410988Srrh int type;
1510988Srrh struct node *n1, *n2;
1610988Srrh 	{
1710988Srrh 	struct node *p;
18*35274Sbostic 	p = (struct node *)malloc(sizeof(*p));
1910988Srrh 	p->left = n1;
2010988Srrh 	p->right = n2;
2110988Srrh 	p->op = type;
2210988Srrh 	p->lit = malloc(slength(string) + 1);
2310988Srrh 	str_copy(string,p->lit,slength(string) + 1);
2410988Srrh 	return(p);
2510988Srrh 	}
2610988Srrh 
2710988Srrh 
2810988Srrh freetree(tree)
2910988Srrh struct node *tree;
3010988Srrh 	{
3110988Srrh 	if (tree)
3210988Srrh 		{freetree(tree->left);
3310988Srrh 		freetree(tree->right);
3410988Srrh 		freenode(tree);
3510988Srrh 		}
3610988Srrh 	}
3710988Srrh 
3810988Srrh freenode(treenode)
3910988Srrh struct node *treenode;
4010988Srrh 	{
4110988Srrh 	free(treenode->lit);
4210988Srrh 	free(treenode);
4310988Srrh 	}
4410988Srrh 
4530667Slepreau int compop[] =	{	'&',	'|',	'<',	'>',	xxeq,	xxle,	xxne,	xxge};
4630667Slepreau int notop[] =	{	'|',	'&',	xxge,	xxle,	xxne,	'>',	xxeq,	'<'};
4730667Slepreau char *opstring[] =	{ "||",  "&&",	">=",	"<=", "!=",	">",	"==",	"<"};
4810988Srrh 
49*35274Sbostic struct node *
5010988Srrh checkneg(tree,neg)		/* eliminate nots if possible */
5110988Srrh struct node *tree;
5210988Srrh int neg;
5310988Srrh 	{
5410988Srrh 	int i;
5510988Srrh 	struct node *t;
5610988Srrh 	if (!tree) return(0);
5710988Srrh 	for (i =  0; i < 8; ++i)
5810988Srrh 		if (tree->op == compop[i]) break;
5910988Srrh 	if (i > 1 && i <  8 && tree ->left ->op == '-' && str_eq(tree->right->lit,"0"))
6010988Srrh 		{
6110988Srrh 		t = tree->right;
6210988Srrh 		tree->right = tree->left->right;
6310988Srrh 		freenode(t);
6410988Srrh 		t = tree->left;
6510988Srrh 		tree->left = tree->left->left;
6610988Srrh 		freenode(t);
6710988Srrh 		}
6810988Srrh 
6910988Srrh 
7010988Srrh 	if (neg)
7110988Srrh 		{
7210988Srrh 		if (tree ->op == '!')
7310988Srrh 			{
7410988Srrh 			t = tree->left;
7510988Srrh 			freenode(tree);
7610988Srrh 			return(checkneg(t,0));
7710988Srrh 			}
7810988Srrh 			if (i < 8)
7910988Srrh 				{
8010988Srrh 				tree->op = notop[i];
8110988Srrh 				free(tree->lit);
8210988Srrh 				tree->lit = malloc(slength(opstring[i])+1);
8310988Srrh 				str_copy(opstring[i],tree->lit, slength(opstring[i])+1);
8410988Srrh 				if (tree->op == '&' || tree->op == '|')
8510988Srrh 					{
8610988Srrh 					tree->left = checkneg(tree->left,1);
8710988Srrh 					tree->right = checkneg(tree->right,1);
8810988Srrh 					}
8910988Srrh 				return(tree);
9010988Srrh 				}
9110988Srrh 		if (tree->op == xxident && str_eq(tree->lit,".false."))
9210988Srrh 			str_copy(".true.",tree->lit, slength(".true.")+1);
9310988Srrh 		else if (tree->op == xxident && str_eq(tree->lit,".true."))
9410988Srrh 			{
9510988Srrh 			free(tree->lit);
9610988Srrh 			tree->lit = malloc(slength(".false.")+1);
9710988Srrh 			str_copy(".false.",tree->lit, slength(".false.")+1);
9810988Srrh 			}
9910988Srrh 		else
10010988Srrh 			{
10110988Srrh 			tree = addroot("!",'!',tree,0);
10210988Srrh 			tree->lit = malloc(2);
10310988Srrh 			str_copy("!",tree->lit, slength("!")+1);
10410988Srrh 			}
10510988Srrh 		return(tree);
10610988Srrh 		}
10710988Srrh 	else
10810988Srrh 		if (tree->op == '!')
10910988Srrh 			{
11010988Srrh 			t = tree;
11110988Srrh 			tree = tree->left;
11210988Srrh 			freenode(t);
11310988Srrh 			return(checkneg(tree,1));
11410988Srrh 			}
11510988Srrh 	else
11610988Srrh 		{tree->left = checkneg(tree->left,0);
11710988Srrh 		tree->right = checkneg(tree->right,0);
11810988Srrh 		return(tree);
11910988Srrh 		}
12010988Srrh 	}
12110988Srrh 
12210988Srrh yield(tree,fprec)
12310988Srrh struct node *tree;
12410988Srrh int fprec;				/* fprec is precedence of father of this node */
12510988Srrh 	{
12610988Srrh 	int paren,p;
12710988Srrh 	static int oplast;			/* oplast = 1 iff last char printed was operator */
12810988Srrh 	if (!tree) return;
12910988Srrh 	p = prec(tree ->op);
13010988Srrh 	paren = (p < fprec || (oplast && tree->op == xxuminus)) ? 1 : 0;
13110988Srrh 
13210988Srrh 	if (paren)
13310988Srrh 		{
13410988Srrh 		putout('(',"(");
13510988Srrh 		oplast = 0;
13610988Srrh 		}
13710988Srrh 
13810988Srrh 	switch(tree->op)
13910988Srrh 		{
14010988Srrh 		case xxuminus:
14110988Srrh 			tree->op = '-';
14210988Srrh 		case '!':
14310988Srrh 			putout(tree->op,tree->lit);
14410988Srrh 			oplast = 1;
14510988Srrh 			yield(tree->left,p);
14610988Srrh 			break;
14710988Srrh 		case '&':
14810988Srrh 		case '|':
14910988Srrh 		case '<':
15010988Srrh 		case '>':
15110988Srrh 		case xxeq:
15210988Srrh 		case xxle:
15310988Srrh 		case xxge:
15410988Srrh 		case '+':
15510988Srrh 		case '-':
15610988Srrh 		case '*':
15710988Srrh 		case '/':
15810988Srrh 		case '^':
15910988Srrh 			yield(tree->left,p);
16010988Srrh 			putout(tree->op, tree->lit);
16110988Srrh 			oplast = 1;
16210988Srrh 			yield(tree->right,p);
16310988Srrh 			break;
16410988Srrh 		case xxidpar:
16510988Srrh 			yield(tree->left,0);
16610988Srrh 			putout('(',"(");
16710988Srrh 			oplast = 0;
16810988Srrh 			yield(tree->right,0);
16910988Srrh 			putout('(',")");
17010988Srrh 			oplast = 0;
17110988Srrh 			break;
17210988Srrh 		default:
17310988Srrh 			yield(tree->left,p);
17410988Srrh 			putout(tree->op, tree->lit);
17510988Srrh 			oplast = 0;
17610988Srrh 			yield(tree->right,p);
17710988Srrh 			break;
17810988Srrh 		}
17910988Srrh 	if (paren)
18010988Srrh 		{
18110988Srrh 		putout(')',")");
18210988Srrh 		oplast = 0;
18310988Srrh 		}
18410988Srrh 	}
18510988Srrh 
18610988Srrh puttree(tree)
18710988Srrh struct node *tree;
18810988Srrh 	{
18910988Srrh 	yield(tree,0);
19010988Srrh 	freetree(tree);
19110988Srrh 	}
19210988Srrh 
19310988Srrh 
19410988Srrh prec(oper)
19510988Srrh int oper;
19610988Srrh 	{
19710988Srrh 	switch(oper)
19810988Srrh 		{
19910988Srrh 		case ',':		return(0);
20010988Srrh 		case '|':	return(1);
20110988Srrh 		case '&':	return(2);
20210988Srrh 		case '!':	return(3);
20310988Srrh 
20410988Srrh 		case '<':		case '>':		case xxeq:
20510988Srrh 		case xxne:	case xxle:	case xxge:
20610988Srrh 				return(4);
20710988Srrh 		case '+':
20810988Srrh 	case '-':		return(5);
20910988Srrh 		case '*':
21010988Srrh 	case '/':		return(6);
21110988Srrh 		case xxuminus:	return(7);
21210988Srrh 		case '^':	return(8);
21310988Srrh 		default:	return(9);
21410988Srrh 		}
21510988Srrh 	}
21610988Srrh str_copy(s,ptr,length)	/* copy s at ptr, return length of s */
21710988Srrh char *s, *ptr;
21810988Srrh int length;
21910988Srrh 	{int i;
22010988Srrh 	for (i = 0; i < length; i++)
22110988Srrh 		{
22210988Srrh 		ptr[i] = s[i];
22310988Srrh 		if (ptr[i] == '\0')
22410988Srrh 			return(i + 1);
22510988Srrh 		}
22610988Srrh 	fprintf(2,"string %s too long to be copied by str_copy at address %d\n",
22710988Srrh 			*s,ptr);
22810988Srrh 	exit(1);
22910988Srrh 	}
23010988Srrh str_eq(s,t)
23110988Srrh char s[],t[];
23210988Srrh 	{int j;
23310988Srrh 	for (j = 0; s[j] == t[j]; j++)
23410988Srrh 		{if (s[j] == '\0') return(1);}
23510988Srrh 	return(0);
23610988Srrh 	}
23710988Srrh 
23810988Srrh slength(s)			/* return number of chars in s, not counting '\0' */
23910988Srrh char *s;
24010988Srrh 	{
24110988Srrh 	int i;
24210988Srrh 	if (!s) return(-1);
24310988Srrh 	for (i = 0; s[i] != '\0'; i++);
24410988Srrh 	return(i);
24510988Srrh 	}
246