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