new copyright; att/bsd/shared
[unix-history] / usr / src / usr.bin / pascal / pxp / rval.c
CommitLineData
0fc6e47b
KB
1/*-
2 * Copyright (c) 1980 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
252367af
DF
6 */
7
8#ifndef lint
0fc6e47b
KB
9static char sccsid[] = "@(#)rval.c 5.2 (Berkeley) %G%";
10#endif /* not lint */
252367af 11
fc670973
PK
12/*
13 * pxp - Pascal execution profiler
14 *
15 * Bill Joy UCB
16 * Version 1.2 January 1979
17 */
18
19#include "0.h"
20#include "tree.h"
21
22extern char *opnames[];
23
24#define alph(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
25/*
26 * Rvalue reformats an expression.
27 * Par is a flag indicating that the expression
28 * should be parenthesized if it is non-atomic.
29 */
30rvalue(r, par)
31 register int *r;
32 int par;
33{
34 register int *al;
35 register char *opname;
36
37 if (r == NIL) {
38 ppid("{expr}");
39 return;
40 }
41 if (r[0] <= T_IN)
42 opname = opnames[r[0]];
43 switch (r[0]) {
44 case T_BINT:
45 case T_INT:
46 case T_FINT:
47 ppnumb(r[2]);
48 if (r[0] == T_BINT)
49 ppsep("b");
50 return;
51 case T_NIL:
52 ppkw("nil");
53 return;
54 case T_FCALL:
55 funccod(r);
56 return;
57 case T_VAR:
58 lvalue(r);
59 return;
60 case T_CSET:
61 cset(r);
62 return;
63 case T_STRNG:
64 ppstr(r[2]);
65 return;
66 }
67 if (par)
68 ppbra("(");
69 switch (r[0]) {
70 default:
71 panic("rval");
72 case T_PLUS:
73 case T_MINUS:
15771929
PK
74 /*
75 * if child is relational (bogus) or adding operator,
76 * parenthesize child.
77 * this has the unaesthetic property that
78 * --i prints as -(-i), but is needed to catch
79 * -(a+b) which must print as -(a+b), not as -a+b.
80 * otherwise child has higher precedence
81 * and need not be parenthesized.
82 */
fc670973
PK
83 ppop(r[0] == T_PLUS ? "+" : "-");
84 al = r[2];
15771929 85 rvalue(r[2], prec(al) <= prec(r) || full);
fc670973
PK
86 break;
87 case T_NOT:
15771929
PK
88 /*
89 * if child is of lesser precedence
90 * (i.e. not another not operator)
91 * parenthesize it.
92 * nested not operators need not be parenthesized
93 * because it's a prefix operator.
94 */
fc670973
PK
95 ppkw(opname);
96 ppspac();
15771929
PK
97 al = r[2];
98 rvalue(r[2], prec(al) < prec(r) || full);
fc670973
PK
99 break;
100 case T_EQ:
101 case T_NE:
102 case T_GE:
103 case T_LE:
104 case T_GT:
105 case T_LT:
15771929
PK
106 /*
107 * make the aesthetic choice to
108 * fully parenthesize relational expressions,
109 * in spite of left to right associativity.
110 * note: there are no operators with lower precedence.
111 */
fc670973
PK
112 al = r[2];
113 rvalue(al, prec(al) <= prec(r) || full);
114 goto rest;
115 case T_AND:
116 case T_OR:
117 case T_MULT:
118 case T_ADD:
119 case T_SUB:
120 case T_DIVD:
121 case T_MOD:
122 case T_DIV:
123 case T_IN:
15771929
PK
124 /*
125 * need not parenthesize left child
126 * if it has equal precedence,
127 * due to left to right associativity.
128 * right child needs to be parenthesized
129 * if it has equal (or lesser) precedence.
130 */
fc670973
PK
131 al = r[2];
132 rvalue(al, prec(al) < prec(r) || full);
133rest:
134 ppspac();
135 if (alph(opname[0]))
136 ppkw(opname);
137 else
138 ppop(opname);
139 ppspac();
140 al = r[3];
141 rvalue(al, prec(al) <= prec(r) || full);
142 break;
143 }
144 if (par)
145 ppket(")");
146}
147
148/*
149 * Prec returns the precedence of an operator,
150 * with larger numbers indicating stronger binding.
151 * This is used to determine when parenthesization
152 * is needed on subexpressions.
153 */
154prec(r)
155 register int *r;
156{
157
158 if (r == NIL)
159 return;
160 switch (r[0]) {
161 case T_NOT:
162 return (3);
163 case T_MULT:
164 case T_DIVD:
165 case T_DIV:
166 case T_MOD:
167 case T_AND:
168 return (2);
169 case T_ADD:
170 case T_SUB:
171 case T_OR:
172 case T_PLUS:
173 case T_MINUS:
174 return (1);
175 default:
176 return (0);
177 }
178}