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