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