13755Sroot # 23755Sroot /* 33755Sroot * 43755Sroot * UNIX debugger 53755Sroot * 63755Sroot */ 73755Sroot 83755Sroot #include "defs.h" 9*3778Sroot static char sccsid[] = "@(#)expr.c 4.3 05/15/81"; 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; 313755Sroot CHAR isymbol[BSIZE]; 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 | | */ 123*3778Sroot INT base, d; 1243755Sroot CHAR savc; 1253755Sroot BOOL hex; 1263755Sroot L_INT frame; 1273755Sroot register struct nlist *symp; 128*3778Sroot 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-- 1963755Sroot THEN IF d==1 THEN expv <<=16; FI 1973755Sroot expv |= ((d&1)?lastc:lastc<<8); 1983755Sroot ELSE error(BADSYN); 1993755Sroot FI 2003755Sroot OD 2013755Sroot 2023755Sroot ELIF a 2033755Sroot THEN error(NOADR); 2043755Sroot ELSE lp--; return(0); 2053755Sroot FI 2063755Sroot return(1); 2073755Sroot } 2083755Sroot 2093755Sroot /* service routines for expression reading */ 2103755Sroot getnum(rdf) int (*rdf)(); 2113755Sroot { 2123755Sroot INT base,d,frpt; 2133755Sroot BOOL hex; 2143755Sroot UNION{REAL r; L_INT i;} real; 2153755Sroot IF isdigit(lastc) ORF (hex=TRUE, lastc=='#' ANDF isxdigit((*rdf)())) 2163755Sroot THEN expv = 0; 2173755Sroot base = (hex ? 16 : radix); 2183755Sroot WHILE (base>10 ? isxdigit(lastc) : isdigit(lastc)) 2193755Sroot DO expv = (base==16 ? expv<<4 : expv*base); 2203755Sroot IF (d=convdig(lastc))>=base THEN error(BADSYN); FI 2213755Sroot expv += d; (*rdf)(); 2223755Sroot IF expv==0 2233755Sroot THEN IF (lastc=='x' ORF lastc=='X') 2243755Sroot THEN hex=TRUE; base=16; (*rdf)(); 2253755Sroot ELIF (lastc=='t' ORF lastc=='T') 2263755Sroot THEN hex=FALSE; base=10; (*rdf)(); 2273755Sroot ELIF (lastc=='o' ORF lastc=='O') 2283755Sroot THEN hex=FALSE; base=8; (*rdf)(); 2293755Sroot FI 2303755Sroot FI 2313755Sroot OD 2323755Sroot IF lastc=='.' ANDF (base==10 ORF expv==0) ANDF !hex 2333755Sroot THEN real.r=expv; frpt=0; base=10; 2343755Sroot WHILE isdigit((*rdf)()) 2353755Sroot DO real.r *= base; frpt++; 2363755Sroot real.r += lastc-'0'; 2373755Sroot OD 2383755Sroot WHILE frpt-- 2393755Sroot DO real.r /= base; OD 2403755Sroot expv = real.i; 2413755Sroot FI 2423755Sroot peekc=lastc; 2433755Sroot /* lp--; */ 2443755Sroot return(1); 2453755Sroot ELSE return(0); 2463755Sroot FI 2473755Sroot } 2483755Sroot 2493755Sroot readsym() 2503755Sroot { 2513755Sroot REG char *p; 2523755Sroot 2533755Sroot p = isymbol; 2543755Sroot REP IF p < &isymbol[sizeof(isymbol)-1] 2553755Sroot THEN *p++ = lastc; 2563755Sroot FI 2573755Sroot readchar(); 2583755Sroot PER symchar(1) DONE 2593755Sroot *p++ = 0; 2603755Sroot } 2613755Sroot 2623755Sroot convdig(c) 2633755Sroot CHAR c; 2643755Sroot { 2653755Sroot IF isdigit(c) 2663755Sroot THEN return(c-'0'); 2673755Sroot ELIF isxdigit(c) 2683755Sroot THEN return(c-'a'+10); 2693755Sroot ELSE return(17); 2703755Sroot FI 2713755Sroot } 2723755Sroot 2733755Sroot symchar(dig) 2743755Sroot { 2753755Sroot IF lastc=='\\' THEN readchar(); return(TRUE); FI 2763755Sroot return( isalpha(lastc) ORF lastc=='_' ORF dig ANDF isdigit(lastc) ); 2773755Sroot } 2783755Sroot 2793755Sroot varchk(name) 2803755Sroot { 2813755Sroot IF isdigit(name) THEN return(name-'0'); FI 2823755Sroot IF isalpha(name) THEN return((name&037)-1+10); FI 2833755Sroot return(-1); 2843755Sroot } 2853755Sroot 2863755Sroot chkloc(frame) 2873755Sroot L_INT frame; 2883755Sroot { 2893755Sroot readsym(); 2903755Sroot REP IF localsym(frame)==0 THEN error(BADLOC); FI 2913755Sroot expv=localval; 2923755Sroot PER !eqsym(cursym->n_un.n_name,isymbol,'~') DONE 2933755Sroot } 2943755Sroot 2953755Sroot eqsym(s1, s2, c) 2963755Sroot register char *s1, *s2; 2973755Sroot { 2983755Sroot 2993755Sroot if (!strcmp(s1,s2)) 3003755Sroot return (1); 3013755Sroot if (*s1 == c && !strcmp(s1+1, s2)) 3023755Sroot return (1); 3033755Sroot return (0); 3043755Sroot } 305