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