|
|
1.1 root 1: #
2: /*
3: *
4: * UNIX debugger
5: *
6: */
7:
8: #include "defs.h"
9: SCCSID(@(#)expr.c 2.5);
10:
11:
12: MSG BADSYM;
13: MSG BADVAR;
14: MSG BADKET;
15: MSG BADSYN;
16: MSG NOCFN;
17: MSG NOADR;
18: MSG BADLOC;
19:
20: SYMTAB symbol;
21: ADDR lastframe;
22: ADDR savlastf;
23: ADDR savframe;
24: ADDR savpc;
25: ADDR callpc;
26:
27:
28:
29: CHAR *lp;
30: INT radix;
31: STRING errflg;
32: L_INT localval;
33: CHAR isymbol[8];
34:
35: CHAR lastc,peekc;
36: char u[ctob(UPAGES)]; /* struct user u; */
37:
38: L_INT dot;
39: L_INT ditto;
40: INT dotinc;
41: L_INT var[];
42: L_INT expv;
43:
44:
45:
46:
47: expr(a)
48: { /* term | term dyadic expr | */
49: INT rc;
50: L_INT lhs;
51:
52: rdc(); lp--; rc=term(a);
53:
54: WHILE rc
55: DO lhs = expv;
56:
57: switch ((int)readchar()) {
58:
59: case '+':
60: term(a|1); expv += lhs; break;
61:
62: case '-':
63: term(a|1); expv = lhs - expv; break;
64:
65: case '#':
66: term(a|1); expv = round(lhs,expv); break;
67:
68: case '*':
69: term(a|1); expv *= lhs; break;
70:
71: case '%':
72: term(a|1); expv = lhs/expv; break;
73:
74: case '&':
75: term(a|1); expv &= lhs; break;
76:
77: case '|':
78: term(a|1); expv |= lhs; break;
79:
80: case ')':
81: IF (a&2)==0 THEN error(BADKET); FI
82:
83: default:
84: lp--;
85: return(rc);
86: }
87: OD
88: return(rc);
89: }
90:
91: term(a)
92: { /* item | monadic item | (expr) | */
93:
94: switch ((int)readchar()) {
95:
96: case '*':
97: term(a|1); expv=chkget(expv,DSP); return(1);
98:
99: case '@':
100: term(a|1); expv=chkget(expv,ISP); return(1);
101:
102: case '-':
103: term(a|1); expv = -expv; return(1);
104:
105: case '~':
106: term(a|1); expv = ~expv; return(1);
107:
108: case '(':
109: expr(2);
110: IF *lp!=')'
111: THEN error(BADSYN);
112: ELSE lp++; return(1);
113: FI
114:
115: default:
116: lp--;
117: return(item(a));
118: }
119: }
120:
121: item(a)
122: { /* name [ . local ] | number | . | ^ | <var | <register | 'x | | */
123: INT base, d, regptr;
124: CHAR savc;
125: BOOL hex;
126: L_INT frame;
127: SYMPTR symp;
128:
129: hex=FALSE;
130:
131: readchar();
132: IF symchar(0)
133: THEN readsym();
134: IF lastc=='.'
135: THEN frame= *(ADDR *)(((ADDR)&u[0])+FP); lastframe=0;
136: callpc= *(ADDR *)(((ADDR)&u[0])+PC);
137: WHILE errflg==0
138: DO savpc=callpc;
139: findsym(callpc,ISYM);
140: IF eqsym(symbol.symc,isymbol,'~')
141: THEN break;
142: FI
143: callpc=get(frame+16, DSP);
144: lastframe=frame;
145: frame=get(frame+12,DSP)&EVEN;
146: IF frame==0
147: THEN error(NOCFN);
148: FI
149: OD
150: savlastf=lastframe; savframe=frame;
151: readchar();
152: IF symchar(0)
153: THEN chkloc(expv=frame);
154: FI
155: ELIF (symp=lookupsym(isymbol))==0 THEN error(BADSYM);
156: ELSE expv = symp->symv;
157: FI
158: lp--;
159:
160:
161: ELIF getnum(readchar)
162: THEN ;
163: ELIF lastc=='.'
164: THEN readchar();
165: IF symchar(0)
166: THEN lastframe=savlastf; callpc=savpc;
167: chkloc(savframe);
168: ELSE expv=dot;
169: FI
170: lp--;
171:
172: ELIF lastc=='"'
173: THEN expv=ditto;
174:
175: ELIF lastc=='+'
176: THEN expv=inkdot(dotinc);
177:
178: ELIF lastc=='^'
179: THEN expv=inkdot(-dotinc);
180:
181: ELIF lastc=='<'
182: THEN savc=rdc();
183: IF regptr=getreg(savc)
184: THEN expv= * (ADDR *)(((ADDR)&u[0])+regptr);
185: ELIF (base=varchk(savc)) != -1
186: THEN expv=var[base];
187: ELSE error(BADVAR);
188: FI
189:
190: ELIF lastc=='\''
191: THEN d=4; expv=0;
192: WHILE quotchar()
193: DO IF d--
194: THEN IF d==1 THEN expv <<=16; FI
195: expv |= ((d&1)?lastc:lastc<<8);
196: ELSE error(BADSYN);
197: FI
198: OD
199:
200: ELIF a
201: THEN error(NOADR);
202: ELSE lp--; return(0);
203: FI
204: return(1);
205: }
206:
207: /* service routines for expression reading */
208: getnum(rdf) int (*rdf)();
209: {
210: INT base,d,frpt;
211: BOOL hex;
212: UNION{REAL r; L_INT i;} real;
213: IF digit(lastc) ORF (hex=TRUE, lastc=='#' ANDF hexdigit((*rdf)()))
214: THEN expv = 0;
215: base = (hex ? 16 : radix);
216: WHILE (base>10 ? hexdigit(lastc) : digit(lastc))
217: DO expv = (base==16 ? expv<<4 : expv*base);
218: IF (d=convdig(lastc))>=base THEN error(BADSYN); FI
219: expv += d; (*rdf)();
220: IF expv==0
221: THEN IF (lastc=='x' ORF lastc=='X')
222: THEN hex=TRUE; base=16; (*rdf)();
223: ELIF (lastc=='t' ORF lastc=='T')
224: THEN hex=FALSE; base=10; (*rdf)();
225: ELIF (lastc=='o' ORF lastc=='O')
226: THEN hex=FALSE; base=8; (*rdf)();
227: FI
228: FI
229: OD
230: IF lastc=='.' ANDF (base==10 ORF expv==0) ANDF !hex
231: THEN real.r=expv; frpt=0; base=10;
232: WHILE digit((*rdf)())
233: DO real.r *= base; frpt++;
234: real.r += lastc-'0';
235: OD
236: WHILE frpt--
237: DO real.r /= base; OD
238: expv = real.i;
239: FI
240: peekc=lastc;
241: /* lp--; */
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[8]
253: THEN *p++ = lastc;
254: FI
255: readchar();
256: PER symchar(1) DONE
257: WHILE p < &isymbol[8] DO *p++ = 0; OD
258: }
259:
260: SYMPTR lookupsym(symstr)
261: STRING symstr;
262: {
263: SYMPTR symp;
264: symset();
265: WHILE (symp=symget())
266: #ifndef EDDT
267: DO IF (symp->symf&SYMCHK)==symp->symf
268: ANDF eqsym(symp->symc, symstr,'_')
269: #else
270: DO IF eqsym(symp->symc, symstr, '_')
271: #endif
272: THEN return(symp);
273: FI
274: OD
275: return(0);
276: }
277:
278: hexdigit(c)
279: CHAR c;
280: { return((c>='0' ANDF c<='9') ORF (c>='a' ANDF c<='f'));
281: }
282:
283: convdig(c)
284: CHAR c;
285: {
286: IF digit(c)
287: THEN return(c-'0');
288: ELIF hexdigit(c)
289: THEN return(c-'a'+10);
290: ELSE return(17);
291: FI
292: }
293:
294: digit(c) char c; {return(c>='0' ANDF c<='9');}
295:
296: letter(c) char c; {return(c>='a' ANDF c<='z' ORF c>='A' ANDF c<='Z');}
297:
298: symchar(dig)
299: {
300: IF lastc=='\\' THEN readchar(); return(TRUE); FI
301: return( letter(lastc) ORF lastc=='_' ORF dig ANDF digit(lastc) );
302: }
303:
304: varchk(name)
305: {
306: IF digit(name) THEN return(name-'0'); FI
307: IF letter(name) THEN return((name&037)-1+10); FI
308: return(-1);
309: }
310:
311: chkloc(frame)
312: L_INT frame;
313: {
314: readsym();
315: REP IF localsym(frame)==0 THEN error(BADLOC); FI
316: expv=localval;
317: PER !eqsym(symbol.symc,isymbol,'~') DONE
318: }
319:
320: eqsym(s1, s2, c)
321: REG STRING s1, s2;
322: CHAR c;
323: {
324: IF eqstr(s1,s2)
325: THEN return(TRUE);
326: ELIF *s1==c
327: THEN CHAR s3[8];
328: REG INT i;
329:
330: s3[0]=c;
331: FOR i=1; i<8; i++
332: DO s3[i] = *s2++; OD
333:
334: return(eqstr(s1,s3));
335: FI
336: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.