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