|
|
1.1 root 1: /*
2: *
3: * UNIX debugger
4: *
5: */
6:
7: #include "defs.h"
8:
9: MSG BADSYM;
10: MSG BADVAR;
11: MSG BADKET;
12: MSG BADSYN;
13: MSG NOCFN;
14: MSG NOADR;
15: MSG BADLOC;
16:
17: ADDR lastframe;
18: ADDR savlastf;
19: ADDR savframe;
20: ADDR savpc;
21: ADDR callpc;
22:
23:
24:
25: CHAR *lp;
26: INT radix;
27: STRING errflg;
28: L_INT localval;
29: CHAR isymbol[1024];
30:
31: CHAR lastc,peekc;
32:
33: L_INT dot;
34: L_INT ditto;
35: INT dotinc;
36: L_INT var[];
37: L_INT expv;
38:
39:
40:
41:
42: expr(a)
43: { /* term | term dyadic expr | */
44: REG rc;
45: REG L_INT lhs;
46:
47: rdc(); lp--; rc=term(a);
48:
49: WHILE rc
50: DO lhs = expv;
51:
52: switch ((int)readchar()) {
53:
54: case '+':
55: term(a|1); expv += lhs; break;
56:
57: case '-':
58: term(a|1); expv = lhs - expv; break;
59:
60: case '#':
61: term(a|1); expv = round(lhs,expv); break;
62:
63: case '*':
64: term(a|1); expv *= lhs; break;
65:
66: case '%':
67: term(a|1); expv = lhs/expv; break;
68:
69: case '&':
70: term(a|1); expv &= lhs; break;
71:
72: case '|':
73: term(a|1); expv |= lhs; break;
74:
75: case ')':
76: IF (a&2)==0 THEN error(BADKET); FI
77:
78: default:
79: lp--;
80: return(rc);
81: }
82: OD
83: return(rc);
84: }
85:
86: term(a)
87: { /* item | monadic item | (expr) | */
88:
89: switch ((int)readchar()) {
90:
91: case '*':
92: term(a|1); expv=chkget(expv,DSP); return(1);
93:
94: case '@':
95: term(a|1); expv=chkget(expv,ISP); return(1);
96:
97: case '-':
98: term(a|1); expv = -expv; return(1);
99:
100: case '~':
101: term(a|1); expv = ~expv; return(1);
102:
103: case '#':
104: term(a|1); expv = !expv; return(1);
105:
106: case '(':
107: expr(2);
108: IF *lp!=')'
109: THEN error(BADSYN);
110: ELSE lp++; return(1);
111: FI
112:
113: default:
114: lp--;
115: return(item(a));
116: }
117: }
118:
119: item(a)
120: { /* name [ . local ] | number | . | ^ | <var | <register | 'x | | */
121: REG base, d, regptr;
122: CHAR savc;
123: REG L_INT frame;
124: register struct nlist *symp;
125:
126: readchar();
127: IF symchar(0)
128: THEN readsym();
129: IF lastc=='.'
130: THEN frame= uw[FP]; lastframe=0;
131: callpc= uw[PC];
132: WHILE errflg==0
133: DO savpc=callpc;
134: findsym(callpc,ISYM);
135: IF eqsym(cursym->n_un.n_name,isymbol,'~')
136: THEN break;
137: FI
138: callpc=get(frame-8, DSP);
139: lastframe=frame;
140: frame=get(frame, DSP)&ALIGN;
141: IF frame==0
142: THEN error(NOCFN);
143: FI
144: OD
145: savlastf=lastframe; savframe=frame;
146: readchar();
147: IF symchar(0)
148: THEN chkloc(expv=frame);
149: FI
150: ELIF (symp=lookup(isymbol))==0 THEN error(BADSYM);
151: ELSE expv = symp->n_value;
152: FI
153: lp--;
154:
155:
156: ELIF getnum()
157: THEN ;
158: ELIF lastc=='.'
159: THEN readchar();
160: IF symchar(0)
161: THEN lastframe=savlastf; callpc=savpc;
162: chkloc(savframe);
163: ELSE expv=dot;
164: FI
165: lp--;
166:
167: ELIF lastc=='"'
168: THEN expv=ditto;
169:
170: ELIF lastc=='+'
171: THEN expv=inkdot(dotinc);
172:
173: ELIF lastc=='^'
174: THEN expv=inkdot(-dotinc);
175:
176: ELIF lastc=='<'
177: THEN savc=rdc();
178: IF regptr=getreg(savc)
179: THEN expv= uw[regptr];
180: ELIF (base=varchk(savc)) != -1
181: THEN expv=var[base];
182: ELSE error(BADVAR);
183: FI
184:
185: ELIF lastc=='\''
186: THEN d=4; expv=0;
187: WHILE quotchar()
188: DO IF d--
189: THEN expv <<= 8;
190: expv |= lastc;
191: ELSE error(BADSYN);
192: FI
193: OD
194:
195: ELIF a
196: THEN error(NOADR);
197: ELSE lp--; return(0);
198: FI
199: return(1);
200: }
201:
202: /* service routines for expression reading */
203: getnum()
204: {
205: REG base,d,frpt;
206: UNION{REAL r; L_INT i;} real;
207: IF (base = radix) < 0 THEN base = -base; FI
208: IF isdigit(lastc)
209: THEN expv = 0;
210: WHILE (base>10 ? isxdigit(lastc) : isdigit(lastc))
211: DO
212: REG m;
213: m = MAXINT/base;
214: if(expv>m)
215: /* avoid overflow */
216: expv = (expv-m)*base+m*base;
217: else
218: expv *= base;
219: IF (d=convdig(lastc))>=base ORF d<0 THEN error(BADSYN); FI
220: expv += d; readchar();
221: IF expv==0
222: THEN IF (lastc=='x' ORF lastc=='X')
223: THEN base=16; readchar();
224: ELIF (lastc=='t' ORF lastc=='T')
225: THEN base=10; readchar();
226: ELIF (lastc=='o' ORF lastc=='O')
227: THEN base=8; readchar();
228: FI
229: FI
230: OD
231: IF lastc=='.' ANDF (base==10 ORF expv==0)
232: THEN real.r=expv; frpt=0; base=10;
233: WHILE isdigit(readchar())
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: return(1);
243: ELSE return(0);
244: FI
245: }
246:
247: readsym()
248: {
249: REG char *p;
250:
251: p = isymbol;
252: REP IF p < &isymbol[sizeof(isymbol)-1]
253: THEN *p++ = lastc;
254: FI
255: readchar();
256: PER symchar(1) DONE
257: *p++ = 0;
258: }
259:
260: convdig(c)
261: CHAR c;
262: {
263: IF isdigit(c)
264: THEN return(c-'0');
265: ELIF isxdigit(c)
266: THEN return(c-'a'+10);
267: ELSE return(-1);
268: FI
269: }
270:
271: symchar(dig)
272: {
273: IF lastc=='\\' THEN readchar(); return(TRUE); FI
274: return ( isalpha(lastc) ORF lastc=='_' ORF dig ANDF isdigit(lastc) );
275: }
276:
277: varchk(name)
278: REG 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:
285: chkloc(frame)
286: L_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:
294: eqsym(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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.