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