Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

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