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