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