1 static char *sccsid = "@(#)rval.c 1.1 (Berkeley) 03/02/81"; 2 /* Copyright (c) 1979 Regents of the University of California */ 3 # 4 /* 5 * pxp - Pascal execution profiler 6 * 7 * Bill Joy UCB 8 * Version 1.2 January 1979 9 */ 10 11 #include "0.h" 12 #include "tree.h" 13 14 extern char *opnames[]; 15 16 #define alph(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) 17 /* 18 * Rvalue reformats an expression. 19 * Par is a flag indicating that the expression 20 * should be parenthesized if it is non-atomic. 21 */ 22 rvalue(r, par) 23 register int *r; 24 int par; 25 { 26 register int *al; 27 register char *opname; 28 29 if (r == NIL) { 30 ppid("{expr}"); 31 return; 32 } 33 if (r[0] <= T_IN) 34 opname = opnames[r[0]]; 35 switch (r[0]) { 36 case T_BINT: 37 case T_INT: 38 case T_FINT: 39 ppnumb(r[2]); 40 if (r[0] == T_BINT) 41 ppsep("b"); 42 return; 43 case T_NIL: 44 ppkw("nil"); 45 return; 46 case T_FCALL: 47 funccod(r); 48 return; 49 case T_VAR: 50 lvalue(r); 51 return; 52 case T_CSET: 53 cset(r); 54 return; 55 case T_STRNG: 56 ppstr(r[2]); 57 return; 58 } 59 if (par) 60 ppbra("("); 61 switch (r[0]) { 62 default: 63 panic("rval"); 64 case T_PLUS: 65 case T_MINUS: 66 ppop(r[0] == T_PLUS ? "+" : "-"); 67 al = r[2]; 68 rvalue(r[2], prec(al) > prec(r) || full); 69 break; 70 case T_NOT: 71 ppkw(opname); 72 ppspac(); 73 rvalue(r[2], 1); 74 break; 75 case T_EQ: 76 case T_NE: 77 case T_GE: 78 case T_LE: 79 case T_GT: 80 case T_LT: 81 al = r[2]; 82 rvalue(al, prec(al) <= prec(r) || full); 83 goto rest; 84 case T_AND: 85 case T_OR: 86 case T_MULT: 87 case T_ADD: 88 case T_SUB: 89 case T_DIVD: 90 case T_MOD: 91 case T_DIV: 92 case T_IN: 93 al = r[2]; 94 rvalue(al, prec(al) < prec(r) || full); 95 rest: 96 ppspac(); 97 if (alph(opname[0])) 98 ppkw(opname); 99 else 100 ppop(opname); 101 ppspac(); 102 al = r[3]; 103 rvalue(al, prec(al) <= prec(r) || full); 104 break; 105 } 106 if (par) 107 ppket(")"); 108 } 109 110 /* 111 * Prec returns the precedence of an operator, 112 * with larger numbers indicating stronger binding. 113 * This is used to determine when parenthesization 114 * is needed on subexpressions. 115 */ 116 prec(r) 117 register int *r; 118 { 119 120 if (r == NIL) 121 return; 122 switch (r[0]) { 123 case T_NOT: 124 return (3); 125 case T_MULT: 126 case T_DIVD: 127 case T_DIV: 128 case T_MOD: 129 case T_AND: 130 return (2); 131 case T_ADD: 132 case T_SUB: 133 case T_OR: 134 case T_PLUS: 135 case T_MINUS: 136 return (1); 137 default: 138 return (0); 139 } 140 } 141