xref: /csrg-svn/old/adb/adb.vax/expr.c (revision 7321)
13755Sroot #
23755Sroot /*
33755Sroot  *
43755Sroot  *	UNIX debugger
53755Sroot  *
63755Sroot  */
73755Sroot 
83755Sroot #include "defs.h"
9*7321Swnj static	char sccsid[] = "@(#)expr.c 4.5 06/27/82";
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--;
823755Sroot 		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 '~':
1033755Sroot 			term(a|1); expv = ~expv; return(1);
1043755Sroot 
1053755Sroot 		    case '#':
1063755Sroot 			term(a|1); expv = !expv; return(1);
1073755Sroot 
1083755Sroot 		    case '(':
1093755Sroot 			expr(2);
1103755Sroot 			IF *lp!=')'
1113755Sroot 			THEN	error(BADSYN);
1123755Sroot 			ELSE	lp++; return(1);
1133755Sroot 			FI
1143755Sroot 
1153755Sroot 		    default:
1163755Sroot 			lp--;
1173755Sroot 			return(item(a));
1183755Sroot 	}
1193755Sroot }
1203755Sroot 
1213755Sroot item(a)
1223755Sroot {	/* name [ . local ] | number | . | ^ | <var | <register | 'x | | */
1233778Sroot 	INT		base, d;
1243755Sroot 	CHAR		savc;
1253755Sroot 	BOOL		hex;
1263755Sroot 	L_INT		frame;
1273755Sroot 	register struct nlist *symp;
1283778Sroot 	int regptr;
1293755Sroot 
1303755Sroot 	hex=FALSE;
1313755Sroot 
1323755Sroot 	readchar();
1333755Sroot 	IF symchar(0)
1343755Sroot 	THEN	readsym();
1353755Sroot 		IF lastc=='.'
1363755Sroot 		THEN	frame= *(ADDR *)(((ADDR)&u)+FP); lastframe=0;
1373755Sroot 			callpc= *(ADDR *)(((ADDR)&u)+PC);
1383755Sroot 			WHILE errflg==0
1393755Sroot 			DO  savpc=callpc;
1403755Sroot 				findsym(callpc,ISYM);
1413755Sroot 			    IF  eqsym(cursym->n_un.n_name,isymbol,'~')
1423755Sroot 			    THEN break;
1433755Sroot 			    FI
1443755Sroot 				callpc=get(frame+16, DSP);
1453755Sroot 			    lastframe=frame;
1463755Sroot 			    frame=get(frame+12,DSP)&EVEN;
1473755Sroot 			    IF frame==0
1483755Sroot 			    THEN error(NOCFN);
1493755Sroot 			    FI
1503755Sroot 			OD
1513755Sroot 			savlastf=lastframe; savframe=frame;
1523755Sroot 			readchar();
1533755Sroot 			IF symchar(0)
1543755Sroot 			THEN	chkloc(expv=frame);
1553755Sroot 			FI
1563755Sroot 		ELIF (symp=lookup(isymbol))==0 THEN error(BADSYM);
1573755Sroot 		ELSE expv = symp->n_value;
1583755Sroot 		FI
1593755Sroot 		lp--;
1603755Sroot 
1613755Sroot 
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--
196*7321Swnj 		    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 
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 
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 
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 
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 
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 
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