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