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