13755Sroot # 23755Sroot /* 33755Sroot * 43755Sroot * UNIX debugger 53755Sroot * 63755Sroot */ 73755Sroot 83755Sroot #include "defs.h" 9*12209Ssam static char sccsid[] = "@(#)expr.c 4.6 05/03/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--; 82*12209Ssam 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 1043755Sroot ELIF getnum(readchar) 1053755Sroot THEN ; 1063755Sroot ELIF lastc=='.' 1073755Sroot THEN readchar(); 1083755Sroot IF symchar(0) 1093755Sroot THEN lastframe=savlastf; callpc=savpc; 1103755Sroot chkloc(savframe); 1113755Sroot ELSE expv=dot; 1123755Sroot FI 1133755Sroot lp--; 1143755Sroot 1153755Sroot ELIF lastc=='"' 1163755Sroot THEN expv=ditto; 1173755Sroot 1183755Sroot ELIF lastc=='+' 1193755Sroot THEN expv=inkdot(dotinc); 1203755Sroot 1213755Sroot ELIF lastc=='^' 1223755Sroot THEN expv=inkdot(-dotinc); 1233755Sroot 1243755Sroot ELIF lastc=='<' 1253755Sroot THEN savc=rdc(); 1263755Sroot IF regptr=getreg(savc) 1273777Sroot THEN IF kcore THEN expv = *(int *)regptr; 1283777Sroot ELSE expv= * (ADDR *)(((ADDR)&u)+regptr); FI 1293755Sroot ELIF (base=varchk(savc)) != -1 1303755Sroot THEN expv=var[base]; 1313755Sroot ELSE error(BADVAR); 1323755Sroot FI 1333755Sroot 1343755Sroot ELIF lastc=='\'' 1353755Sroot THEN d=4; expv=0; 1363755Sroot WHILE quotchar() 1373755Sroot DO IF d-- 1387321Swnj THEN expv = (expv << 8) | lastc; 1393755Sroot ELSE error(BADSYN); 1403755Sroot FI 1413755Sroot OD 1423755Sroot 1433755Sroot ELIF a 1443755Sroot THEN error(NOADR); 1453755Sroot ELSE lp--; return(0); 1463755Sroot FI 1473755Sroot return(1); 1483755Sroot } 1493755Sroot 1503755Sroot /* service routines for expression reading */ 1513755Sroot getnum(rdf) int (*rdf)(); 1523755Sroot { 1533755Sroot INT base,d,frpt; 1543755Sroot BOOL hex; 1553755Sroot UNION{REAL r; L_INT i;} real; 1563755Sroot IF isdigit(lastc) ORF (hex=TRUE, lastc=='#' ANDF isxdigit((*rdf)())) 1573755Sroot THEN expv = 0; 1583755Sroot base = (hex ? 16 : radix); 1593755Sroot WHILE (base>10 ? isxdigit(lastc) : isdigit(lastc)) 1603755Sroot DO expv = (base==16 ? expv<<4 : expv*base); 1613755Sroot IF (d=convdig(lastc))>=base THEN error(BADSYN); FI 1623755Sroot expv += d; (*rdf)(); 1633755Sroot IF expv==0 1643755Sroot THEN IF (lastc=='x' ORF lastc=='X') 1653755Sroot THEN hex=TRUE; base=16; (*rdf)(); 1663755Sroot ELIF (lastc=='t' ORF lastc=='T') 1673755Sroot THEN hex=FALSE; base=10; (*rdf)(); 1683755Sroot ELIF (lastc=='o' ORF lastc=='O') 1693755Sroot THEN hex=FALSE; base=8; (*rdf)(); 1703755Sroot FI 1713755Sroot FI 1723755Sroot OD 1733755Sroot IF lastc=='.' ANDF (base==10 ORF expv==0) ANDF !hex 1743755Sroot THEN real.r=expv; frpt=0; base=10; 1753755Sroot WHILE isdigit((*rdf)()) 1763755Sroot DO real.r *= base; frpt++; 1773755Sroot real.r += lastc-'0'; 1783755Sroot OD 1793755Sroot WHILE frpt-- 1803755Sroot DO real.r /= base; OD 1813755Sroot expv = real.i; 1823755Sroot FI 1833755Sroot peekc=lastc; 1843755Sroot /* lp--; */ 1853755Sroot return(1); 1863755Sroot ELSE return(0); 1873755Sroot FI 1883755Sroot } 1893755Sroot 1903755Sroot readsym() 1913755Sroot { 1923755Sroot REG char *p; 1933755Sroot 1943755Sroot p = isymbol; 1953755Sroot REP IF p < &isymbol[sizeof(isymbol)-1] 1963755Sroot THEN *p++ = lastc; 1973755Sroot FI 1983755Sroot readchar(); 1993755Sroot PER symchar(1) DONE 2003755Sroot *p++ = 0; 2013755Sroot } 2023755Sroot 2033755Sroot convdig(c) 2043755Sroot CHAR c; 2053755Sroot { 2063755Sroot IF isdigit(c) 2073755Sroot THEN return(c-'0'); 2083755Sroot ELIF isxdigit(c) 2093755Sroot THEN return(c-'a'+10); 2103755Sroot ELSE return(17); 2113755Sroot FI 2123755Sroot } 2133755Sroot 2143755Sroot symchar(dig) 2153755Sroot { 2163755Sroot IF lastc=='\\' THEN readchar(); return(TRUE); FI 2173755Sroot return( isalpha(lastc) ORF lastc=='_' ORF dig ANDF isdigit(lastc) ); 2183755Sroot } 2193755Sroot 2203755Sroot varchk(name) 2213755Sroot { 2223755Sroot IF isdigit(name) THEN return(name-'0'); FI 2233755Sroot IF isalpha(name) THEN return((name&037)-1+10); FI 2243755Sroot return(-1); 2253755Sroot } 2263755Sroot 2273755Sroot chkloc(frame) 2283755Sroot L_INT frame; 2293755Sroot { 2303755Sroot readsym(); 2313755Sroot REP IF localsym(frame)==0 THEN error(BADLOC); FI 2323755Sroot expv=localval; 2333755Sroot PER !eqsym(cursym->n_un.n_name,isymbol,'~') DONE 2343755Sroot } 2353755Sroot 2363755Sroot eqsym(s1, s2, c) 2373755Sroot register char *s1, *s2; 2383755Sroot { 2393755Sroot 2403755Sroot if (!strcmp(s1,s2)) 2413755Sroot return (1); 2423755Sroot if (*s1 == c && !strcmp(s1+1, s2)) 2433755Sroot return (1); 2443755Sroot return (0); 2453755Sroot } 246