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