1*48120Sbostic /*- 2*48120Sbostic * %sccs.include.proprietary.c% 3*48120Sbostic */ 4*48120Sbostic 510988Srrh #ifndef lint 6*48120Sbostic static char sccsid[] = "@(#)tree.c 5.1 (Berkeley) 04/16/91"; 7*48120Sbostic #endif /* not lint */ 810988Srrh 910988Srrh # include "y.tab.h" 1010988Srrh #include "b.h" 1110988Srrh #include <stdio.h> 1210988Srrh 1335274Sbostic struct node * 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 * 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 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 } 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 } 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 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