1 /*- 2 * Copyright (c) 1980, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)rval.c 8.1 (Berkeley) 06/06/93"; 10 #endif /* not lint */ 11 12 /* 13 * pxp - Pascal execution profiler 14 * 15 * Bill Joy UCB 16 * Version 1.2 January 1979 17 */ 18 19 #include "0.h" 20 #include "tree.h" 21 22 extern char *opnames[]; 23 24 #define alph(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) 25 /* 26 * Rvalue reformats an expression. 27 * Par is a flag indicating that the expression 28 * should be parenthesized if it is non-atomic. 29 */ 30 rvalue(r, par) 31 register int *r; 32 int par; 33 { 34 register int *al; 35 register char *opname; 36 37 if (r == NIL) { 38 ppid("{expr}"); 39 return; 40 } 41 if (r[0] <= T_IN) 42 opname = opnames[r[0]]; 43 switch (r[0]) { 44 case T_BINT: 45 case T_INT: 46 case T_FINT: 47 ppnumb(r[2]); 48 if (r[0] == T_BINT) 49 ppsep("b"); 50 return; 51 case T_NIL: 52 ppkw("nil"); 53 return; 54 case T_FCALL: 55 funccod(r); 56 return; 57 case T_VAR: 58 lvalue(r); 59 return; 60 case T_CSET: 61 cset(r); 62 return; 63 case T_STRNG: 64 ppstr(r[2]); 65 return; 66 } 67 if (par) 68 ppbra("("); 69 switch (r[0]) { 70 default: 71 panic("rval"); 72 case T_PLUS: 73 case T_MINUS: 74 /* 75 * if child is relational (bogus) or adding operator, 76 * parenthesize child. 77 * this has the unaesthetic property that 78 * --i prints as -(-i), but is needed to catch 79 * -(a+b) which must print as -(a+b), not as -a+b. 80 * otherwise child has higher precedence 81 * and need not be parenthesized. 82 */ 83 ppop(r[0] == T_PLUS ? "+" : "-"); 84 al = r[2]; 85 rvalue(r[2], prec(al) <= prec(r) || full); 86 break; 87 case T_NOT: 88 /* 89 * if child is of lesser precedence 90 * (i.e. not another not operator) 91 * parenthesize it. 92 * nested not operators need not be parenthesized 93 * because it's a prefix operator. 94 */ 95 ppkw(opname); 96 ppspac(); 97 al = r[2]; 98 rvalue(r[2], prec(al) < prec(r) || full); 99 break; 100 case T_EQ: 101 case T_NE: 102 case T_GE: 103 case T_LE: 104 case T_GT: 105 case T_LT: 106 /* 107 * make the aesthetic choice to 108 * fully parenthesize relational expressions, 109 * in spite of left to right associativity. 110 * note: there are no operators with lower precedence. 111 */ 112 al = r[2]; 113 rvalue(al, prec(al) <= prec(r) || full); 114 goto rest; 115 case T_AND: 116 case T_OR: 117 case T_MULT: 118 case T_ADD: 119 case T_SUB: 120 case T_DIVD: 121 case T_MOD: 122 case T_DIV: 123 case T_IN: 124 /* 125 * need not parenthesize left child 126 * if it has equal precedence, 127 * due to left to right associativity. 128 * right child needs to be parenthesized 129 * if it has equal (or lesser) precedence. 130 */ 131 al = r[2]; 132 rvalue(al, prec(al) < prec(r) || full); 133 rest: 134 ppspac(); 135 if (alph(opname[0])) 136 ppkw(opname); 137 else 138 ppop(opname); 139 ppspac(); 140 al = r[3]; 141 rvalue(al, prec(al) <= prec(r) || full); 142 break; 143 } 144 if (par) 145 ppket(")"); 146 } 147 148 /* 149 * Prec returns the precedence of an operator, 150 * with larger numbers indicating stronger binding. 151 * This is used to determine when parenthesization 152 * is needed on subexpressions. 153 */ 154 prec(r) 155 register int *r; 156 { 157 158 if (r == NIL) 159 return; 160 switch (r[0]) { 161 case T_NOT: 162 return (3); 163 case T_MULT: 164 case T_DIVD: 165 case T_DIV: 166 case T_MOD: 167 case T_AND: 168 return (2); 169 case T_ADD: 170 case T_SUB: 171 case T_OR: 172 case T_PLUS: 173 case T_MINUS: 174 return (1); 175 default: 176 return (0); 177 } 178 } 179