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