12864Speter /* 2*22238Sdist * Copyright (c) 1980 Regents of the University of California. 3*22238Sdist * All rights reserved. The Berkeley software License Agreement 4*22238Sdist * specifies the terms and conditions for redistribution. 5*22238Sdist */ 6*22238Sdist 7*22238Sdist #ifndef lint 8*22238Sdist static char sccsid[] = "@(#)rval.c 5.1 (Berkeley) 06/05/85"; 9*22238Sdist #endif not lint 10*22238Sdist 11*22238Sdist /* 122864Speter * pxp - Pascal execution profiler 132864Speter * 142864Speter * Bill Joy UCB 152864Speter * Version 1.2 January 1979 162864Speter */ 172864Speter 182864Speter #include "0.h" 192864Speter #include "tree.h" 202864Speter 212864Speter extern char *opnames[]; 222864Speter 232864Speter #define alph(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) 242864Speter /* 252864Speter * Rvalue reformats an expression. 262864Speter * Par is a flag indicating that the expression 272864Speter * should be parenthesized if it is non-atomic. 282864Speter */ 292864Speter rvalue(r, par) 302864Speter register int *r; 312864Speter int par; 322864Speter { 332864Speter register int *al; 342864Speter register char *opname; 352864Speter 362864Speter if (r == NIL) { 372864Speter ppid("{expr}"); 382864Speter return; 392864Speter } 402864Speter if (r[0] <= T_IN) 412864Speter opname = opnames[r[0]]; 422864Speter switch (r[0]) { 432864Speter case T_BINT: 442864Speter case T_INT: 452864Speter case T_FINT: 462864Speter ppnumb(r[2]); 472864Speter if (r[0] == T_BINT) 482864Speter ppsep("b"); 492864Speter return; 502864Speter case T_NIL: 512864Speter ppkw("nil"); 522864Speter return; 532864Speter case T_FCALL: 542864Speter funccod(r); 552864Speter return; 562864Speter case T_VAR: 572864Speter lvalue(r); 582864Speter return; 592864Speter case T_CSET: 602864Speter cset(r); 612864Speter return; 622864Speter case T_STRNG: 632864Speter ppstr(r[2]); 642864Speter return; 652864Speter } 662864Speter if (par) 672864Speter ppbra("("); 682864Speter switch (r[0]) { 692864Speter default: 702864Speter panic("rval"); 712864Speter case T_PLUS: 722864Speter case T_MINUS: 7316274Speter /* 7416274Speter * if child is relational (bogus) or adding operator, 7516274Speter * parenthesize child. 7616274Speter * this has the unaesthetic property that 7716274Speter * --i prints as -(-i), but is needed to catch 7816274Speter * -(a+b) which must print as -(a+b), not as -a+b. 7916274Speter * otherwise child has higher precedence 8016274Speter * and need not be parenthesized. 8116274Speter */ 822864Speter ppop(r[0] == T_PLUS ? "+" : "-"); 832864Speter al = r[2]; 8416274Speter rvalue(r[2], prec(al) <= prec(r) || full); 852864Speter break; 862864Speter case T_NOT: 8716274Speter /* 8816274Speter * if child is of lesser precedence 8916274Speter * (i.e. not another not operator) 9016274Speter * parenthesize it. 9116274Speter * nested not operators need not be parenthesized 9216274Speter * because it's a prefix operator. 9316274Speter */ 942864Speter ppkw(opname); 952864Speter ppspac(); 9616274Speter al = r[2]; 9716274Speter rvalue(r[2], prec(al) < prec(r) || full); 982864Speter break; 992864Speter case T_EQ: 1002864Speter case T_NE: 1012864Speter case T_GE: 1022864Speter case T_LE: 1032864Speter case T_GT: 1042864Speter case T_LT: 10516274Speter /* 10616274Speter * make the aesthetic choice to 10716274Speter * fully parenthesize relational expressions, 10816274Speter * in spite of left to right associativity. 10916274Speter * note: there are no operators with lower precedence. 11016274Speter */ 1112864Speter al = r[2]; 1122864Speter rvalue(al, prec(al) <= prec(r) || full); 1132864Speter goto rest; 1142864Speter case T_AND: 1152864Speter case T_OR: 1162864Speter case T_MULT: 1172864Speter case T_ADD: 1182864Speter case T_SUB: 1192864Speter case T_DIVD: 1202864Speter case T_MOD: 1212864Speter case T_DIV: 1222864Speter case T_IN: 12316274Speter /* 12416274Speter * need not parenthesize left child 12516274Speter * if it has equal precedence, 12616274Speter * due to left to right associativity. 12716274Speter * right child needs to be parenthesized 12816274Speter * if it has equal (or lesser) precedence. 12916274Speter */ 1302864Speter al = r[2]; 1312864Speter rvalue(al, prec(al) < prec(r) || full); 1322864Speter rest: 1332864Speter ppspac(); 1342864Speter if (alph(opname[0])) 1352864Speter ppkw(opname); 1362864Speter else 1372864Speter ppop(opname); 1382864Speter ppspac(); 1392864Speter al = r[3]; 1402864Speter rvalue(al, prec(al) <= prec(r) || full); 1412864Speter break; 1422864Speter } 1432864Speter if (par) 1442864Speter ppket(")"); 1452864Speter } 1462864Speter 1472864Speter /* 1482864Speter * Prec returns the precedence of an operator, 1492864Speter * with larger numbers indicating stronger binding. 1502864Speter * This is used to determine when parenthesization 1512864Speter * is needed on subexpressions. 1522864Speter */ 1532864Speter prec(r) 1542864Speter register int *r; 1552864Speter { 1562864Speter 1572864Speter if (r == NIL) 1582864Speter return; 1592864Speter switch (r[0]) { 1602864Speter case T_NOT: 1612864Speter return (3); 1622864Speter case T_MULT: 1632864Speter case T_DIVD: 1642864Speter case T_DIV: 1652864Speter case T_MOD: 1662864Speter case T_AND: 1672864Speter return (2); 1682864Speter case T_ADD: 1692864Speter case T_SUB: 1702864Speter case T_OR: 1712864Speter case T_PLUS: 1722864Speter case T_MINUS: 1732864Speter return (1); 1742864Speter default: 1752864Speter return (0); 1762864Speter } 1772864Speter } 178