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