xref: /csrg-svn/old/adb/adb.vax/expr.c (revision 12403)
13755Sroot #
23755Sroot /*
33755Sroot  *
43755Sroot  *	UNIX debugger
53755Sroot  *
63755Sroot  */
73755Sroot 
83755Sroot #include "defs.h"
9*12403Srrh static	char sccsid[] = "@(#)expr.c	4.7 05/12/83";
103755Sroot 
113755Sroot MSG		BADSYM;
123755Sroot MSG		BADVAR;
133755Sroot MSG		BADKET;
143755Sroot MSG		BADSYN;
153755Sroot MSG		NOCFN;
163755Sroot MSG		NOADR;
173755Sroot MSG		BADLOC;
183755Sroot 
193755Sroot ADDR		lastframe;
203755Sroot ADDR		savlastf;
213755Sroot ADDR		savframe;
223755Sroot ADDR		savpc;
233755Sroot ADDR		callpc;
243755Sroot 
253755Sroot 
263755Sroot 
273755Sroot CHAR		*lp;
283755Sroot INT		radix;
293755Sroot STRING		errflg;
303755Sroot L_INT		localval;
316662Smckusick CHAR		isymbol[1024];
323755Sroot 
333755Sroot CHAR		lastc,peekc;
343755Sroot 
353755Sroot L_INT		dot;
363755Sroot L_INT		ditto;
373755Sroot INT		dotinc;
383755Sroot L_INT		var[];
393755Sroot L_INT		expv;
403755Sroot 
413755Sroot 
423755Sroot 
433755Sroot 
443755Sroot expr(a)
453755Sroot {	/* term | term dyadic expr |  */
463755Sroot 	INT		rc;
473755Sroot 	L_INT		lhs;
483755Sroot 
493755Sroot 	rdc(); lp--; rc=term(a);
503755Sroot 
513755Sroot 	WHILE rc
523755Sroot 	DO  lhs = expv;
533755Sroot 
543755Sroot 	    switch ((int)readchar()) {
553755Sroot 
563755Sroot 		    case '+':
573755Sroot 			term(a|1); expv += lhs; break;
583755Sroot 
593755Sroot 		    case '-':
603755Sroot 			term(a|1); expv = lhs - expv; break;
613755Sroot 
623755Sroot 		    case '#':
633755Sroot 			term(a|1); expv = round(lhs,expv); break;
643755Sroot 
653755Sroot 		    case '*':
663755Sroot 			term(a|1); expv *= lhs; break;
673755Sroot 
683755Sroot 		    case '%':
693755Sroot 			term(a|1); expv = lhs/expv; break;
703755Sroot 
713755Sroot 		    case '&':
723755Sroot 			term(a|1); expv &= lhs; break;
733755Sroot 
743755Sroot 		    case '|':
753755Sroot 			term(a|1); expv |= lhs; break;
763755Sroot 
773755Sroot 		    case ')':
783755Sroot 			IF (a&2)==0 THEN error(BADKET); FI
793755Sroot 
803755Sroot 		    default:
813755Sroot 			lp--;
8212209Ssam 			return(rc);
833755Sroot 	    }
843755Sroot 	OD
853755Sroot 	return(rc);
863755Sroot }
873755Sroot 
883755Sroot term(a)
893755Sroot {	/* item | monadic item | (expr) | */
903755Sroot 
913755Sroot 	switch ((int)readchar()) {
923755Sroot 
933755Sroot 		    case '*':
943755Sroot 			term(a|1); expv=chkget(expv,DSP); return(1);
953755Sroot 
963755Sroot 		    case '@':
973755Sroot 			term(a|1); expv=chkget(expv,ISP); return(1);
983755Sroot 
993755Sroot 		    case '-':
1003755Sroot 			term(a|1); expv = -expv; return(1);
1013755Sroot 
1023755Sroot 		    case '~':
103*12403Srrh 			term(a|1); expv = ~expv; return(1);
1043755Sroot 
105*12403Srrh 		    case '#':
106*12403Srrh 			term(a|1); expv = !expv; return(1);
107*12403Srrh 
108*12403Srrh 		    case '(':
109*12403Srrh 			expr(2);
110*12403Srrh 			IF *lp!=')'
111*12403Srrh 			THEN	error(BADSYN);
112*12403Srrh 			ELSE	lp++; return(1);
113*12403Srrh 			FI
114*12403Srrh 
115*12403Srrh 		    default:
116*12403Srrh 			lp--;
117*12403Srrh 			return(item(a));
118*12403Srrh 	}
119*12403Srrh }
120*12403Srrh 
121*12403Srrh item(a)
122*12403Srrh {	/* name [ . local ] | number | . | ^ | <var | <register | 'x | | */
123*12403Srrh 	INT		base, d;
124*12403Srrh 	CHAR		savc;
125*12403Srrh 	BOOL		hex;
126*12403Srrh 	L_INT		frame;
127*12403Srrh 	register struct nlist *symp;
128*12403Srrh 	int regptr;
129*12403Srrh 
130*12403Srrh 	hex=FALSE;
131*12403Srrh 
132*12403Srrh 	readchar();
133*12403Srrh 	IF symchar(0)
134*12403Srrh 	THEN	readsym();
135*12403Srrh 		IF lastc=='.'
136*12403Srrh 		THEN	frame= *(ADDR *)(((ADDR)&u)+FP); lastframe=0;
137*12403Srrh 			callpc= *(ADDR *)(((ADDR)&u)+PC);
138*12403Srrh 			WHILE errflg==0
139*12403Srrh 			DO  savpc=callpc;
140*12403Srrh 				findsym(callpc,ISYM);
141*12403Srrh 			    IF  eqsym(cursym->n_un.n_name,isymbol,'~')
142*12403Srrh 			    THEN break;
143*12403Srrh 			    FI
144*12403Srrh 				callpc=get(frame+16, DSP);
145*12403Srrh 			    lastframe=frame;
146*12403Srrh 			    frame=get(frame+12,DSP)&EVEN;
147*12403Srrh 			    IF frame==0
148*12403Srrh 			    THEN error(NOCFN);
149*12403Srrh 			    FI
150*12403Srrh 			OD
151*12403Srrh 			savlastf=lastframe; savframe=frame;
152*12403Srrh 			readchar();
153*12403Srrh 			IF symchar(0)
154*12403Srrh 			THEN	chkloc(expv=frame);
155*12403Srrh 			FI
156*12403Srrh 		ELIF (symp=lookup(isymbol))==0 THEN error(BADSYM);
157*12403Srrh 		ELSE expv = symp->n_value;
158*12403Srrh 		FI
159*12403Srrh 		lp--;
160*12403Srrh 
1613755Sroot 	ELIF getnum(readchar)
1623755Sroot 	THEN ;
1633755Sroot 	ELIF lastc=='.'
1643755Sroot 	THEN	readchar();
1653755Sroot 		IF symchar(0)
1663755Sroot 		THEN	lastframe=savlastf; callpc=savpc;
1673755Sroot 			chkloc(savframe);
1683755Sroot 		ELSE	expv=dot;
1693755Sroot 		FI
1703755Sroot 		lp--;
1713755Sroot 
1723755Sroot 	ELIF lastc=='"'
1733755Sroot 	THEN	expv=ditto;
1743755Sroot 
1753755Sroot 	ELIF lastc=='+'
1763755Sroot 	THEN	expv=inkdot(dotinc);
1773755Sroot 
1783755Sroot 	ELIF lastc=='^'
1793755Sroot 	THEN	expv=inkdot(-dotinc);
1803755Sroot 
1813755Sroot 	ELIF lastc=='<'
1823755Sroot 	THEN	savc=rdc();
1833755Sroot 		IF regptr=getreg(savc)
1843777Sroot 		THEN	IF kcore THEN expv = *(int *)regptr;
1853777Sroot 			ELSE expv= * (ADDR *)(((ADDR)&u)+regptr); FI
1863755Sroot 		ELIF (base=varchk(savc)) != -1
1873755Sroot 		THEN	expv=var[base];
1883755Sroot 		ELSE	error(BADVAR);
1893755Sroot 		FI
1903755Sroot 
1913755Sroot 	ELIF lastc=='\''
1923755Sroot 	THEN	d=4; expv=0;
1933755Sroot 		WHILE quotchar()
1943755Sroot 		DO  IF d--
1957321Swnj 		    THEN expv = (expv << 8) | lastc;
1963755Sroot 		    ELSE error(BADSYN);
1973755Sroot 		    FI
1983755Sroot 		OD
1993755Sroot 
2003755Sroot 	ELIF a
2013755Sroot 	THEN	error(NOADR);
2023755Sroot 	ELSE	lp--; return(0);
2033755Sroot 	FI
2043755Sroot 	return(1);
2053755Sroot }
2063755Sroot 
2073755Sroot /* service routines for expression reading */
2083755Sroot getnum(rdf) int (*rdf)();
2093755Sroot {
2103755Sroot 	INT base,d,frpt;
2113755Sroot 	BOOL hex;
2123755Sroot 	UNION{REAL r; L_INT i;} real;
2133755Sroot 	IF isdigit(lastc) ORF (hex=TRUE, lastc=='#' ANDF isxdigit((*rdf)()))
2143755Sroot 	THEN	expv = 0;
2153755Sroot 		base = (hex ? 16 : radix);
2163755Sroot 		WHILE (base>10 ? isxdigit(lastc) : isdigit(lastc))
2173755Sroot 		DO  expv = (base==16 ? expv<<4 : expv*base);
2183755Sroot 		    IF (d=convdig(lastc))>=base THEN error(BADSYN); FI
2193755Sroot 		    expv += d; (*rdf)();
2203755Sroot 		    IF expv==0
2213755Sroot 		    THEN IF (lastc=='x' ORF lastc=='X')
2223755Sroot 				 THEN hex=TRUE; base=16; (*rdf)();
2233755Sroot 				 ELIF (lastc=='t' ORF lastc=='T')
2243755Sroot 			     THEN hex=FALSE; base=10; (*rdf)();
2253755Sroot 		    	 ELIF (lastc=='o' ORF lastc=='O')
2263755Sroot 		    	 THEN hex=FALSE; base=8; (*rdf)();
2273755Sroot 				 FI
2283755Sroot 		    FI
2293755Sroot 		OD
2303755Sroot 		IF lastc=='.' ANDF (base==10 ORF expv==0) ANDF !hex
2313755Sroot 		THEN	real.r=expv; frpt=0; base=10;
2323755Sroot 			WHILE isdigit((*rdf)())
2333755Sroot 			DO	real.r *= base; frpt++;
2343755Sroot 				real.r += lastc-'0';
2353755Sroot 			OD
2363755Sroot 			WHILE frpt--
2373755Sroot 			DO	real.r /= base; OD
2383755Sroot 			expv = real.i;
2393755Sroot 		FI
2403755Sroot 		peekc=lastc;
2413755Sroot /*		lp--; */
2423755Sroot 		return(1);
2433755Sroot 	ELSE return(0);
2443755Sroot 	FI
2453755Sroot }
2463755Sroot 
2473755Sroot readsym()
2483755Sroot {
2493755Sroot 	REG char	*p;
2503755Sroot 
2513755Sroot 	p = isymbol;
2523755Sroot 	REP IF p < &isymbol[sizeof(isymbol)-1]
2533755Sroot 	    THEN *p++ = lastc;
2543755Sroot 	    FI
2553755Sroot 	    readchar();
2563755Sroot 	PER symchar(1) DONE
2573755Sroot 	*p++ = 0;
2583755Sroot }
2593755Sroot 
2603755Sroot convdig(c)
2613755Sroot CHAR c;
2623755Sroot {
2633755Sroot 	IF isdigit(c)
2643755Sroot 	THEN	return(c-'0');
2653755Sroot 	ELIF isxdigit(c)
2663755Sroot 	THEN	return(c-'a'+10);
2673755Sroot 	ELSE	return(17);
2683755Sroot 	FI
2693755Sroot }
2703755Sroot 
2713755Sroot symchar(dig)
2723755Sroot {
2733755Sroot 	IF lastc=='\\' THEN readchar(); return(TRUE); FI
2743755Sroot 	return( isalpha(lastc) ORF lastc=='_' ORF dig ANDF isdigit(lastc) );
2753755Sroot }
2763755Sroot 
2773755Sroot varchk(name)
2783755Sroot {
2793755Sroot 	IF isdigit(name) THEN return(name-'0'); FI
2803755Sroot 	IF isalpha(name) THEN return((name&037)-1+10); FI
2813755Sroot 	return(-1);
2823755Sroot }
2833755Sroot 
2843755Sroot chkloc(frame)
2853755Sroot L_INT		frame;
2863755Sroot {
2873755Sroot 	readsym();
2883755Sroot 	REP IF localsym(frame)==0 THEN error(BADLOC); FI
2893755Sroot 	    expv=localval;
2903755Sroot 	PER !eqsym(cursym->n_un.n_name,isymbol,'~') DONE
2913755Sroot }
2923755Sroot 
2933755Sroot eqsym(s1, s2, c)
2943755Sroot 	register char *s1, *s2;
2953755Sroot {
2963755Sroot 
2973755Sroot 	if (!strcmp(s1,s2))
2983755Sroot 		return (1);
2993755Sroot 	if (*s1 == c && !strcmp(s1+1, s2))
3003755Sroot 		return (1);
3013755Sroot 	return (0);
3023755Sroot }
303