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