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