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