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