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