|
|
1.1 root 1: /*
2: *
3: * UNIX debugger
4: *
5: */
6:
7: #include "defs.h"
8: #include <a.out.h>
9: #include "regs.h"
10:
11: MSG BADSYM;
12: MSG BADVAR;
13: MSG BADKET;
14: MSG BADSYN;
15: MSG NOCFN;
16: MSG NOADR;
17:
18: WORD var[NVARS];
19:
20: int radix;
21:
22: char lastc, peekc;
23:
24: extern ADDR ditto;
25: extern int ditsp;
26: extern int dotsp;
27: WORD expv;
28: int expsp;
29:
30: WORD
31: defval(w)
32: WORD w;
33: {
34: if (expr(0))
35: return (expv);
36: else
37: return (w);
38: }
39:
40: expr(a)
41: register int a;
42: { /* term | term dyadic expr | */
43: register int rc;
44: register WORD lhs;
45:
46: rdc();
47: reread();
48: expsp = NOSP;
49: rc=term(a);
50: while (rc) {
51: lhs = expv;
52: switch ((int)readchar()) {
53:
54: case '+':
55: term(a|1);
56: expv += lhs;
57: break;
58:
59: case '-':
60: term(a|1);
61: expv = lhs - expv;
62: break;
63:
64: case '#':
65: term(a|1);
66: expv = round(lhs,expv);
67: break;
68:
69: case '*':
70: term(a|1);
71: expv *= lhs;
72: break;
73:
74: case '%':
75: term(a|1);
76: expv = lhs/expv;
77: break;
78:
79: case '&':
80: term(a|1);
81: expv &= lhs;
82: break;
83:
84: case '|':
85: term(a|1);
86: expv |= lhs;
87: break;
88:
89: case ')':
90: if ((a&2)==0)
91: error(BADKET);
92:
93: default:
94: reread();
95: return(rc);
96: }
97: }
98: return(rc);
99: }
100:
101: term(a)
102: register int a;
103: { /* item | monadic item | (expr) | */
104:
105: switch ((int)readchar()) {
106:
107: case '*':
108: term(a|1);
109: expv=atow(aget((ADDR)expv, CORF|DATASP));
110: chkerr();
111: return(1);
112:
113: case '@':
114: term(a|1);
115: expv=atow(aget((ADDR)expv, SYMF|INSTSP));
116: return(1);
117:
118: case '-':
119: term(a|1);
120: expv = -expv;
121: return(1);
122:
123: case '~':
124: term(a|1);
125: expv = ~expv;
126: return(1);
127:
128: case '(':
129: expr(2);
130: if (readchar()!=')')
131: error(BADSYN);
132: return(1);
133:
134: case '%':
135: term(a|1);
136: expsp = REGSP;
137: return(1);
138:
139: default:
140: reread();
141: return(item(a));
142: }
143: }
144:
145: item(a)
146: register int a;
147: { /* name [ . local ] | number | . | ^ | <var | <register | 'x | | */
148: int base;
149: char savc;
150: register struct nlist *symp;
151: char gsym[MAXSYM], lsym[MAXSYM];
152: WORD ascval();
153:
154: readchar();
155: if (symchar(0)) {
156: readsym(gsym);
157: if (lastc=='.') {
158: readchar(); /* ugh */
159: if (!symchar(0))
160: localaddr(gsym, (char *)NULL);
161: else {
162: readsym(lsym);
163: localaddr(gsym, lsym);
164: }
165: }
166: else {
167: if ((symp = lookup(gsym)) == NULL)
168: error(BADSYM);
169: expv = symp->n_value;
170: }
171: reread();
172: } else if (getnum(readchar)) {
173: ;
174: } else if (lastc=='.') {
175: readchar();
176: if (!symchar(0)) {
177: expv = dot;
178: expsp = dotsp;
179: } else {
180: readsym(lsym);
181: localaddr((char *)NULL, lsym);
182: }
183: reread();
184: } else if (lastc=='"') {
185: expv=ditto;
186: expsp = ditsp;
187: } else if (lastc=='+') {
188: expv=inkdot(dotinc);
189: expsp = ditsp;
190: } else if (lastc=='^') {
191: expv=inkdot(-dotinc);
192: expsp = ditsp;
193: } else if (lastc=='<') {
194: savc=rdc();
195: base = getreg(savc);
196: if (base != BADREG)
197: expv = rtow(rget(base));
198: else if ((base = varchk(savc)) != -1)
199: expv = var[base];
200: else
201: error(BADVAR);
202: }
203: else if (lastc=='\'')
204: expv = ascval();
205: else if (a)
206: error(NOADR);
207: else {
208: reread();
209: return(0);
210: }
211: return(1);
212: }
213:
214: #define MAXBASE 16
215:
216: /* service routines for expression reading */
217: getnum(rdf)
218: int (*rdf)();
219: {
220: register char *cp;
221: register int base, d;
222: BOOL fpnum;
223: char num[MAXLIN];
224: WORD fpin();
225:
226: base = radix;
227: fpnum = FALSE;
228: if (lastc == '#') {
229: base = 16;
230: (*rdf)();
231: }
232: if (convdig(lastc) >= MAXBASE)
233: return (0);
234: if (lastc == '0')
235: switch ((*rdf)()) {
236: case 'x':
237: case 'X':
238: base = 16;
239: (*rdf)();
240: break;
241:
242: case 't':
243: case 'T':
244: base = 10;
245: (*rdf)();
246: break;
247:
248: case 'o':
249: case 'O':
250: base = 8;
251: (*rdf)();
252: break;
253: }
254: if (base == 0) {
255: if (lastc == '0')
256: base = 8;
257: else
258: base = 10;
259: }
260: expv = 0;
261: for (cp = num, *cp++ = lastc; ;(*rdf)()) {
262: if ((d = convdig(lastc)) < base) {
263: expv *= base;
264: expv += d;
265: *cp++ = lastc;
266: }
267: else if (lastc == '.') {
268: fpnum = TRUE;
269: *cp++ = lastc;
270: }
271: else {
272: reread();
273: break;
274: }
275: }
276: if (fpnum)
277: expv = fpin(num);
278: return (1);
279: }
280:
281: readsym(isymbol)
282: register char *isymbol;
283: {
284: register char *p;
285:
286: p = isymbol;
287: do {
288: if (p < &isymbol[MAXSYM-1])
289: *p++ = lastc;
290: readchar();
291: } while (symchar(1));
292: *p = 0;
293: }
294:
295: convdig(c)
296: register char c;
297: {
298: if (isdigit(c))
299: return(c-'0');
300: else if (isxdigit(c))
301: return(c-'a'+10);
302: else
303: return(MAXBASE);
304: }
305:
306: symchar(dig)
307: {
308: if (lastc=='\\') {
309: readchar();
310: return(TRUE);
311: }
312: return(isalpha(lastc) || lastc=='_' || dig && isdigit(lastc));
313: }
314:
315: varchk(name)
316: {
317: if (isdigit(name))
318: return(name-'0');
319: if (isalpha(name))
320: return((name&037)-1+10);
321: return(-1);
322: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.