xref: /csrg-svn/old/adb/adb.tahoe/expr.c (revision 29663)
126417Ssam #ifndef lint
2*29663Ssam static	char sccsid[] = "@(#)expr.c	1.2 (Berkeley) 07/25/86";
326417Ssam #endif
426417Ssam /*
526417Ssam  *
626417Ssam  *	UNIX debugger
726417Ssam  *
826417Ssam  */
926417Ssam 
1026417Ssam #include "defs.h"
1126417Ssam 
1226417Ssam MSG		BADSYM;
1326417Ssam MSG		BADVAR;
1426417Ssam MSG		BADKET;
1526417Ssam MSG		BADSYN;
1626417Ssam MSG		NOCFN;
1726417Ssam MSG		NOADR;
1826417Ssam MSG		BADLOC;
1926417Ssam 
2026417Ssam ADDR		lastframe;
2126417Ssam ADDR		savlastf;
2226417Ssam ADDR		savframe;
2326417Ssam ADDR		savpc;
2426417Ssam ADDR		callpc;
2526417Ssam 
2626417Ssam 
2726417Ssam 
2826417Ssam CHAR		*lp;
2926417Ssam INT		radix;
3026417Ssam STRING		errflg;
3126417Ssam ADDR		localval;
3226417Ssam CHAR		isymbol[1024];
3326417Ssam 
3426417Ssam CHAR		lastc,peekc;
3526417Ssam 
3626417Ssam L_INT		dot;
3726417Ssam L_INT		ditto;
3826417Ssam INT		dotinc;
3926417Ssam L_INT		var[];
4026417Ssam L_INT		expv;
4126417Ssam 
4226417Ssam 
4326417Ssam 
4426417Ssam 
expr(a)4526417Ssam expr(a)
4626417Ssam {	/* term | term dyadic expr |  */
4726417Ssam 	REG	rc;
4826417Ssam 	REG	L_INT	lhs;
4926417Ssam 
5026417Ssam 	rdc(); lp--; rc=term(a);
5126417Ssam 
5226417Ssam 	WHILE rc
5326417Ssam 	DO  lhs = expv;
5426417Ssam 
5526417Ssam 	    switch ((int)readchar()) {
5626417Ssam 
5726417Ssam 		    case '+':
5826417Ssam 			term(a|1); expv += lhs; break;
5926417Ssam 
6026417Ssam 		    case '-':
6126417Ssam 			term(a|1); expv = lhs - expv; break;
6226417Ssam 
6326417Ssam 		    case '#':
6426417Ssam 			term(a|1); expv = round(lhs,expv); break;
6526417Ssam 
6626417Ssam 		    case '*':
6726417Ssam 			term(a|1); expv *= lhs; break;
6826417Ssam 
6926417Ssam 		    case '%':
7026417Ssam 			term(a|1); expv = lhs/expv; break;
7126417Ssam 
7226417Ssam 		    case '&':
7326417Ssam 			term(a|1); expv &= lhs; break;
7426417Ssam 
7526417Ssam 		    case '|':
7626417Ssam 			term(a|1); expv |= lhs; break;
7726417Ssam 
7826417Ssam 		    case ')':
7926417Ssam 			IF (a&2)==0 THEN error(BADKET); FI
8026417Ssam 
8126417Ssam 		    default:
8226417Ssam 			lp--;
8326417Ssam 			return(rc);
8426417Ssam 	    }
8526417Ssam 	OD
8626417Ssam 	return(rc);
8726417Ssam }
8826417Ssam 
term(a)8926417Ssam term(a)
9026417Ssam {	/* item | monadic item | (expr) | */
9126417Ssam 
9226417Ssam 	switch ((int)readchar()) {
9326417Ssam 
9426417Ssam 		    case '*':
9526417Ssam 			term(a|1); expv=chkget(expv,DSP); return(1);
9626417Ssam 
9726417Ssam 		    case '@':
9826417Ssam 			term(a|1); expv=chkget(expv,ISP); return(1);
9926417Ssam 
10026417Ssam 		    case '-':
10126417Ssam 			term(a|1); expv = -expv; return(1);
10226417Ssam 
10326417Ssam 		    case '~':
10426417Ssam 			term(a|1); expv = ~expv; return(1);
10526417Ssam 
10626417Ssam 		    case '#':
10726417Ssam 			term(a|1); expv = !expv; return(1);
10826417Ssam 
10926417Ssam 		    case '(':
11026417Ssam 			expr(2);
11126417Ssam 			IF *lp!=')'
11226417Ssam 			THEN	error(BADSYN);
11326417Ssam 			ELSE	lp++; return(1);
11426417Ssam 			FI
11526417Ssam 
11626417Ssam 		    default:
11726417Ssam 			lp--;
11826417Ssam 			return(item(a));
11926417Ssam 	}
12026417Ssam }
12126417Ssam 
item(a)12226417Ssam item(a)
12326417Ssam {	/* name [ . local ] | number | . | ^ | <var | <register | 'x | | */
12426417Ssam 	REG		base, d, regptr;
12526417Ssam 	CHAR		savc;
12626417Ssam 	REG	L_INT		frame;
12726417Ssam 	register struct nlist *symp;
12826417Ssam 
12926417Ssam 	readchar();
13026417Ssam 	IF symchar(0)
13126417Ssam 	THEN	readsym();
13226417Ssam 		IF lastc=='.'
13326417Ssam 		THEN	frame= *(ADDR *)(((ADDR)(&u))+FP); lastframe=0;
13426417Ssam 			callpc= *(ADDR *)(((ADDR)(&u))+PC);
13526417Ssam 			WHILE errflg==0
13626417Ssam 			DO  savpc=callpc;
13726417Ssam 				findsym(callpc,ISYM);
13826417Ssam 			    IF  eqsym(cursym->n_un.n_name,isymbol,'~')
13926417Ssam 			    THEN break;
14026417Ssam 			    FI
14126417Ssam 				callpc=get(frame-8, DSP);
14226417Ssam 			    lastframe=frame;
14326417Ssam 			    frame=get(frame, DSP)&ALIGN;
14426417Ssam 			    IF frame==0
14526417Ssam 			    THEN error(NOCFN);
14626417Ssam 			    FI
14726417Ssam 			OD
14826417Ssam 			savlastf=lastframe; savframe=frame;
14926417Ssam 			readchar();
15026417Ssam 			IF symchar(0)
15126417Ssam 			THEN	chkloc(expv=frame);
15226417Ssam 			FI
15326417Ssam 		ELIF (symp=lookup(isymbol))==0 THEN error(BADSYM);
15426417Ssam 		ELSE expv = symp->n_value;
15526417Ssam 		FI
15626417Ssam 		lp--;
15726417Ssam 
15826417Ssam 
15926417Ssam 	ELIF getnum()
16026417Ssam 	THEN ;
16126417Ssam 	ELIF lastc=='.'
16226417Ssam 	THEN	readchar();
16326417Ssam 		IF symchar(0)
16426417Ssam 		THEN	lastframe=savlastf; callpc=savpc;
16526417Ssam 			chkloc(savframe);
16626417Ssam 		ELSE	expv=dot;
16726417Ssam 		FI
16826417Ssam 		lp--;
16926417Ssam 
17026417Ssam 	ELIF lastc=='"'
17126417Ssam 	THEN	expv=ditto;
17226417Ssam 
17326417Ssam 	ELIF lastc=='+'
17426417Ssam 	THEN	expv=inkdot(dotinc);
17526417Ssam 
17626417Ssam 	ELIF lastc=='^'
17726417Ssam 	THEN	expv=inkdot(-dotinc);
17826417Ssam 
17926417Ssam 	ELIF lastc=='<'
18026417Ssam 	THEN	savc=rdc();
181*29663Ssam 		IF (regptr=getreg(savc)) != -1
18226417Ssam 		THEN	IF kcore THEN expv = *(int *)regptr;
18326417Ssam 			ELSE expv= *(ADDR *)(((ADDR)(&u))+regptr); FI
18426417Ssam 		ELIF (base=varchk(savc)) != -1
18526417Ssam 		THEN	expv=var[base];
18626417Ssam 		ELSE	error(BADVAR);
18726417Ssam 		FI
18826417Ssam 
18926417Ssam 	ELIF lastc=='\''
19026417Ssam 	THEN	d=4; expv=0;
19126417Ssam 		WHILE quotchar()
19226417Ssam 		DO  IF d--
19326417Ssam 		    THEN expv <<= 8;
19426417Ssam 			 expv |= lastc;
19526417Ssam 		    ELSE error(BADSYN);
19626417Ssam 		    FI
19726417Ssam 		OD
19826417Ssam 
19926417Ssam 	ELIF a
20026417Ssam 	THEN	error(NOADR);
20126417Ssam 	ELSE lp--; return(0);
20226417Ssam 	FI
20326417Ssam 	return(1);
20426417Ssam }
20526417Ssam 
20626417Ssam /* service routines for expression reading */
getnum()20726417Ssam getnum()
20826417Ssam {
20926417Ssam 	REG base,d,frpt;
21026417Ssam 	UNION{REAL r; L_INT i;} real;
21126417Ssam 	IF (base = radix) < 0 THEN base = -base; FI
21226417Ssam 	IF isdigit(lastc)
21326417Ssam 	THEN	expv = 0;
21426417Ssam 		WHILE (base>10 ? isxdigit(lastc) : isdigit(lastc))
21526417Ssam 		DO
21626417Ssam 		    REG m;
21726417Ssam 		    m = MAXINT/base;
21826417Ssam 		    if(expv>m)
21926417Ssam 			/* avoid overflow */
22026417Ssam 			expv = (expv-m)*base+m*base;
22126417Ssam 		    else
22226417Ssam 			expv *= base;
22326417Ssam 		    IF (d=convdig(lastc))>=base ORF d<0 THEN error(BADSYN); FI
22426417Ssam 		    expv += d; readchar();
22526417Ssam 		    IF expv==0
22626417Ssam 		    THEN IF (lastc=='x' ORF lastc=='X')
22726417Ssam 				 THEN base=16; readchar();
22826417Ssam 				 ELIF (lastc=='t' ORF lastc=='T')
22926417Ssam 			     THEN base=10; readchar();
23026417Ssam 		    	 ELIF (lastc=='o' ORF lastc=='O')
23126417Ssam 		    	 THEN base=8; readchar();
23226417Ssam 				 FI
23326417Ssam 		    FI
23426417Ssam 		OD
23526417Ssam 		IF lastc=='.' ANDF (base==10 ORF expv==0)
23626417Ssam 		THEN	real.r=expv; frpt=0; base=10;
23726417Ssam 			WHILE isdigit(readchar())
23826417Ssam 			DO	real.r *= base; frpt++;
23926417Ssam 				real.r += lastc-'0';
24026417Ssam 			OD
24126417Ssam 			WHILE frpt--
24226417Ssam 			DO	real.r /= base; OD
24326417Ssam 			expv = real.i;
24426417Ssam 		FI
24526417Ssam 		peekc=lastc;
24626417Ssam 		return(1);
24726417Ssam 	ELSE return(0);
24826417Ssam 	FI
24926417Ssam }
25026417Ssam 
readsym()25126417Ssam readsym()
25226417Ssam {
25326417Ssam 	REG char	*p;
25426417Ssam 
25526417Ssam 	p = isymbol;
25626417Ssam 	REP IF p < &isymbol[sizeof(isymbol)-1]
25726417Ssam 	    THEN *p++ = lastc;
25826417Ssam 	    FI
25926417Ssam 	    readchar();
26026417Ssam 	PER symchar(1) DONE
26126417Ssam 	*p++ = 0;
26226417Ssam }
26326417Ssam 
convdig(c)26426417Ssam convdig(c)
26526417Ssam CHAR c;
26626417Ssam {
26726417Ssam 	IF isdigit(c)
26826417Ssam 	THEN	return(c-'0');
26926417Ssam 	ELIF isxdigit(c)
27026417Ssam 	THEN	return(c-'a'+10);
27126417Ssam 	ELSE return(-1);
27226417Ssam 	FI
27326417Ssam }
27426417Ssam 
symchar(dig)27526417Ssam symchar(dig)
27626417Ssam {
27726417Ssam 	IF lastc=='\\' THEN readchar(); return(TRUE); FI
27826417Ssam 	return ( isalpha(lastc) ORF lastc=='_' ORF dig ANDF isdigit(lastc) );
27926417Ssam }
28026417Ssam 
varchk(name)28126417Ssam varchk(name)
28226417Ssam REG name;
28326417Ssam {
28426417Ssam 	IF isdigit(name) THEN return(name-'0'); FI
28526417Ssam 	IF isalpha(name) THEN return((name&037)-1+10); FI
28626417Ssam 	return(-1);
28726417Ssam }
28826417Ssam 
chkloc(frame)28926417Ssam chkloc(frame)
29026417Ssam L_INT		frame;
29126417Ssam {
29226417Ssam 	readsym();
29326417Ssam 	REP IF localsym(frame)==0 THEN error(BADLOC); FI
29426417Ssam 	    expv=localval;
29526417Ssam 	PER !eqsym(cursym->n_un.n_name,isymbol,'~') DONE
29626417Ssam }
29726417Ssam 
eqsym(s1,s2,c)29826417Ssam eqsym(s1, s2, c)
29926417Ssam 	register char *s1, *s2;
30026417Ssam {
30126417Ssam 
30226417Ssam 	if (!strcmp(s1,s2))
30326417Ssam 		return (1);
30426417Ssam 	if (*s1 == c && !strcmp(s1+1, s2))
30526417Ssam 		return (1);
30626417Ssam 	return (0);
30726417Ssam }
308