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