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