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