1 /* 2 * 3 * debugger 4 * 5 */ 6 7 #include "defs.h" 8 #include "fns.h" 9 10 static long round(long, long); 11 12 WORD var[NVARS]; 13 14 extern char lastc, peekc; 15 16 extern ADDR ditto; 17 extern int ditsp; 18 WORD expv; 19 int expsp; 20 21 WORD 22 defval(WORD w) 23 { 24 if (expr(0)) 25 return (expv); 26 else 27 return (w); 28 } 29 30 expr(int a) 31 { /* term | term dyadic expr | */ 32 int rc; 33 WORD lhs; 34 35 rdc(); 36 reread(); 37 expsp = SEGNONE; 38 rc=term(a); 39 while (rc) { 40 lhs = expv; 41 switch ((int)readchar()) { 42 43 case '+': 44 term(a|1); 45 expv += lhs; 46 break; 47 48 case '-': 49 term(a|1); 50 expv = lhs - expv; 51 break; 52 53 case '#': 54 term(a|1); 55 expv = round(lhs,expv); 56 break; 57 58 case '*': 59 term(a|1); 60 expv *= lhs; 61 break; 62 63 case '%': 64 term(a|1); 65 if(expv != 0) 66 expv = lhs/expv; 67 else{ 68 if(lhs) 69 expv = 1; 70 else 71 expv = 0; 72 } 73 break; 74 75 case '&': 76 term(a|1); 77 expv &= lhs; 78 break; 79 80 case '|': 81 term(a|1); 82 expv |= lhs; 83 break; 84 85 case ')': 86 if ((a&2)==0) 87 error("unexpected `)'"); 88 89 default: 90 reread(); 91 return(rc); 92 } 93 } 94 return(rc); 95 } 96 97 term(int a) 98 { /* item | monadic item | (expr) | */ 99 100 switch ((int)readchar()) { 101 102 case '*': 103 term(a|1); 104 get4(cormap, (ADDR)expv, SEGDATA, &expv); 105 expsp = SEGNONE; 106 chkerr(); 107 return(1); 108 109 case '@': 110 term(a|1); 111 get4(symmap, (ADDR)expv, SEGTEXT, &expv); 112 expsp = SEGNONE; 113 return(1); 114 115 case '-': 116 term(a|1); 117 expv = -expv; 118 return(1); 119 120 case '~': 121 term(a|1); 122 expv = ~expv; 123 return(1); 124 125 case '(': 126 expr(2); 127 if (readchar()!=')') 128 error("syntax error: `)' expected"); 129 return(1); 130 131 case '%': 132 term(a|1); 133 expsp = SEGREGS; 134 return(1); 135 136 default: 137 reread(); 138 return(item(a)); 139 } 140 } 141 142 item(int a) 143 { /* name [ . local ] | number | . | ^ | <var | <register | 'x | | */ 144 int base; 145 char savc; 146 Symbol s; 147 char gsym[MAXSYM], lsym[MAXSYM]; 148 149 readchar(); 150 if (isfileref()) { 151 readfname(gsym); 152 rdc(); /* skip white space */ 153 if (lastc == ':') { /* it better be */ 154 rdc(); /* skip white space */ 155 if (!getnum(readchar)) 156 error("bad number"); 157 if (expv == 0) 158 expv = 1; /* file begins at line 1 */ 159 expv = file2pc(gsym, expv); 160 if (expv == -1) 161 error(symerror); 162 expsp = SEGNONE; 163 return 1; 164 } 165 error("bad file location"); 166 } else if (symchar(0)) { 167 readsym(gsym); 168 if (lastc=='.') { 169 readchar(); /* ugh */ 170 if (!symchar(0)) 171 localaddr(gsym, 0); 172 else { 173 readsym(lsym); 174 localaddr(gsym, lsym); 175 } 176 } 177 else { 178 if (lookup(0, gsym, &s) == 0) 179 error("symbol not found"); 180 expv = s.value; 181 } 182 reread(); 183 } else if (getnum(readchar)) { 184 ; 185 } else if (lastc=='.') { 186 readchar(); 187 if (!symchar(0)) { 188 expv = dot; 189 expsp = dotsp; 190 } else { 191 readsym(lsym); 192 localaddr(0, lsym); 193 } 194 reread(); 195 } else if (lastc=='"') { 196 expv=ditto; 197 expsp = ditsp; 198 } else if (lastc=='+') { 199 expv=inkdot(dotinc); 200 expsp = ditsp; 201 } else if (lastc=='^') { 202 expv=inkdot(-dotinc); 203 expsp = ditsp; 204 } else if (lastc=='<') { 205 savc=rdc(); 206 base = getreg(savc); 207 if (base != BADREG) 208 expv = rget(base); 209 else if ((base = varchk(savc)) != -1) 210 expv = var[base]; 211 else 212 error("bad variable"); 213 } 214 else if (lastc=='\'') 215 expv = ascval(); 216 else if (a) 217 error("address expected"); 218 else { 219 reread(); 220 return(0); 221 } 222 return(1); 223 } 224 225 #define MAXBASE 16 226 227 /* service routines for expression reading */ 228 getnum(int (*rdf)(void)) 229 { 230 char *cp; 231 int base, d; 232 BOOL fpnum; 233 char num[MAXLIN]; 234 235 base = 0; 236 fpnum = FALSE; 237 if (lastc == '#') { 238 base = 16; 239 (*rdf)(); 240 } 241 if (convdig(lastc) >= MAXBASE) 242 return (0); 243 if (lastc == '0') 244 switch ((*rdf)()) { 245 case 'x': 246 case 'X': 247 base = 16; 248 (*rdf)(); 249 break; 250 251 case 't': 252 case 'T': 253 base = 10; 254 (*rdf)(); 255 break; 256 257 case 'o': 258 case 'O': 259 base = 8; 260 (*rdf)(); 261 break; 262 default: 263 if (base == 0) 264 base = 8; 265 break; 266 } 267 if (base == 0) 268 base = 10; 269 expv = 0; 270 for (cp = num, *cp = lastc; ;(*rdf)()) { 271 if ((d = convdig(lastc)) < base) { 272 expv *= base; 273 expv += d; 274 *cp++ = lastc; 275 } 276 else if (lastc == '.') { 277 fpnum = TRUE; 278 *cp++ = lastc; 279 } else { 280 reread(); 281 break; 282 } 283 } 284 if (fpnum) 285 expv = fpin(num); 286 return (1); 287 } 288 289 void 290 readsym(char *isymbol) 291 { 292 char *p; 293 294 p = isymbol; 295 do { 296 if (p < &isymbol[MAXSYM-1]) 297 *p++ = lastc; 298 readchar(); 299 } while (symchar(1)); 300 *p = 0; 301 } 302 303 void 304 readfname(char *filename) 305 { 306 char *p; 307 char c; 308 309 /* snarf chars until un-escaped char in terminal char set */ 310 p = filename; 311 do { 312 if ((c = lastc) != '\\' && p < &filename[MAXSYM-1]) 313 *p++ = c; 314 readchar(); 315 } while (c == '\\' || strchr(CMD_VERBS, lastc) == 0); 316 *p = 0; 317 reread(); 318 } 319 320 convdig(int c) 321 { 322 if (isdigit(c)) 323 return(c-'0'); 324 else if (!isxdigit(c)) 325 return(MAXBASE); 326 else if (isupper(c)) 327 return(c-'A'+10); 328 else 329 return(c-'a'+10); 330 } 331 332 symchar(int dig) 333 { 334 if (lastc=='\\') { 335 readchar(); 336 return(TRUE); 337 } 338 return(isalpha(lastc) || lastc=='_' || dig && isdigit(lastc)); 339 } 340 341 varchk(int name) 342 { 343 if (isdigit(name)) 344 return(name-'0'); 345 if (isalpha(name)) 346 return((name&037)-1+10); 347 return(-1); 348 } 349 350 static long 351 round(long a, long b) 352 { 353 long w; 354 355 w = (a/b)*b; 356 if (a!=w) 357 w += b; 358 return(w); 359 } 360