1*16274Speter static char *sccsid = "@(#)rval.c 2.2 (Berkeley) 04/02/84"; 22864Speter /* Copyright (c) 1979 Regents of the University of California */ 32864Speter # 42864Speter /* 52864Speter * pxp - Pascal execution profiler 62864Speter * 72864Speter * Bill Joy UCB 82864Speter * Version 1.2 January 1979 92864Speter */ 102864Speter 112864Speter #include "0.h" 122864Speter #include "tree.h" 132864Speter 142864Speter extern char *opnames[]; 152864Speter 162864Speter #define alph(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) 172864Speter /* 182864Speter * Rvalue reformats an expression. 192864Speter * Par is a flag indicating that the expression 202864Speter * should be parenthesized if it is non-atomic. 212864Speter */ 222864Speter rvalue(r, par) 232864Speter register int *r; 242864Speter int par; 252864Speter { 262864Speter register int *al; 272864Speter register char *opname; 282864Speter 292864Speter if (r == NIL) { 302864Speter ppid("{expr}"); 312864Speter return; 322864Speter } 332864Speter if (r[0] <= T_IN) 342864Speter opname = opnames[r[0]]; 352864Speter switch (r[0]) { 362864Speter case T_BINT: 372864Speter case T_INT: 382864Speter case T_FINT: 392864Speter ppnumb(r[2]); 402864Speter if (r[0] == T_BINT) 412864Speter ppsep("b"); 422864Speter return; 432864Speter case T_NIL: 442864Speter ppkw("nil"); 452864Speter return; 462864Speter case T_FCALL: 472864Speter funccod(r); 482864Speter return; 492864Speter case T_VAR: 502864Speter lvalue(r); 512864Speter return; 522864Speter case T_CSET: 532864Speter cset(r); 542864Speter return; 552864Speter case T_STRNG: 562864Speter ppstr(r[2]); 572864Speter return; 582864Speter } 592864Speter if (par) 602864Speter ppbra("("); 612864Speter switch (r[0]) { 622864Speter default: 632864Speter panic("rval"); 642864Speter case T_PLUS: 652864Speter case T_MINUS: 66*16274Speter /* 67*16274Speter * if child is relational (bogus) or adding operator, 68*16274Speter * parenthesize child. 69*16274Speter * this has the unaesthetic property that 70*16274Speter * --i prints as -(-i), but is needed to catch 71*16274Speter * -(a+b) which must print as -(a+b), not as -a+b. 72*16274Speter * otherwise child has higher precedence 73*16274Speter * and need not be parenthesized. 74*16274Speter */ 752864Speter ppop(r[0] == T_PLUS ? "+" : "-"); 762864Speter al = r[2]; 77*16274Speter rvalue(r[2], prec(al) <= prec(r) || full); 782864Speter break; 792864Speter case T_NOT: 80*16274Speter /* 81*16274Speter * if child is of lesser precedence 82*16274Speter * (i.e. not another not operator) 83*16274Speter * parenthesize it. 84*16274Speter * nested not operators need not be parenthesized 85*16274Speter * because it's a prefix operator. 86*16274Speter */ 872864Speter ppkw(opname); 882864Speter ppspac(); 89*16274Speter al = r[2]; 90*16274Speter rvalue(r[2], prec(al) < prec(r) || full); 912864Speter break; 922864Speter case T_EQ: 932864Speter case T_NE: 942864Speter case T_GE: 952864Speter case T_LE: 962864Speter case T_GT: 972864Speter case T_LT: 98*16274Speter /* 99*16274Speter * make the aesthetic choice to 100*16274Speter * fully parenthesize relational expressions, 101*16274Speter * in spite of left to right associativity. 102*16274Speter * note: there are no operators with lower precedence. 103*16274Speter */ 1042864Speter al = r[2]; 1052864Speter rvalue(al, prec(al) <= prec(r) || full); 1062864Speter goto rest; 1072864Speter case T_AND: 1082864Speter case T_OR: 1092864Speter case T_MULT: 1102864Speter case T_ADD: 1112864Speter case T_SUB: 1122864Speter case T_DIVD: 1132864Speter case T_MOD: 1142864Speter case T_DIV: 1152864Speter case T_IN: 116*16274Speter /* 117*16274Speter * need not parenthesize left child 118*16274Speter * if it has equal precedence, 119*16274Speter * due to left to right associativity. 120*16274Speter * right child needs to be parenthesized 121*16274Speter * if it has equal (or lesser) precedence. 122*16274Speter */ 1232864Speter al = r[2]; 1242864Speter rvalue(al, prec(al) < prec(r) || full); 1252864Speter rest: 1262864Speter ppspac(); 1272864Speter if (alph(opname[0])) 1282864Speter ppkw(opname); 1292864Speter else 1302864Speter ppop(opname); 1312864Speter ppspac(); 1322864Speter al = r[3]; 1332864Speter rvalue(al, prec(al) <= prec(r) || full); 1342864Speter break; 1352864Speter } 1362864Speter if (par) 1372864Speter ppket(")"); 1382864Speter } 1392864Speter 1402864Speter /* 1412864Speter * Prec returns the precedence of an operator, 1422864Speter * with larger numbers indicating stronger binding. 1432864Speter * This is used to determine when parenthesization 1442864Speter * is needed on subexpressions. 1452864Speter */ 1462864Speter prec(r) 1472864Speter register int *r; 1482864Speter { 1492864Speter 1502864Speter if (r == NIL) 1512864Speter return; 1522864Speter switch (r[0]) { 1532864Speter case T_NOT: 1542864Speter return (3); 1552864Speter case T_MULT: 1562864Speter case T_DIVD: 1572864Speter case T_DIV: 1582864Speter case T_MOD: 1592864Speter case T_AND: 1602864Speter return (2); 1612864Speter case T_ADD: 1622864Speter case T_SUB: 1632864Speter case T_OR: 1642864Speter case T_PLUS: 1652864Speter case T_MINUS: 1662864Speter return (1); 1672864Speter default: 1682864Speter return (0); 1692864Speter } 1702864Speter } 171