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