1*3755Sroot # 2*3755Sroot /* 3*3755Sroot * 4*3755Sroot * UNIX debugger 5*3755Sroot * 6*3755Sroot */ 7*3755Sroot 8*3755Sroot #include "defs.h" 9*3755Sroot static char sccsid[] = "@(#)expr.c 4.1 05/14/81"; 10*3755Sroot 11*3755Sroot MSG BADSYM; 12*3755Sroot MSG BADVAR; 13*3755Sroot MSG BADKET; 14*3755Sroot MSG BADSYN; 15*3755Sroot MSG NOCFN; 16*3755Sroot MSG NOADR; 17*3755Sroot MSG BADLOC; 18*3755Sroot 19*3755Sroot ADDR lastframe; 20*3755Sroot ADDR savlastf; 21*3755Sroot ADDR savframe; 22*3755Sroot ADDR savpc; 23*3755Sroot ADDR callpc; 24*3755Sroot 25*3755Sroot 26*3755Sroot 27*3755Sroot CHAR *lp; 28*3755Sroot INT radix; 29*3755Sroot STRING errflg; 30*3755Sroot L_INT localval; 31*3755Sroot CHAR isymbol[BSIZE]; 32*3755Sroot 33*3755Sroot CHAR lastc,peekc; 34*3755Sroot 35*3755Sroot L_INT dot; 36*3755Sroot L_INT ditto; 37*3755Sroot INT dotinc; 38*3755Sroot L_INT var[]; 39*3755Sroot L_INT expv; 40*3755Sroot 41*3755Sroot 42*3755Sroot 43*3755Sroot 44*3755Sroot expr(a) 45*3755Sroot { /* term | term dyadic expr | */ 46*3755Sroot INT rc; 47*3755Sroot L_INT lhs; 48*3755Sroot 49*3755Sroot rdc(); lp--; rc=term(a); 50*3755Sroot 51*3755Sroot WHILE rc 52*3755Sroot DO lhs = expv; 53*3755Sroot 54*3755Sroot switch ((int)readchar()) { 55*3755Sroot 56*3755Sroot case '+': 57*3755Sroot term(a|1); expv += lhs; break; 58*3755Sroot 59*3755Sroot case '-': 60*3755Sroot term(a|1); expv = lhs - expv; break; 61*3755Sroot 62*3755Sroot case '#': 63*3755Sroot term(a|1); expv = round(lhs,expv); break; 64*3755Sroot 65*3755Sroot case '*': 66*3755Sroot term(a|1); expv *= lhs; break; 67*3755Sroot 68*3755Sroot case '%': 69*3755Sroot term(a|1); expv = lhs/expv; break; 70*3755Sroot 71*3755Sroot case '&': 72*3755Sroot term(a|1); expv &= lhs; break; 73*3755Sroot 74*3755Sroot case '|': 75*3755Sroot term(a|1); expv |= lhs; break; 76*3755Sroot 77*3755Sroot case ')': 78*3755Sroot IF (a&2)==0 THEN error(BADKET); FI 79*3755Sroot 80*3755Sroot default: 81*3755Sroot lp--; 82*3755Sroot return rc); 83*3755Sroot } 84*3755Sroot OD 85*3755Sroot return(rc); 86*3755Sroot } 87*3755Sroot 88*3755Sroot term(a) 89*3755Sroot { /* item | monadic item | (expr) | */ 90*3755Sroot 91*3755Sroot switch ((int)readchar()) { 92*3755Sroot 93*3755Sroot case '*': 94*3755Sroot term(a|1); expv=chkget(expv,DSP); return(1); 95*3755Sroot 96*3755Sroot case '@': 97*3755Sroot term(a|1); expv=chkget(expv,ISP); return(1); 98*3755Sroot 99*3755Sroot case '-': 100*3755Sroot term(a|1); expv = -expv; return(1); 101*3755Sroot 102*3755Sroot case '~': 103*3755Sroot term(a|1); expv = ~expv; return(1); 104*3755Sroot 105*3755Sroot case '#': 106*3755Sroot term(a|1); expv = !expv; return(1); 107*3755Sroot 108*3755Sroot case '(': 109*3755Sroot expr(2); 110*3755Sroot IF *lp!=')' 111*3755Sroot THEN error(BADSYN); 112*3755Sroot ELSE lp++; return(1); 113*3755Sroot FI 114*3755Sroot 115*3755Sroot default: 116*3755Sroot lp--; 117*3755Sroot return(item(a)); 118*3755Sroot } 119*3755Sroot } 120*3755Sroot 121*3755Sroot item(a) 122*3755Sroot { /* name [ . local ] | number | . | ^ | <var | <register | 'x | | */ 123*3755Sroot INT base, d, regptr; 124*3755Sroot CHAR savc; 125*3755Sroot BOOL hex; 126*3755Sroot L_INT frame; 127*3755Sroot register struct nlist *symp; 128*3755Sroot 129*3755Sroot hex=FALSE; 130*3755Sroot 131*3755Sroot readchar(); 132*3755Sroot IF symchar(0) 133*3755Sroot THEN readsym(); 134*3755Sroot IF lastc=='.' 135*3755Sroot THEN frame= *(ADDR *)(((ADDR)&u)+FP); lastframe=0; 136*3755Sroot callpc= *(ADDR *)(((ADDR)&u)+PC); 137*3755Sroot WHILE errflg==0 138*3755Sroot DO savpc=callpc; 139*3755Sroot findsym(callpc,ISYM); 140*3755Sroot IF eqsym(cursym->n_un.n_name,isymbol,'~') 141*3755Sroot THEN break; 142*3755Sroot FI 143*3755Sroot callpc=get(frame+16, DSP); 144*3755Sroot lastframe=frame; 145*3755Sroot frame=get(frame+12,DSP)&EVEN; 146*3755Sroot IF frame==0 147*3755Sroot THEN error(NOCFN); 148*3755Sroot FI 149*3755Sroot OD 150*3755Sroot savlastf=lastframe; savframe=frame; 151*3755Sroot readchar(); 152*3755Sroot IF symchar(0) 153*3755Sroot THEN chkloc(expv=frame); 154*3755Sroot FI 155*3755Sroot ELIF (symp=lookup(isymbol))==0 THEN error(BADSYM); 156*3755Sroot ELSE expv = symp->n_value; 157*3755Sroot FI 158*3755Sroot lp--; 159*3755Sroot 160*3755Sroot 161*3755Sroot ELIF getnum(readchar) 162*3755Sroot THEN ; 163*3755Sroot ELIF lastc=='.' 164*3755Sroot THEN readchar(); 165*3755Sroot IF symchar(0) 166*3755Sroot THEN lastframe=savlastf; callpc=savpc; 167*3755Sroot chkloc(savframe); 168*3755Sroot ELSE expv=dot; 169*3755Sroot FI 170*3755Sroot lp--; 171*3755Sroot 172*3755Sroot ELIF lastc=='"' 173*3755Sroot THEN expv=ditto; 174*3755Sroot 175*3755Sroot ELIF lastc=='+' 176*3755Sroot THEN expv=inkdot(dotinc); 177*3755Sroot 178*3755Sroot ELIF lastc=='^' 179*3755Sroot THEN expv=inkdot(-dotinc); 180*3755Sroot 181*3755Sroot ELIF lastc=='<' 182*3755Sroot THEN savc=rdc(); 183*3755Sroot IF regptr=getreg(savc) 184*3755Sroot THEN expv= * (ADDR *)(((ADDR)&u)+regptr); 185*3755Sroot ELIF (base=varchk(savc)) != -1 186*3755Sroot THEN expv=var[base]; 187*3755Sroot ELSE error(BADVAR); 188*3755Sroot FI 189*3755Sroot 190*3755Sroot ELIF lastc=='\'' 191*3755Sroot THEN d=4; expv=0; 192*3755Sroot WHILE quotchar() 193*3755Sroot DO IF d-- 194*3755Sroot THEN IF d==1 THEN expv <<=16; FI 195*3755Sroot expv |= ((d&1)?lastc:lastc<<8); 196*3755Sroot ELSE error(BADSYN); 197*3755Sroot FI 198*3755Sroot OD 199*3755Sroot 200*3755Sroot ELIF a 201*3755Sroot THEN error(NOADR); 202*3755Sroot ELSE lp--; return(0); 203*3755Sroot FI 204*3755Sroot return(1); 205*3755Sroot } 206*3755Sroot 207*3755Sroot /* service routines for expression reading */ 208*3755Sroot getnum(rdf) int (*rdf)(); 209*3755Sroot { 210*3755Sroot INT base,d,frpt; 211*3755Sroot BOOL hex; 212*3755Sroot UNION{REAL r; L_INT i;} real; 213*3755Sroot IF isdigit(lastc) ORF (hex=TRUE, lastc=='#' ANDF isxdigit((*rdf)())) 214*3755Sroot THEN expv = 0; 215*3755Sroot base = (hex ? 16 : radix); 216*3755Sroot WHILE (base>10 ? isxdigit(lastc) : isdigit(lastc)) 217*3755Sroot DO expv = (base==16 ? expv<<4 : expv*base); 218*3755Sroot IF (d=convdig(lastc))>=base THEN error(BADSYN); FI 219*3755Sroot expv += d; (*rdf)(); 220*3755Sroot IF expv==0 221*3755Sroot THEN IF (lastc=='x' ORF lastc=='X') 222*3755Sroot THEN hex=TRUE; base=16; (*rdf)(); 223*3755Sroot ELIF (lastc=='t' ORF lastc=='T') 224*3755Sroot THEN hex=FALSE; base=10; (*rdf)(); 225*3755Sroot ELIF (lastc=='o' ORF lastc=='O') 226*3755Sroot THEN hex=FALSE; base=8; (*rdf)(); 227*3755Sroot FI 228*3755Sroot FI 229*3755Sroot OD 230*3755Sroot IF lastc=='.' ANDF (base==10 ORF expv==0) ANDF !hex 231*3755Sroot THEN real.r=expv; frpt=0; base=10; 232*3755Sroot WHILE isdigit((*rdf)()) 233*3755Sroot DO real.r *= base; frpt++; 234*3755Sroot real.r += lastc-'0'; 235*3755Sroot OD 236*3755Sroot WHILE frpt-- 237*3755Sroot DO real.r /= base; OD 238*3755Sroot expv = real.i; 239*3755Sroot FI 240*3755Sroot peekc=lastc; 241*3755Sroot /* lp--; */ 242*3755Sroot return(1); 243*3755Sroot ELSE return(0); 244*3755Sroot FI 245*3755Sroot } 246*3755Sroot 247*3755Sroot readsym() 248*3755Sroot { 249*3755Sroot REG char *p; 250*3755Sroot 251*3755Sroot p = isymbol; 252*3755Sroot REP IF p < &isymbol[sizeof(isymbol)-1] 253*3755Sroot THEN *p++ = lastc; 254*3755Sroot FI 255*3755Sroot readchar(); 256*3755Sroot PER symchar(1) DONE 257*3755Sroot *p++ = 0; 258*3755Sroot } 259*3755Sroot 260*3755Sroot convdig(c) 261*3755Sroot CHAR c; 262*3755Sroot { 263*3755Sroot IF isdigit(c) 264*3755Sroot THEN return(c-'0'); 265*3755Sroot ELIF isxdigit(c) 266*3755Sroot THEN return(c-'a'+10); 267*3755Sroot ELSE return(17); 268*3755Sroot FI 269*3755Sroot } 270*3755Sroot 271*3755Sroot symchar(dig) 272*3755Sroot { 273*3755Sroot IF lastc=='\\' THEN readchar(); return(TRUE); FI 274*3755Sroot return( isalpha(lastc) ORF lastc=='_' ORF dig ANDF isdigit(lastc) ); 275*3755Sroot } 276*3755Sroot 277*3755Sroot varchk(name) 278*3755Sroot { 279*3755Sroot IF isdigit(name) THEN return(name-'0'); FI 280*3755Sroot IF isalpha(name) THEN return((name&037)-1+10); FI 281*3755Sroot return(-1); 282*3755Sroot } 283*3755Sroot 284*3755Sroot chkloc(frame) 285*3755Sroot L_INT frame; 286*3755Sroot { 287*3755Sroot readsym(); 288*3755Sroot REP IF localsym(frame)==0 THEN error(BADLOC); FI 289*3755Sroot expv=localval; 290*3755Sroot PER !eqsym(cursym->n_un.n_name,isymbol,'~') DONE 291*3755Sroot } 292*3755Sroot 293*3755Sroot eqsym(s1, s2, c) 294*3755Sroot register char *s1, *s2; 295*3755Sroot { 296*3755Sroot 297*3755Sroot if (!strcmp(s1,s2)) 298*3755Sroot return (1); 299*3755Sroot if (*s1 == c && !strcmp(s1+1, s2)) 300*3755Sroot return (1); 301*3755Sroot return (0); 302*3755Sroot } 303