1*10988Srrh #ifndef lint 2*10988Srrh static char sccsid[] = "@(#)tree.c 4.1 (Berkeley) 02/11/83"; 3*10988Srrh #endif not lint 4*10988Srrh 5*10988Srrh # include "y.tab.h" 6*10988Srrh #include "b.h" 7*10988Srrh #include <stdio.h> 8*10988Srrh 9*10988Srrh 10*10988Srrh addroot(string,type,n1,n2) 11*10988Srrh char *string; 12*10988Srrh int type; 13*10988Srrh struct node *n1, *n2; 14*10988Srrh { 15*10988Srrh struct node *p; 16*10988Srrh p = malloc(sizeof(*p)); 17*10988Srrh p->left = n1; 18*10988Srrh p->right = n2; 19*10988Srrh p->op = type; 20*10988Srrh p->lit = malloc(slength(string) + 1); 21*10988Srrh str_copy(string,p->lit,slength(string) + 1); 22*10988Srrh return(p); 23*10988Srrh } 24*10988Srrh 25*10988Srrh 26*10988Srrh freetree(tree) 27*10988Srrh struct node *tree; 28*10988Srrh { 29*10988Srrh if (tree) 30*10988Srrh {freetree(tree->left); 31*10988Srrh freetree(tree->right); 32*10988Srrh freenode(tree); 33*10988Srrh } 34*10988Srrh } 35*10988Srrh 36*10988Srrh freenode(treenode) 37*10988Srrh struct node *treenode; 38*10988Srrh { 39*10988Srrh free(treenode->lit); 40*10988Srrh free(treenode); 41*10988Srrh } 42*10988Srrh 43*10988Srrh int compop[] { '&', '|', '<', '>', xxeq, xxle, xxne, xxge}; 44*10988Srrh int notop[] { '|', '&', xxge, xxle, xxne, '>', xxeq, '<'}; 45*10988Srrh char *opstring[] { "||", "&&", ">=", "<=", "!=", ">", "==", "<"}; 46*10988Srrh 47*10988Srrh checkneg(tree,neg) /* eliminate nots if possible */ 48*10988Srrh struct node *tree; 49*10988Srrh int neg; 50*10988Srrh { 51*10988Srrh int i; 52*10988Srrh struct node *t; 53*10988Srrh if (!tree) return(0); 54*10988Srrh for (i = 0; i < 8; ++i) 55*10988Srrh if (tree->op == compop[i]) break; 56*10988Srrh if (i > 1 && i < 8 && tree ->left ->op == '-' && str_eq(tree->right->lit,"0")) 57*10988Srrh { 58*10988Srrh t = tree->right; 59*10988Srrh tree->right = tree->left->right; 60*10988Srrh freenode(t); 61*10988Srrh t = tree->left; 62*10988Srrh tree->left = tree->left->left; 63*10988Srrh freenode(t); 64*10988Srrh } 65*10988Srrh 66*10988Srrh 67*10988Srrh if (neg) 68*10988Srrh { 69*10988Srrh if (tree ->op == '!') 70*10988Srrh { 71*10988Srrh t = tree->left; 72*10988Srrh freenode(tree); 73*10988Srrh return(checkneg(t,0)); 74*10988Srrh } 75*10988Srrh if (i < 8) 76*10988Srrh { 77*10988Srrh tree->op = notop[i]; 78*10988Srrh free(tree->lit); 79*10988Srrh tree->lit = malloc(slength(opstring[i])+1); 80*10988Srrh str_copy(opstring[i],tree->lit, slength(opstring[i])+1); 81*10988Srrh if (tree->op == '&' || tree->op == '|') 82*10988Srrh { 83*10988Srrh tree->left = checkneg(tree->left,1); 84*10988Srrh tree->right = checkneg(tree->right,1); 85*10988Srrh } 86*10988Srrh return(tree); 87*10988Srrh } 88*10988Srrh if (tree->op == xxident && str_eq(tree->lit,".false.")) 89*10988Srrh str_copy(".true.",tree->lit, slength(".true.")+1); 90*10988Srrh else if (tree->op == xxident && str_eq(tree->lit,".true.")) 91*10988Srrh { 92*10988Srrh free(tree->lit); 93*10988Srrh tree->lit = malloc(slength(".false.")+1); 94*10988Srrh str_copy(".false.",tree->lit, slength(".false.")+1); 95*10988Srrh } 96*10988Srrh else 97*10988Srrh { 98*10988Srrh tree = addroot("!",'!',tree,0); 99*10988Srrh tree->lit = malloc(2); 100*10988Srrh str_copy("!",tree->lit, slength("!")+1); 101*10988Srrh } 102*10988Srrh return(tree); 103*10988Srrh } 104*10988Srrh else 105*10988Srrh if (tree->op == '!') 106*10988Srrh { 107*10988Srrh t = tree; 108*10988Srrh tree = tree->left; 109*10988Srrh freenode(t); 110*10988Srrh return(checkneg(tree,1)); 111*10988Srrh } 112*10988Srrh else 113*10988Srrh {tree->left = checkneg(tree->left,0); 114*10988Srrh tree->right = checkneg(tree->right,0); 115*10988Srrh return(tree); 116*10988Srrh } 117*10988Srrh } 118*10988Srrh 119*10988Srrh yield(tree,fprec) 120*10988Srrh struct node *tree; 121*10988Srrh int fprec; /* fprec is precedence of father of this node */ 122*10988Srrh { 123*10988Srrh int paren,p; 124*10988Srrh static int oplast; /* oplast = 1 iff last char printed was operator */ 125*10988Srrh if (!tree) return; 126*10988Srrh p = prec(tree ->op); 127*10988Srrh paren = (p < fprec || (oplast && tree->op == xxuminus)) ? 1 : 0; 128*10988Srrh 129*10988Srrh if (paren) 130*10988Srrh { 131*10988Srrh putout('(',"("); 132*10988Srrh oplast = 0; 133*10988Srrh } 134*10988Srrh 135*10988Srrh switch(tree->op) 136*10988Srrh { 137*10988Srrh case xxuminus: 138*10988Srrh tree->op = '-'; 139*10988Srrh case '!': 140*10988Srrh putout(tree->op,tree->lit); 141*10988Srrh oplast = 1; 142*10988Srrh yield(tree->left,p); 143*10988Srrh break; 144*10988Srrh case '&': 145*10988Srrh case '|': 146*10988Srrh case '<': 147*10988Srrh case '>': 148*10988Srrh case xxeq: 149*10988Srrh case xxle: 150*10988Srrh case xxge: 151*10988Srrh case '+': 152*10988Srrh case '-': 153*10988Srrh case '*': 154*10988Srrh case '/': 155*10988Srrh case '^': 156*10988Srrh yield(tree->left,p); 157*10988Srrh putout(tree->op, tree->lit); 158*10988Srrh oplast = 1; 159*10988Srrh yield(tree->right,p); 160*10988Srrh break; 161*10988Srrh case xxidpar: 162*10988Srrh yield(tree->left,0); 163*10988Srrh putout('(',"("); 164*10988Srrh oplast = 0; 165*10988Srrh yield(tree->right,0); 166*10988Srrh putout('(',")"); 167*10988Srrh oplast = 0; 168*10988Srrh break; 169*10988Srrh default: 170*10988Srrh yield(tree->left,p); 171*10988Srrh putout(tree->op, tree->lit); 172*10988Srrh oplast = 0; 173*10988Srrh yield(tree->right,p); 174*10988Srrh break; 175*10988Srrh } 176*10988Srrh if (paren) 177*10988Srrh { 178*10988Srrh putout(')',")"); 179*10988Srrh oplast = 0; 180*10988Srrh } 181*10988Srrh } 182*10988Srrh 183*10988Srrh puttree(tree) 184*10988Srrh struct node *tree; 185*10988Srrh { 186*10988Srrh yield(tree,0); 187*10988Srrh freetree(tree); 188*10988Srrh } 189*10988Srrh 190*10988Srrh 191*10988Srrh prec(oper) 192*10988Srrh int oper; 193*10988Srrh { 194*10988Srrh switch(oper) 195*10988Srrh { 196*10988Srrh case ',': return(0); 197*10988Srrh case '|': return(1); 198*10988Srrh case '&': return(2); 199*10988Srrh case '!': return(3); 200*10988Srrh 201*10988Srrh case '<': case '>': case xxeq: 202*10988Srrh case xxne: case xxle: case xxge: 203*10988Srrh return(4); 204*10988Srrh case '+': 205*10988Srrh case '-': return(5); 206*10988Srrh case '*': 207*10988Srrh case '/': return(6); 208*10988Srrh case xxuminus: return(7); 209*10988Srrh case '^': return(8); 210*10988Srrh default: return(9); 211*10988Srrh } 212*10988Srrh } 213*10988Srrh str_copy(s,ptr,length) /* copy s at ptr, return length of s */ 214*10988Srrh char *s, *ptr; 215*10988Srrh int length; 216*10988Srrh {int i; 217*10988Srrh for (i = 0; i < length; i++) 218*10988Srrh { 219*10988Srrh ptr[i] = s[i]; 220*10988Srrh if (ptr[i] == '\0') 221*10988Srrh return(i + 1); 222*10988Srrh } 223*10988Srrh fprintf(2,"string %s too long to be copied by str_copy at address %d\n", 224*10988Srrh *s,ptr); 225*10988Srrh exit(1); 226*10988Srrh } 227*10988Srrh str_eq(s,t) 228*10988Srrh char s[],t[]; 229*10988Srrh {int j; 230*10988Srrh for (j = 0; s[j] == t[j]; j++) 231*10988Srrh {if (s[j] == '\0') return(1);} 232*10988Srrh return(0); 233*10988Srrh } 234*10988Srrh 235*10988Srrh slength(s) /* return number of chars in s, not counting '\0' */ 236*10988Srrh char *s; 237*10988Srrh { 238*10988Srrh int i; 239*10988Srrh if (!s) return(-1); 240*10988Srrh for (i = 0; s[i] != '\0'; i++); 241*10988Srrh return(i); 242*10988Srrh } 243