Blob


1 /*
2 *
3 * debugger
4 *
5 */
7 #include "defs.h"
8 #include "fns.h"
10 static long dbround(long, long);
12 extern ADDR ditto;
13 vlong expv;
15 static WORD
16 ascval(void)
17 {
18 Rune r;
20 if (readchar() == 0)
21 return (0);
22 r = lastc;
23 while(quotchar()) /*discard chars to ending quote */
24 ;
25 return((WORD) r);
26 }
28 /*
29 * read a floating point number
30 * the result must fit in a WORD
31 */
33 static WORD
34 fpin(char *buf)
35 {
36 union {
37 WORD w;
38 float f;
39 } x;
41 x.f = atof(buf);
42 return (x.w);
43 }
45 WORD
46 defval(WORD w)
47 {
48 if (expr(0))
49 return (expv);
50 else
51 return (w);
52 }
54 int
55 expr(int a)
56 { /* term | term dyadic expr | */
57 int rc;
58 WORD lhs;
60 rdc();
61 reread();
62 rc=term(a);
63 while (rc) {
64 lhs = expv;
65 switch ((int)readchar()) {
67 case '+':
68 term(a|1);
69 expv += lhs;
70 break;
72 case '-':
73 term(a|1);
74 expv = lhs - expv;
75 break;
77 case '#':
78 term(a|1);
79 expv = dbround(lhs,expv);
80 break;
82 case '*':
83 term(a|1);
84 expv *= lhs;
85 break;
87 case '%':
88 term(a|1);
89 if(expv != 0)
90 expv = lhs/expv;
91 else{
92 if(lhs)
93 expv = 1;
94 else
95 expv = 0;
96 }
97 break;
99 case '&':
100 term(a|1);
101 expv &= lhs;
102 break;
104 case '|':
105 term(a|1);
106 expv |= lhs;
107 break;
109 case ')':
110 if ((a&2)==0)
111 error("unexpected `)'");
113 default:
114 reread();
115 return(rc);
118 return(rc);
121 int
122 term(int a)
123 { /* item | monadic item | (expr) | */
124 u32int u;
126 switch ((int)readchar()) {
128 case '*':
129 term(a|1);
130 if (get4(cormap, (ADDR)expv, &u) < 0)
131 error("%r");
132 expv = u;
133 return(1);
135 case '@':
136 term(a|1);
137 if (get4(symmap, (ADDR)expv, &u) < 0)
138 error("%r");
139 expv = u;
140 return(1);
142 case '-':
143 term(a|1);
144 expv = -expv;
145 return(1);
147 case '~':
148 term(a|1);
149 expv = ~expv;
150 return(1);
152 case '(':
153 expr(2);
154 if (readchar()!=')')
155 error("syntax error: `)' expected");
156 return(1);
158 default:
159 reread();
160 return(item(a));
164 int
165 item(int a)
166 { /* name [ . local ] | number | . | ^ | <register | 'x | | */
167 char *base;
168 char savc;
169 u64int u;
170 Symbol s;
171 char gsym[MAXSYM], lsym[MAXSYM];
173 readchar();
174 if (isfileref()) {
175 readfname(gsym);
176 rdc(); /* skip white space */
177 if (lastc == ':') { /* it better be */
178 rdc(); /* skip white space */
179 if (!getnum(readchar))
180 error("bad number");
181 if (expv == 0)
182 expv = 1; /* file begins at line 1 */
183 if(file2pc(gsym, expv, &u) < 0)
184 error("%r");
185 expv = u;
186 return 1;
188 error("bad file location");
189 } else if (symchar(0)) {
190 readsym(gsym);
191 if (lastc=='.') {
192 readchar(); /* ugh */
193 if (lastc == '.') {
194 lsym[0] = '.';
195 readchar();
196 readsym(lsym+1);
197 } else if (symchar(0)) {
198 readsym(lsym);
199 } else
200 lsym[0] = 0;
201 if (localaddr(cormap, correg, gsym, lsym, &u) < 0)
202 error("%r");
203 expv = u;
205 else {
206 if (lookupsym(0, gsym, &s) < 0)
207 error("symbol not found");
208 if (s.loc.type != LADDR)
209 error("symbol not kept in memory");
210 expv = s.loc.addr;
212 reread();
213 } else if (getnum(readchar)) {
215 } else if (lastc=='.') {
216 readchar();
217 if (!symchar(0) && lastc != '.') {
218 expv = dot;
219 } else {
220 if (findsym(locaddr(dbrget(cormap, mach->pc)), CTEXT, &s) < 0)
221 error("no current function");
222 if (lastc == '.') {
223 lsym[0] = '.';
224 readchar();
225 readsym(lsym+1);
226 } else
227 readsym(lsym);
228 if (localaddr(cormap, correg, s.name, lsym, &u) < 0)
229 error("%r");
230 expv = u;
232 reread();
233 } else if (lastc=='"') {
234 expv=ditto;
235 } else if (lastc=='+') {
236 expv=inkdot(dotinc);
237 } else if (lastc=='^') {
238 expv=inkdot(-dotinc);
239 } else if (lastc=='<') {
240 savc=rdc();
241 base = regname(savc);
242 expv = dbrget(cormap, base);
244 else if (lastc=='\'')
245 expv = ascval();
246 else if (a)
247 error("address expected");
248 else {
249 reread();
250 return(0);
252 return(1);
255 #define MAXBASE 16
257 /* service routines for expression reading */
258 int
259 getnum(int (*rdf)(void))
261 char *cp;
262 int base, d;
263 BOOL fpnum;
264 char num[MAXLIN];
266 base = 0;
267 fpnum = FALSE;
268 if (lastc == '#') {
269 base = 16;
270 (*rdf)();
272 if (convdig(lastc) >= MAXBASE)
273 return (0);
274 if (lastc == '0')
275 switch ((*rdf)()) {
276 case 'x':
277 case 'X':
278 base = 16;
279 (*rdf)();
280 break;
282 case 't':
283 case 'T':
284 base = 10;
285 (*rdf)();
286 break;
288 case 'o':
289 case 'O':
290 base = 8;
291 (*rdf)();
292 break;
293 default:
294 if (base == 0)
295 base = 8;
296 break;
298 if (base == 0)
299 base = 10;
300 expv = 0;
301 for (cp = num, *cp = lastc; ;(*rdf)()) {
302 if ((d = convdig(lastc)) < base) {
303 expv *= base;
304 expv += d;
305 *cp++ = lastc;
307 else if (lastc == '.') {
308 fpnum = TRUE;
309 *cp++ = lastc;
310 } else {
311 reread();
312 break;
315 if (fpnum)
316 expv = fpin(num);
317 return (1);
320 void
321 readsym(char *isymbol)
323 char *p;
324 Rune r;
326 p = isymbol;
327 do {
328 if (p < &isymbol[MAXSYM-UTFmax-1]){
329 r = lastc;
330 p += runetochar(p, &r);
332 readchar();
333 } while (symchar(1));
334 *p = 0;
337 void
338 readfname(char *filename)
340 char *p;
341 Rune c;
343 /* snarf chars until un-escaped char in terminal char set */
344 p = filename;
345 do {
346 if ((c = lastc) != '\\' && p < &filename[MAXSYM-UTFmax-1])
347 p += runetochar(p, &c);
348 readchar();
349 } while (c == '\\' || strchr(CMD_VERBS, lastc) == 0);
350 *p = 0;
351 reread();
354 int
355 convdig(int c)
357 if (isdigit(c))
358 return(c-'0');
359 else if (!isxdigit(c))
360 return(MAXBASE);
361 else if (isupper(c))
362 return(c-'A'+10);
363 else
364 return(c-'a'+10);
367 int
368 symchar(int dig)
370 if (lastc=='\\') {
371 readchar();
372 return(TRUE);
374 return(isalpha(lastc) || lastc>0x80 || lastc=='_' || dig && isdigit(lastc));
377 static long
378 dbround(long a, long b)
380 long w;
382 w = (a/b)*b;
383 if (a!=w)
384 w += b;
385 return(w);
388 ulong
389 dbrget(Map *map, char *name)
391 u64int u;
393 USED(map);
394 if(rget(correg, name, &u) < 0)
395 return ~(ulong)0;
396 return u;