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