xref: /csrg-svn/old/adb/adb.vax/expr.c (revision 14468)
1*14468Ssam #ifndef lint
2*14468Ssam static	char sccsid[] = "@(#)expr.c	4.8 08/11/83";
3*14468Ssam #endif
43755Sroot /*
53755Sroot  *
63755Sroot  *	UNIX debugger
73755Sroot  *
83755Sroot  */
93755Sroot 
103755Sroot #include "defs.h"
113755Sroot 
123755Sroot MSG		BADSYM;
133755Sroot MSG		BADVAR;
143755Sroot MSG		BADKET;
153755Sroot MSG		BADSYN;
163755Sroot MSG		NOCFN;
173755Sroot MSG		NOADR;
183755Sroot MSG		BADLOC;
193755Sroot 
203755Sroot ADDR		lastframe;
213755Sroot ADDR		savlastf;
223755Sroot ADDR		savframe;
233755Sroot ADDR		savpc;
243755Sroot ADDR		callpc;
253755Sroot 
263755Sroot 
273755Sroot 
283755Sroot CHAR		*lp;
293755Sroot INT		radix;
303755Sroot STRING		errflg;
313755Sroot L_INT		localval;
326662Smckusick CHAR		isymbol[1024];
333755Sroot 
343755Sroot CHAR		lastc,peekc;
353755Sroot 
363755Sroot L_INT		dot;
373755Sroot L_INT		ditto;
383755Sroot INT		dotinc;
393755Sroot L_INT		var[];
403755Sroot L_INT		expv;
413755Sroot 
423755Sroot 
433755Sroot 
443755Sroot 
expr(a)453755Sroot expr(a)
463755Sroot {	/* term | term dyadic expr |  */
473755Sroot 	INT		rc;
483755Sroot 	L_INT		lhs;
493755Sroot 
503755Sroot 	rdc(); lp--; rc=term(a);
513755Sroot 
523755Sroot 	WHILE rc
533755Sroot 	DO  lhs = expv;
543755Sroot 
553755Sroot 	    switch ((int)readchar()) {
563755Sroot 
573755Sroot 		    case '+':
583755Sroot 			term(a|1); expv += lhs; break;
593755Sroot 
603755Sroot 		    case '-':
613755Sroot 			term(a|1); expv = lhs - expv; break;
623755Sroot 
633755Sroot 		    case '#':
643755Sroot 			term(a|1); expv = round(lhs,expv); break;
653755Sroot 
663755Sroot 		    case '*':
673755Sroot 			term(a|1); expv *= lhs; break;
683755Sroot 
693755Sroot 		    case '%':
703755Sroot 			term(a|1); expv = lhs/expv; break;
713755Sroot 
723755Sroot 		    case '&':
733755Sroot 			term(a|1); expv &= lhs; break;
743755Sroot 
753755Sroot 		    case '|':
763755Sroot 			term(a|1); expv |= lhs; break;
773755Sroot 
783755Sroot 		    case ')':
793755Sroot 			IF (a&2)==0 THEN error(BADKET); FI
803755Sroot 
813755Sroot 		    default:
823755Sroot 			lp--;
8312209Ssam 			return(rc);
843755Sroot 	    }
853755Sroot 	OD
863755Sroot 	return(rc);
873755Sroot }
883755Sroot 
term(a)893755Sroot term(a)
903755Sroot {	/* item | monadic item | (expr) | */
913755Sroot 
923755Sroot 	switch ((int)readchar()) {
933755Sroot 
943755Sroot 		    case '*':
953755Sroot 			term(a|1); expv=chkget(expv,DSP); return(1);
963755Sroot 
973755Sroot 		    case '@':
983755Sroot 			term(a|1); expv=chkget(expv,ISP); return(1);
993755Sroot 
1003755Sroot 		    case '-':
1013755Sroot 			term(a|1); expv = -expv; return(1);
1023755Sroot 
1033755Sroot 		    case '~':
10412403Srrh 			term(a|1); expv = ~expv; return(1);
1053755Sroot 
10612403Srrh 		    case '#':
10712403Srrh 			term(a|1); expv = !expv; return(1);
10812403Srrh 
10912403Srrh 		    case '(':
11012403Srrh 			expr(2);
11112403Srrh 			IF *lp!=')'
11212403Srrh 			THEN	error(BADSYN);
11312403Srrh 			ELSE	lp++; return(1);
11412403Srrh 			FI
11512403Srrh 
11612403Srrh 		    default:
11712403Srrh 			lp--;
11812403Srrh 			return(item(a));
11912403Srrh 	}
12012403Srrh }
12112403Srrh 
item(a)12212403Srrh item(a)
12312403Srrh {	/* name [ . local ] | number | . | ^ | <var | <register | 'x | | */
12412403Srrh 	INT		base, d;
12512403Srrh 	CHAR		savc;
12612403Srrh 	BOOL		hex;
12712403Srrh 	L_INT		frame;
12812403Srrh 	register struct nlist *symp;
12912403Srrh 	int regptr;
13012403Srrh 
13112403Srrh 	hex=FALSE;
13212403Srrh 
13312403Srrh 	readchar();
13412403Srrh 	IF symchar(0)
13512403Srrh 	THEN	readsym();
13612403Srrh 		IF lastc=='.'
13712403Srrh 		THEN	frame= *(ADDR *)(((ADDR)&u)+FP); lastframe=0;
13812403Srrh 			callpc= *(ADDR *)(((ADDR)&u)+PC);
13912403Srrh 			WHILE errflg==0
14012403Srrh 			DO  savpc=callpc;
14112403Srrh 				findsym(callpc,ISYM);
14212403Srrh 			    IF  eqsym(cursym->n_un.n_name,isymbol,'~')
14312403Srrh 			    THEN break;
14412403Srrh 			    FI
14512403Srrh 				callpc=get(frame+16, DSP);
14612403Srrh 			    lastframe=frame;
14712403Srrh 			    frame=get(frame+12,DSP)&EVEN;
14812403Srrh 			    IF frame==0
14912403Srrh 			    THEN error(NOCFN);
15012403Srrh 			    FI
15112403Srrh 			OD
15212403Srrh 			savlastf=lastframe; savframe=frame;
15312403Srrh 			readchar();
15412403Srrh 			IF symchar(0)
15512403Srrh 			THEN	chkloc(expv=frame);
15612403Srrh 			FI
15712403Srrh 		ELIF (symp=lookup(isymbol))==0 THEN error(BADSYM);
15812403Srrh 		ELSE expv = symp->n_value;
15912403Srrh 		FI
16012403Srrh 		lp--;
16112403Srrh 
1623755Sroot 	ELIF getnum(readchar)
1633755Sroot 	THEN ;
1643755Sroot 	ELIF lastc=='.'
1653755Sroot 	THEN	readchar();
1663755Sroot 		IF symchar(0)
1673755Sroot 		THEN	lastframe=savlastf; callpc=savpc;
1683755Sroot 			chkloc(savframe);
1693755Sroot 		ELSE	expv=dot;
1703755Sroot 		FI
1713755Sroot 		lp--;
1723755Sroot 
1733755Sroot 	ELIF lastc=='"'
1743755Sroot 	THEN	expv=ditto;
1753755Sroot 
1763755Sroot 	ELIF lastc=='+'
1773755Sroot 	THEN	expv=inkdot(dotinc);
1783755Sroot 
1793755Sroot 	ELIF lastc=='^'
1803755Sroot 	THEN	expv=inkdot(-dotinc);
1813755Sroot 
1823755Sroot 	ELIF lastc=='<'
1833755Sroot 	THEN	savc=rdc();
1843755Sroot 		IF regptr=getreg(savc)
1853777Sroot 		THEN	IF kcore THEN expv = *(int *)regptr;
1863777Sroot 			ELSE expv= * (ADDR *)(((ADDR)&u)+regptr); FI
1873755Sroot 		ELIF (base=varchk(savc)) != -1
1883755Sroot 		THEN	expv=var[base];
1893755Sroot 		ELSE	error(BADVAR);
1903755Sroot 		FI
1913755Sroot 
1923755Sroot 	ELIF lastc=='\''
1933755Sroot 	THEN	d=4; expv=0;
1943755Sroot 		WHILE quotchar()
1953755Sroot 		DO  IF d--
1967321Swnj 		    THEN expv = (expv << 8) | lastc;
1973755Sroot 		    ELSE error(BADSYN);
1983755Sroot 		    FI
1993755Sroot 		OD
2003755Sroot 
2013755Sroot 	ELIF a
2023755Sroot 	THEN	error(NOADR);
2033755Sroot 	ELSE	lp--; return(0);
2043755Sroot 	FI
2053755Sroot 	return(1);
2063755Sroot }
2073755Sroot 
2083755Sroot /* service routines for expression reading */
2093755Sroot getnum(rdf) int (*rdf)();
2103755Sroot {
2113755Sroot 	INT base,d,frpt;
2123755Sroot 	BOOL hex;
2133755Sroot 	UNION{REAL r; L_INT i;} real;
2143755Sroot 	IF isdigit(lastc) ORF (hex=TRUE, lastc=='#' ANDF isxdigit((*rdf)()))
2153755Sroot 	THEN	expv = 0;
2163755Sroot 		base = (hex ? 16 : radix);
2173755Sroot 		WHILE (base>10 ? isxdigit(lastc) : isdigit(lastc))
2183755Sroot 		DO  expv = (base==16 ? expv<<4 : expv*base);
2193755Sroot 		    IF (d=convdig(lastc))>=base THEN error(BADSYN); FI
2203755Sroot 		    expv += d; (*rdf)();
2213755Sroot 		    IF expv==0
2223755Sroot 		    THEN IF (lastc=='x' ORF lastc=='X')
2233755Sroot 				 THEN hex=TRUE; base=16; (*rdf)();
2243755Sroot 				 ELIF (lastc=='t' ORF lastc=='T')
2253755Sroot 			     THEN hex=FALSE; base=10; (*rdf)();
2263755Sroot 		    	 ELIF (lastc=='o' ORF lastc=='O')
2273755Sroot 		    	 THEN hex=FALSE; base=8; (*rdf)();
2283755Sroot 				 FI
2293755Sroot 		    FI
2303755Sroot 		OD
2313755Sroot 		IF lastc=='.' ANDF (base==10 ORF expv==0) ANDF !hex
2323755Sroot 		THEN	real.r=expv; frpt=0; base=10;
2333755Sroot 			WHILE isdigit((*rdf)())
2343755Sroot 			DO	real.r *= base; frpt++;
2353755Sroot 				real.r += lastc-'0';
2363755Sroot 			OD
2373755Sroot 			WHILE frpt--
2383755Sroot 			DO	real.r /= base; OD
2393755Sroot 			expv = real.i;
2403755Sroot 		FI
2413755Sroot 		peekc=lastc;
2423755Sroot /*		lp--; */
2433755Sroot 		return(1);
2443755Sroot 	ELSE return(0);
2453755Sroot 	FI
2463755Sroot }
2473755Sroot 
readsym()2483755Sroot readsym()
2493755Sroot {
2503755Sroot 	REG char	*p;
2513755Sroot 
2523755Sroot 	p = isymbol;
2533755Sroot 	REP IF p < &isymbol[sizeof(isymbol)-1]
2543755Sroot 	    THEN *p++ = lastc;
2553755Sroot 	    FI
2563755Sroot 	    readchar();
2573755Sroot 	PER symchar(1) DONE
2583755Sroot 	*p++ = 0;
2593755Sroot }
2603755Sroot 
convdig(c)2613755Sroot convdig(c)
2623755Sroot CHAR c;
2633755Sroot {
2643755Sroot 	IF isdigit(c)
2653755Sroot 	THEN	return(c-'0');
2663755Sroot 	ELIF isxdigit(c)
2673755Sroot 	THEN	return(c-'a'+10);
2683755Sroot 	ELSE	return(17);
2693755Sroot 	FI
2703755Sroot }
2713755Sroot 
symchar(dig)2723755Sroot symchar(dig)
2733755Sroot {
2743755Sroot 	IF lastc=='\\' THEN readchar(); return(TRUE); FI
2753755Sroot 	return( isalpha(lastc) ORF lastc=='_' ORF dig ANDF isdigit(lastc) );
2763755Sroot }
2773755Sroot 
varchk(name)2783755Sroot varchk(name)
2793755Sroot {
2803755Sroot 	IF isdigit(name) THEN return(name-'0'); FI
2813755Sroot 	IF isalpha(name) THEN return((name&037)-1+10); FI
2823755Sroot 	return(-1);
2833755Sroot }
2843755Sroot 
chkloc(frame)2853755Sroot chkloc(frame)
2863755Sroot L_INT		frame;
2873755Sroot {
2883755Sroot 	readsym();
2893755Sroot 	REP IF localsym(frame)==0 THEN error(BADLOC); FI
2903755Sroot 	    expv=localval;
2913755Sroot 	PER !eqsym(cursym->n_un.n_name,isymbol,'~') DONE
2923755Sroot }
2933755Sroot 
eqsym(s1,s2,c)2943755Sroot eqsym(s1, s2, c)
2953755Sroot 	register char *s1, *s2;
2963755Sroot {
2973755Sroot 
2983755Sroot 	if (!strcmp(s1,s2))
2993755Sroot 		return (1);
3003755Sroot 	if (*s1 == c && !strcmp(s1+1, s2))
3013755Sroot 		return (1);
3023755Sroot 	return (0);
3033755Sroot }
304