new version from Chris Torek
[unix-history] / usr / src / old / adb / adb.vax / expr.c
CommitLineData
a1dada70
SL
1#ifndef lint
2static char sccsid[] = "@(#)expr.c 4.8 %G%";
3#endif
51a6db3a
BJ
4/*
5 *
6 * UNIX debugger
7 *
8 */
9
10#include "defs.h"
51a6db3a
BJ
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;
31L_INT localval;
3d9f6a35 32CHAR isymbol[1024];
51a6db3a
BJ
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 INT rc;
48 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--;
d042e5db 83 return(rc);
51a6db3a
BJ
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 '~':
60fd2268
RH
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 INT base, d;
125 CHAR savc;
126 BOOL hex;
127 L_INT frame;
128 register struct nlist *symp;
129 int regptr;
130
131 hex=FALSE;
132
133 readchar();
134 IF symchar(0)
135 THEN readsym();
136 IF lastc=='.'
137 THEN frame= *(ADDR *)(((ADDR)&u)+FP); lastframe=0;
138 callpc= *(ADDR *)(((ADDR)&u)+PC);
139 WHILE errflg==0
140 DO savpc=callpc;
141 findsym(callpc,ISYM);
142 IF eqsym(cursym->n_un.n_name,isymbol,'~')
143 THEN break;
144 FI
145 callpc=get(frame+16, DSP);
146 lastframe=frame;
147 frame=get(frame+12,DSP)&EVEN;
148 IF frame==0
149 THEN error(NOCFN);
150 FI
151 OD
152 savlastf=lastframe; savframe=frame;
153 readchar();
154 IF symchar(0)
155 THEN chkloc(expv=frame);
156 FI
157 ELIF (symp=lookup(isymbol))==0 THEN error(BADSYM);
158 ELSE expv = symp->n_value;
159 FI
160 lp--;
51a6db3a
BJ
161
162 ELIF getnum(readchar)
163 THEN ;
164 ELIF lastc=='.'
165 THEN readchar();
166 IF symchar(0)
167 THEN lastframe=savlastf; callpc=savpc;
168 chkloc(savframe);
169 ELSE expv=dot;
170 FI
171 lp--;
172
173 ELIF lastc=='"'
174 THEN expv=ditto;
175
176 ELIF lastc=='+'
177 THEN expv=inkdot(dotinc);
178
179 ELIF lastc=='^'
180 THEN expv=inkdot(-dotinc);
181
182 ELIF lastc=='<'
183 THEN savc=rdc();
184 IF regptr=getreg(savc)
6eadceb1
BJ
185 THEN IF kcore THEN expv = *(int *)regptr;
186 ELSE expv= * (ADDR *)(((ADDR)&u)+regptr); FI
51a6db3a
BJ
187 ELIF (base=varchk(savc)) != -1
188 THEN expv=var[base];
189 ELSE error(BADVAR);
190 FI
191
192 ELIF lastc=='\''
193 THEN d=4; expv=0;
194 WHILE quotchar()
195 DO IF d--
8589da02 196 THEN expv = (expv << 8) | lastc;
51a6db3a
BJ
197 ELSE error(BADSYN);
198 FI
199 OD
200
201 ELIF a
202 THEN error(NOADR);
203 ELSE lp--; return(0);
204 FI
205 return(1);
206}
207
208/* service routines for expression reading */
209getnum(rdf) int (*rdf)();
210{
211 INT base,d,frpt;
212 BOOL hex;
213 UNION{REAL r; L_INT i;} real;
214 IF isdigit(lastc) ORF (hex=TRUE, lastc=='#' ANDF isxdigit((*rdf)()))
215 THEN expv = 0;
216 base = (hex ? 16 : radix);
217 WHILE (base>10 ? isxdigit(lastc) : isdigit(lastc))
218 DO expv = (base==16 ? expv<<4 : expv*base);
219 IF (d=convdig(lastc))>=base THEN error(BADSYN); FI
220 expv += d; (*rdf)();
221 IF expv==0
222 THEN IF (lastc=='x' ORF lastc=='X')
223 THEN hex=TRUE; base=16; (*rdf)();
224 ELIF (lastc=='t' ORF lastc=='T')
225 THEN hex=FALSE; base=10; (*rdf)();
226 ELIF (lastc=='o' ORF lastc=='O')
227 THEN hex=FALSE; base=8; (*rdf)();
228 FI
229 FI
230 OD
231 IF lastc=='.' ANDF (base==10 ORF expv==0) ANDF !hex
232 THEN real.r=expv; frpt=0; base=10;
233 WHILE isdigit((*rdf)())
234 DO real.r *= base; frpt++;
235 real.r += lastc-'0';
236 OD
237 WHILE frpt--
238 DO real.r /= base; OD
239 expv = real.i;
240 FI
241 peekc=lastc;
242/* lp--; */
243 return(1);
244 ELSE return(0);
245 FI
246}
247
248readsym()
249{
250 REG char *p;
251
252 p = isymbol;
253 REP IF p < &isymbol[sizeof(isymbol)-1]
254 THEN *p++ = lastc;
255 FI
256 readchar();
257 PER symchar(1) DONE
258 *p++ = 0;
259}
260
261convdig(c)
262CHAR c;
263{
264 IF isdigit(c)
265 THEN return(c-'0');
266 ELIF isxdigit(c)
267 THEN return(c-'a'+10);
268 ELSE return(17);
269 FI
270}
271
272symchar(dig)
273{
274 IF lastc=='\\' THEN readchar(); return(TRUE); FI
275 return( isalpha(lastc) ORF lastc=='_' ORF dig ANDF isdigit(lastc) );
276}
277
278varchk(name)
279{
280 IF isdigit(name) THEN return(name-'0'); FI
281 IF isalpha(name) THEN return((name&037)-1+10); FI
282 return(-1);
283}
284
285chkloc(frame)
286L_INT frame;
287{
288 readsym();
289 REP IF localsym(frame)==0 THEN error(BADLOC); FI
290 expv=localval;
291 PER !eqsym(cursym->n_un.n_name,isymbol,'~') DONE
292}
293
294eqsym(s1, s2, c)
295 register char *s1, *s2;
296{
297
298 if (!strcmp(s1,s2))
299 return (1);
300 if (*s1 == c && !strcmp(s1+1, s2))
301 return (1);
302 return (0);
303}