xref: /csrg-svn/usr.bin/pascal/pxp/rval.c (revision 16274)
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