mr-frog reminded me: need to invalidate ptrace cache
[unix-history] / usr / src / old / adb / adb.tahoe / expr.c
CommitLineData
f5f1c911 1#ifndef lint
184d26e1 2static char sccsid[] = "@(#)expr.c 1.2 (Berkeley) %G%";
f5f1c911
SL
3#endif
4/*
5 *
6 * UNIX debugger
7 *
8 */
9
10#include "defs.h"
11
12MSG BADSYM;
13MSG BADVAR;
14MSG BADKET;
15MSG BADSYN;
16MSG NOCFN;
17MSG NOADR;
18MSG BADLOC;
19
20ADDR lastframe;
21ADDR savlastf;
22ADDR savframe;
23ADDR savpc;
24ADDR callpc;
25
26
27
28CHAR *lp;
29INT radix;
30STRING errflg;
31ADDR localval;
32CHAR isymbol[1024];
33
34CHAR lastc,peekc;
35
36L_INT dot;
37L_INT ditto;
38INT dotinc;
39L_INT var[];
40L_INT expv;
41
42
43
44
45expr(a)
46{ /* term | term dyadic expr | */
47 REG rc;
48 REG L_INT lhs;
49
50 rdc(); lp--; rc=term(a);
51
52 WHILE rc
53 DO lhs = expv;
54
55 switch ((int)readchar()) {
56
57 case '+':
58 term(a|1); expv += lhs; break;
59
60 case '-':
61 term(a|1); expv = lhs - expv; break;
62
63 case '#':
64 term(a|1); expv = round(lhs,expv); break;
65
66 case '*':
67 term(a|1); expv *= lhs; break;
68
69 case '%':
70 term(a|1); expv = lhs/expv; break;
71
72 case '&':
73 term(a|1); expv &= lhs; break;
74
75 case '|':
76 term(a|1); expv |= lhs; break;
77
78 case ')':
79 IF (a&2)==0 THEN error(BADKET); FI
80
81 default:
82 lp--;
83 return(rc);
84 }
85 OD
86 return(rc);
87}
88
89term(a)
90{ /* item | monadic item | (expr) | */
91
92 switch ((int)readchar()) {
93
94 case '*':
95 term(a|1); expv=chkget(expv,DSP); return(1);
96
97 case '@':
98 term(a|1); expv=chkget(expv,ISP); return(1);
99
100 case '-':
101 term(a|1); expv = -expv; return(1);
102
103 case '~':
104 term(a|1); expv = ~expv; return(1);
105
106 case '#':
107 term(a|1); expv = !expv; return(1);
108
109 case '(':
110 expr(2);
111 IF *lp!=')'
112 THEN error(BADSYN);
113 ELSE lp++; return(1);
114 FI
115
116 default:
117 lp--;
118 return(item(a));
119 }
120}
121
122item(a)
123{ /* name [ . local ] | number | . | ^ | <var | <register | 'x | | */
124 REG base, d, regptr;
125 CHAR savc;
126 REG L_INT frame;
127 register struct nlist *symp;
128
129 readchar();
130 IF symchar(0)
131 THEN readsym();
132 IF lastc=='.'
133 THEN frame= *(ADDR *)(((ADDR)(&u))+FP); lastframe=0;
134 callpc= *(ADDR *)(((ADDR)(&u))+PC);
135 WHILE errflg==0
136 DO savpc=callpc;
137 findsym(callpc,ISYM);
138 IF eqsym(cursym->n_un.n_name,isymbol,'~')
139 THEN break;
140 FI
141 callpc=get(frame-8, DSP);
142 lastframe=frame;
143 frame=get(frame, DSP)&ALIGN;
144 IF frame==0
145 THEN error(NOCFN);
146 FI
147 OD
148 savlastf=lastframe; savframe=frame;
149 readchar();
150 IF symchar(0)
151 THEN chkloc(expv=frame);
152 FI
153 ELIF (symp=lookup(isymbol))==0 THEN error(BADSYM);
154 ELSE expv = symp->n_value;
155 FI
156 lp--;
157
158
159 ELIF getnum()
160 THEN ;
161 ELIF lastc=='.'
162 THEN readchar();
163 IF symchar(0)
164 THEN lastframe=savlastf; callpc=savpc;
165 chkloc(savframe);
166 ELSE expv=dot;
167 FI
168 lp--;
169
170 ELIF lastc=='"'
171 THEN expv=ditto;
172
173 ELIF lastc=='+'
174 THEN expv=inkdot(dotinc);
175
176 ELIF lastc=='^'
177 THEN expv=inkdot(-dotinc);
178
179 ELIF lastc=='<'
180 THEN savc=rdc();
184d26e1 181 IF (regptr=getreg(savc)) != -1
f5f1c911
SL
182 THEN IF kcore THEN expv = *(int *)regptr;
183 ELSE expv= *(ADDR *)(((ADDR)(&u))+regptr); FI
184 ELIF (base=varchk(savc)) != -1
185 THEN expv=var[base];
186 ELSE error(BADVAR);
187 FI
188
189 ELIF lastc=='\''
190 THEN d=4; expv=0;
191 WHILE quotchar()
192 DO IF d--
193 THEN expv <<= 8;
194 expv |= lastc;
195 ELSE error(BADSYN);
196 FI
197 OD
198
199 ELIF a
200 THEN error(NOADR);
201 ELSE lp--; return(0);
202 FI
203 return(1);
204}
205
206/* service routines for expression reading */
207getnum()
208{
209 REG base,d,frpt;
210 UNION{REAL r; L_INT i;} real;
211 IF (base = radix) < 0 THEN base = -base; FI
212 IF isdigit(lastc)
213 THEN expv = 0;
214 WHILE (base>10 ? isxdigit(lastc) : isdigit(lastc))
215 DO
216 REG m;
217 m = MAXINT/base;
218 if(expv>m)
219 /* avoid overflow */
220 expv = (expv-m)*base+m*base;
221 else
222 expv *= base;
223 IF (d=convdig(lastc))>=base ORF d<0 THEN error(BADSYN); FI
224 expv += d; readchar();
225 IF expv==0
226 THEN IF (lastc=='x' ORF lastc=='X')
227 THEN base=16; readchar();
228 ELIF (lastc=='t' ORF lastc=='T')
229 THEN base=10; readchar();
230 ELIF (lastc=='o' ORF lastc=='O')
231 THEN base=8; readchar();
232 FI
233 FI
234 OD
235 IF lastc=='.' ANDF (base==10 ORF expv==0)
236 THEN real.r=expv; frpt=0; base=10;
237 WHILE isdigit(readchar())
238 DO real.r *= base; frpt++;
239 real.r += lastc-'0';
240 OD
241 WHILE frpt--
242 DO real.r /= base; OD
243 expv = real.i;
244 FI
245 peekc=lastc;
246 return(1);
247 ELSE return(0);
248 FI
249}
250
251readsym()
252{
253 REG char *p;
254
255 p = isymbol;
256 REP IF p < &isymbol[sizeof(isymbol)-1]
257 THEN *p++ = lastc;
258 FI
259 readchar();
260 PER symchar(1) DONE
261 *p++ = 0;
262}
263
264convdig(c)
265CHAR c;
266{
267 IF isdigit(c)
268 THEN return(c-'0');
269 ELIF isxdigit(c)
270 THEN return(c-'a'+10);
271 ELSE return(-1);
272 FI
273}
274
275symchar(dig)
276{
277 IF lastc=='\\' THEN readchar(); return(TRUE); FI
278 return ( isalpha(lastc) ORF lastc=='_' ORF dig ANDF isdigit(lastc) );
279}
280
281varchk(name)
282REG name;
283{
284 IF isdigit(name) THEN return(name-'0'); FI
285 IF isalpha(name) THEN return((name&037)-1+10); FI
286 return(-1);
287}
288
289chkloc(frame)
290L_INT frame;
291{
292 readsym();
293 REP IF localsym(frame)==0 THEN error(BADLOC); FI
294 expv=localval;
295 PER !eqsym(cursym->n_un.n_name,isymbol,'~') DONE
296}
297
298eqsym(s1, s2, c)
299 register char *s1, *s2;
300{
301
302 if (!strcmp(s1,s2))
303 return (1);
304 if (*s1 == c && !strcmp(s1+1, s2))
305 return (1);
306 return (0);
307}