1 #ifndef lint 2 static char sccsid[] = "@(#)expr.c 4.8 08/11/83"; 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 L_INT 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 INT rc; 48 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 INT base, d; 125 CHAR savc; 126 BOOL hex; 127 L_INT frame; 128 register struct nlist *symp; 129 int regptr; 130 131 hex=FALSE; 132 133 readchar(); 134 IF symchar(0) 135 THEN readsym(); 136 IF lastc=='.' 137 THEN frame= *(ADDR *)(((ADDR)&u)+FP); lastframe=0; 138 callpc= *(ADDR *)(((ADDR)&u)+PC); 139 WHILE errflg==0 140 DO savpc=callpc; 141 findsym(callpc,ISYM); 142 IF eqsym(cursym->n_un.n_name,isymbol,'~') 143 THEN break; 144 FI 145 callpc=get(frame+16, DSP); 146 lastframe=frame; 147 frame=get(frame+12,DSP)&EVEN; 148 IF frame==0 149 THEN error(NOCFN); 150 FI 151 OD 152 savlastf=lastframe; savframe=frame; 153 readchar(); 154 IF symchar(0) 155 THEN chkloc(expv=frame); 156 FI 157 ELIF (symp=lookup(isymbol))==0 THEN error(BADSYM); 158 ELSE expv = symp->n_value; 159 FI 160 lp--; 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 expv = (expv << 8) | lastc; 197 ELSE error(BADSYN); 198 FI 199 OD 200 201 ELIF a 202 THEN error(NOADR); 203 ELSE lp--; return(0); 204 FI 205 return(1); 206 } 207 208 /* service routines for expression reading */ 209 getnum(rdf) int (*rdf)(); 210 { 211 INT base,d,frpt; 212 BOOL hex; 213 UNION{REAL r; L_INT i;} real; 214 IF isdigit(lastc) ORF (hex=TRUE, lastc=='#' ANDF isxdigit((*rdf)())) 215 THEN expv = 0; 216 base = (hex ? 16 : radix); 217 WHILE (base>10 ? isxdigit(lastc) : isdigit(lastc)) 218 DO expv = (base==16 ? expv<<4 : expv*base); 219 IF (d=convdig(lastc))>=base THEN error(BADSYN); FI 220 expv += d; (*rdf)(); 221 IF expv==0 222 THEN IF (lastc=='x' ORF lastc=='X') 223 THEN hex=TRUE; base=16; (*rdf)(); 224 ELIF (lastc=='t' ORF lastc=='T') 225 THEN hex=FALSE; base=10; (*rdf)(); 226 ELIF (lastc=='o' ORF lastc=='O') 227 THEN hex=FALSE; base=8; (*rdf)(); 228 FI 229 FI 230 OD 231 IF lastc=='.' ANDF (base==10 ORF expv==0) ANDF !hex 232 THEN real.r=expv; frpt=0; base=10; 233 WHILE isdigit((*rdf)()) 234 DO real.r *= base; frpt++; 235 real.r += lastc-'0'; 236 OD 237 WHILE frpt-- 238 DO real.r /= base; OD 239 expv = real.i; 240 FI 241 peekc=lastc; 242 /* lp--; */ 243 return(1); 244 ELSE return(0); 245 FI 246 } 247 248 readsym() 249 { 250 REG char *p; 251 252 p = isymbol; 253 REP IF p < &isymbol[sizeof(isymbol)-1] 254 THEN *p++ = lastc; 255 FI 256 readchar(); 257 PER symchar(1) DONE 258 *p++ = 0; 259 } 260 261 convdig(c) 262 CHAR c; 263 { 264 IF isdigit(c) 265 THEN return(c-'0'); 266 ELIF isxdigit(c) 267 THEN return(c-'a'+10); 268 ELSE return(17); 269 FI 270 } 271 272 symchar(dig) 273 { 274 IF lastc=='\\' THEN readchar(); return(TRUE); FI 275 return( isalpha(lastc) ORF lastc=='_' ORF dig ANDF isdigit(lastc) ); 276 } 277 278 varchk(name) 279 { 280 IF isdigit(name) THEN return(name-'0'); FI 281 IF isalpha(name) THEN return((name&037)-1+10); FI 282 return(-1); 283 } 284 285 chkloc(frame) 286 L_INT frame; 287 { 288 readsym(); 289 REP IF localsym(frame)==0 THEN error(BADLOC); FI 290 expv=localval; 291 PER !eqsym(cursym->n_un.n_name,isymbol,'~') DONE 292 } 293 294 eqsym(s1, s2, c) 295 register char *s1, *s2; 296 { 297 298 if (!strcmp(s1,s2)) 299 return (1); 300 if (*s1 == c && !strcmp(s1+1, s2)) 301 return (1); 302 return (0); 303 } 304