13e12c5d1SDavid du Colombier /* 23e12c5d1SDavid du Colombier * 33e12c5d1SDavid du Colombier * debugger 43e12c5d1SDavid du Colombier * 53e12c5d1SDavid du Colombier */ 63e12c5d1SDavid du Colombier 73e12c5d1SDavid du Colombier #include "defs.h" 83e12c5d1SDavid du Colombier #include "fns.h" 93e12c5d1SDavid du Colombier 103e12c5d1SDavid du Colombier static long round(long, long); 113e12c5d1SDavid du Colombier 123e12c5d1SDavid du Colombier extern ADDR ditto; 137dd7cddfSDavid du Colombier vlong expv; 14219b2ee8SDavid du Colombier 15219b2ee8SDavid du Colombier static WORD 16219b2ee8SDavid du Colombier ascval(void) 17219b2ee8SDavid du Colombier { 18219b2ee8SDavid du Colombier Rune r; 19219b2ee8SDavid du Colombier 20219b2ee8SDavid du Colombier if (readchar() == 0) 21219b2ee8SDavid du Colombier return (0); 22*9a747e4fSDavid du Colombier r = lastc; 23219b2ee8SDavid du Colombier while(quotchar()) /*discard chars to ending quote */ 24219b2ee8SDavid du Colombier ; 25219b2ee8SDavid du Colombier return((WORD) r); 26219b2ee8SDavid du Colombier } 27219b2ee8SDavid du Colombier 28219b2ee8SDavid du Colombier /* 29219b2ee8SDavid du Colombier * read a floating point number 30219b2ee8SDavid du Colombier * the result must fit in a WORD 31219b2ee8SDavid du Colombier */ 32219b2ee8SDavid du Colombier 33219b2ee8SDavid du Colombier static WORD 34219b2ee8SDavid du Colombier fpin(char *buf) 35219b2ee8SDavid du Colombier { 36219b2ee8SDavid du Colombier union { 37219b2ee8SDavid du Colombier WORD w; 38219b2ee8SDavid du Colombier float f; 39219b2ee8SDavid du Colombier } x; 40219b2ee8SDavid du Colombier 41219b2ee8SDavid du Colombier x.f = atof(buf); 42219b2ee8SDavid du Colombier return (x.w); 43219b2ee8SDavid du Colombier } 443e12c5d1SDavid du Colombier 453e12c5d1SDavid du Colombier WORD 463e12c5d1SDavid du Colombier defval(WORD w) 473e12c5d1SDavid du Colombier { 483e12c5d1SDavid du Colombier if (expr(0)) 493e12c5d1SDavid du Colombier return (expv); 503e12c5d1SDavid du Colombier else 513e12c5d1SDavid du Colombier return (w); 523e12c5d1SDavid du Colombier } 533e12c5d1SDavid du Colombier 543e12c5d1SDavid du Colombier expr(int a) 553e12c5d1SDavid du Colombier { /* term | term dyadic expr | */ 563e12c5d1SDavid du Colombier int rc; 573e12c5d1SDavid du Colombier WORD lhs; 583e12c5d1SDavid du Colombier 593e12c5d1SDavid du Colombier rdc(); 603e12c5d1SDavid du Colombier reread(); 613e12c5d1SDavid du Colombier rc=term(a); 623e12c5d1SDavid du Colombier while (rc) { 633e12c5d1SDavid du Colombier lhs = expv; 643e12c5d1SDavid du Colombier switch ((int)readchar()) { 653e12c5d1SDavid du Colombier 663e12c5d1SDavid du Colombier case '+': 673e12c5d1SDavid du Colombier term(a|1); 683e12c5d1SDavid du Colombier expv += lhs; 693e12c5d1SDavid du Colombier break; 703e12c5d1SDavid du Colombier 713e12c5d1SDavid du Colombier case '-': 723e12c5d1SDavid du Colombier term(a|1); 733e12c5d1SDavid du Colombier expv = lhs - expv; 743e12c5d1SDavid du Colombier break; 753e12c5d1SDavid du Colombier 763e12c5d1SDavid du Colombier case '#': 773e12c5d1SDavid du Colombier term(a|1); 783e12c5d1SDavid du Colombier expv = round(lhs,expv); 793e12c5d1SDavid du Colombier break; 803e12c5d1SDavid du Colombier 813e12c5d1SDavid du Colombier case '*': 823e12c5d1SDavid du Colombier term(a|1); 833e12c5d1SDavid du Colombier expv *= lhs; 843e12c5d1SDavid du Colombier break; 853e12c5d1SDavid du Colombier 863e12c5d1SDavid du Colombier case '%': 873e12c5d1SDavid du Colombier term(a|1); 883e12c5d1SDavid du Colombier if(expv != 0) 893e12c5d1SDavid du Colombier expv = lhs/expv; 903e12c5d1SDavid du Colombier else{ 913e12c5d1SDavid du Colombier if(lhs) 923e12c5d1SDavid du Colombier expv = 1; 933e12c5d1SDavid du Colombier else 943e12c5d1SDavid du Colombier expv = 0; 953e12c5d1SDavid du Colombier } 963e12c5d1SDavid du Colombier break; 973e12c5d1SDavid du Colombier 983e12c5d1SDavid du Colombier case '&': 993e12c5d1SDavid du Colombier term(a|1); 1003e12c5d1SDavid du Colombier expv &= lhs; 1013e12c5d1SDavid du Colombier break; 1023e12c5d1SDavid du Colombier 1033e12c5d1SDavid du Colombier case '|': 1043e12c5d1SDavid du Colombier term(a|1); 1053e12c5d1SDavid du Colombier expv |= lhs; 1063e12c5d1SDavid du Colombier break; 1073e12c5d1SDavid du Colombier 1083e12c5d1SDavid du Colombier case ')': 1093e12c5d1SDavid du Colombier if ((a&2)==0) 1103e12c5d1SDavid du Colombier error("unexpected `)'"); 1113e12c5d1SDavid du Colombier 1123e12c5d1SDavid du Colombier default: 1133e12c5d1SDavid du Colombier reread(); 1143e12c5d1SDavid du Colombier return(rc); 1153e12c5d1SDavid du Colombier } 1163e12c5d1SDavid du Colombier } 1173e12c5d1SDavid du Colombier return(rc); 1183e12c5d1SDavid du Colombier } 1193e12c5d1SDavid du Colombier 1203e12c5d1SDavid du Colombier term(int a) 1213e12c5d1SDavid du Colombier { /* item | monadic item | (expr) | */ 1227dd7cddfSDavid du Colombier WORD e; 1233e12c5d1SDavid du Colombier 1243e12c5d1SDavid du Colombier switch ((int)readchar()) { 1253e12c5d1SDavid du Colombier 1263e12c5d1SDavid du Colombier case '*': 1273e12c5d1SDavid du Colombier term(a|1); 1287dd7cddfSDavid du Colombier if (get4(cormap, (ADDR)expv, &e) < 0) 129219b2ee8SDavid du Colombier error("%r"); 1307dd7cddfSDavid du Colombier expv = e; 1313e12c5d1SDavid du Colombier return(1); 1323e12c5d1SDavid du Colombier 1333e12c5d1SDavid du Colombier case '@': 1343e12c5d1SDavid du Colombier term(a|1); 1357dd7cddfSDavid du Colombier if (get4(symmap, (ADDR)expv, &e) < 0) 136219b2ee8SDavid du Colombier error("%r"); 1377dd7cddfSDavid du Colombier expv = e; 1383e12c5d1SDavid du Colombier return(1); 1393e12c5d1SDavid du Colombier 1403e12c5d1SDavid du Colombier case '-': 1413e12c5d1SDavid du Colombier term(a|1); 1423e12c5d1SDavid du Colombier expv = -expv; 1433e12c5d1SDavid du Colombier return(1); 1443e12c5d1SDavid du Colombier 1453e12c5d1SDavid du Colombier case '~': 1463e12c5d1SDavid du Colombier term(a|1); 1473e12c5d1SDavid du Colombier expv = ~expv; 1483e12c5d1SDavid du Colombier return(1); 1493e12c5d1SDavid du Colombier 1503e12c5d1SDavid du Colombier case '(': 1513e12c5d1SDavid du Colombier expr(2); 1523e12c5d1SDavid du Colombier if (readchar()!=')') 1533e12c5d1SDavid du Colombier error("syntax error: `)' expected"); 1543e12c5d1SDavid du Colombier return(1); 1553e12c5d1SDavid du Colombier 1563e12c5d1SDavid du Colombier default: 1573e12c5d1SDavid du Colombier reread(); 1583e12c5d1SDavid du Colombier return(item(a)); 1593e12c5d1SDavid du Colombier } 1603e12c5d1SDavid du Colombier } 1613e12c5d1SDavid du Colombier 1623e12c5d1SDavid du Colombier item(int a) 163219b2ee8SDavid du Colombier { /* name [ . local ] | number | . | ^ | <register | 'x | | */ 164219b2ee8SDavid du Colombier char *base; 1653e12c5d1SDavid du Colombier char savc; 1667dd7cddfSDavid du Colombier WORD e; 1673e12c5d1SDavid du Colombier Symbol s; 1683e12c5d1SDavid du Colombier char gsym[MAXSYM], lsym[MAXSYM]; 1693e12c5d1SDavid du Colombier 1703e12c5d1SDavid du Colombier readchar(); 1713e12c5d1SDavid du Colombier if (isfileref()) { 1723e12c5d1SDavid du Colombier readfname(gsym); 1733e12c5d1SDavid du Colombier rdc(); /* skip white space */ 1743e12c5d1SDavid du Colombier if (lastc == ':') { /* it better be */ 1753e12c5d1SDavid du Colombier rdc(); /* skip white space */ 1763e12c5d1SDavid du Colombier if (!getnum(readchar)) 1773e12c5d1SDavid du Colombier error("bad number"); 1783e12c5d1SDavid du Colombier if (expv == 0) 1793e12c5d1SDavid du Colombier expv = 1; /* file begins at line 1 */ 1803e12c5d1SDavid du Colombier expv = file2pc(gsym, expv); 1813e12c5d1SDavid du Colombier if (expv == -1) 182219b2ee8SDavid du Colombier error("%r"); 1833e12c5d1SDavid du Colombier return 1; 1843e12c5d1SDavid du Colombier } 1853e12c5d1SDavid du Colombier error("bad file location"); 1863e12c5d1SDavid du Colombier } else if (symchar(0)) { 1873e12c5d1SDavid du Colombier readsym(gsym); 1883e12c5d1SDavid du Colombier if (lastc=='.') { 1893e12c5d1SDavid du Colombier readchar(); /* ugh */ 190219b2ee8SDavid du Colombier if (lastc == '.') { 191219b2ee8SDavid du Colombier lsym[0] = '.'; 192219b2ee8SDavid du Colombier readchar(); 193219b2ee8SDavid du Colombier readsym(lsym+1); 194219b2ee8SDavid du Colombier } else if (symchar(0)) { 1953e12c5d1SDavid du Colombier readsym(lsym); 196219b2ee8SDavid du Colombier } else 197219b2ee8SDavid du Colombier lsym[0] = 0; 1987dd7cddfSDavid du Colombier if (localaddr(cormap, gsym, lsym, &e, rget) < 0) 199219b2ee8SDavid du Colombier error("%r"); 2007dd7cddfSDavid du Colombier expv = e; 2013e12c5d1SDavid du Colombier } 2023e12c5d1SDavid du Colombier else { 2033e12c5d1SDavid du Colombier if (lookup(0, gsym, &s) == 0) 2043e12c5d1SDavid du Colombier error("symbol not found"); 2053e12c5d1SDavid du Colombier expv = s.value; 2063e12c5d1SDavid du Colombier } 2073e12c5d1SDavid du Colombier reread(); 2083e12c5d1SDavid du Colombier } else if (getnum(readchar)) { 2093e12c5d1SDavid du Colombier ; 2103e12c5d1SDavid du Colombier } else if (lastc=='.') { 2113e12c5d1SDavid du Colombier readchar(); 212219b2ee8SDavid du Colombier if (!symchar(0) && lastc != '.') { 2133e12c5d1SDavid du Colombier expv = dot; 2143e12c5d1SDavid du Colombier } else { 215219b2ee8SDavid du Colombier if (findsym(rget(cormap, mach->pc), CTEXT, &s) == 0) 216219b2ee8SDavid du Colombier error("no current function"); 217219b2ee8SDavid du Colombier if (lastc == '.') { 218219b2ee8SDavid du Colombier lsym[0] = '.'; 219219b2ee8SDavid du Colombier readchar(); 220219b2ee8SDavid du Colombier readsym(lsym+1); 221219b2ee8SDavid du Colombier } else 2223e12c5d1SDavid du Colombier readsym(lsym); 2237dd7cddfSDavid du Colombier if (localaddr(cormap, s.name, lsym, &e, rget) < 0) 224219b2ee8SDavid du Colombier error("%r"); 2257dd7cddfSDavid du Colombier expv = e; 2263e12c5d1SDavid du Colombier } 2273e12c5d1SDavid du Colombier reread(); 2283e12c5d1SDavid du Colombier } else if (lastc=='"') { 2293e12c5d1SDavid du Colombier expv=ditto; 2303e12c5d1SDavid du Colombier } else if (lastc=='+') { 2313e12c5d1SDavid du Colombier expv=inkdot(dotinc); 2323e12c5d1SDavid du Colombier } else if (lastc=='^') { 2333e12c5d1SDavid du Colombier expv=inkdot(-dotinc); 2343e12c5d1SDavid du Colombier } else if (lastc=='<') { 2353e12c5d1SDavid du Colombier savc=rdc(); 236219b2ee8SDavid du Colombier base = regname(savc); 237219b2ee8SDavid du Colombier expv = rget(cormap, base); 2383e12c5d1SDavid du Colombier } 2393e12c5d1SDavid du Colombier else if (lastc=='\'') 2403e12c5d1SDavid du Colombier expv = ascval(); 2413e12c5d1SDavid du Colombier else if (a) 2423e12c5d1SDavid du Colombier error("address expected"); 2433e12c5d1SDavid du Colombier else { 2443e12c5d1SDavid du Colombier reread(); 2453e12c5d1SDavid du Colombier return(0); 2463e12c5d1SDavid du Colombier } 2473e12c5d1SDavid du Colombier return(1); 2483e12c5d1SDavid du Colombier } 2493e12c5d1SDavid du Colombier 2503e12c5d1SDavid du Colombier #define MAXBASE 16 2513e12c5d1SDavid du Colombier 2523e12c5d1SDavid du Colombier /* service routines for expression reading */ 2533e12c5d1SDavid du Colombier getnum(int (*rdf)(void)) 2543e12c5d1SDavid du Colombier { 2553e12c5d1SDavid du Colombier char *cp; 2563e12c5d1SDavid du Colombier int base, d; 2573e12c5d1SDavid du Colombier BOOL fpnum; 2583e12c5d1SDavid du Colombier char num[MAXLIN]; 2593e12c5d1SDavid du Colombier 2603e12c5d1SDavid du Colombier base = 0; 2613e12c5d1SDavid du Colombier fpnum = FALSE; 2623e12c5d1SDavid du Colombier if (lastc == '#') { 2633e12c5d1SDavid du Colombier base = 16; 2643e12c5d1SDavid du Colombier (*rdf)(); 2653e12c5d1SDavid du Colombier } 2663e12c5d1SDavid du Colombier if (convdig(lastc) >= MAXBASE) 2673e12c5d1SDavid du Colombier return (0); 2683e12c5d1SDavid du Colombier if (lastc == '0') 2693e12c5d1SDavid du Colombier switch ((*rdf)()) { 2703e12c5d1SDavid du Colombier case 'x': 2713e12c5d1SDavid du Colombier case 'X': 2723e12c5d1SDavid du Colombier base = 16; 2733e12c5d1SDavid du Colombier (*rdf)(); 2743e12c5d1SDavid du Colombier break; 2753e12c5d1SDavid du Colombier 2763e12c5d1SDavid du Colombier case 't': 2773e12c5d1SDavid du Colombier case 'T': 2783e12c5d1SDavid du Colombier base = 10; 2793e12c5d1SDavid du Colombier (*rdf)(); 2803e12c5d1SDavid du Colombier break; 2813e12c5d1SDavid du Colombier 2823e12c5d1SDavid du Colombier case 'o': 2833e12c5d1SDavid du Colombier case 'O': 2843e12c5d1SDavid du Colombier base = 8; 2853e12c5d1SDavid du Colombier (*rdf)(); 2863e12c5d1SDavid du Colombier break; 2873e12c5d1SDavid du Colombier default: 2883e12c5d1SDavid du Colombier if (base == 0) 2893e12c5d1SDavid du Colombier base = 8; 2903e12c5d1SDavid du Colombier break; 2913e12c5d1SDavid du Colombier } 2923e12c5d1SDavid du Colombier if (base == 0) 2933e12c5d1SDavid du Colombier base = 10; 2943e12c5d1SDavid du Colombier expv = 0; 2953e12c5d1SDavid du Colombier for (cp = num, *cp = lastc; ;(*rdf)()) { 2963e12c5d1SDavid du Colombier if ((d = convdig(lastc)) < base) { 2973e12c5d1SDavid du Colombier expv *= base; 2983e12c5d1SDavid du Colombier expv += d; 2993e12c5d1SDavid du Colombier *cp++ = lastc; 3003e12c5d1SDavid du Colombier } 3013e12c5d1SDavid du Colombier else if (lastc == '.') { 3023e12c5d1SDavid du Colombier fpnum = TRUE; 3033e12c5d1SDavid du Colombier *cp++ = lastc; 3043e12c5d1SDavid du Colombier } else { 3053e12c5d1SDavid du Colombier reread(); 3063e12c5d1SDavid du Colombier break; 3073e12c5d1SDavid du Colombier } 3083e12c5d1SDavid du Colombier } 3093e12c5d1SDavid du Colombier if (fpnum) 3103e12c5d1SDavid du Colombier expv = fpin(num); 3113e12c5d1SDavid du Colombier return (1); 3123e12c5d1SDavid du Colombier } 3133e12c5d1SDavid du Colombier 3143e12c5d1SDavid du Colombier void 3153e12c5d1SDavid du Colombier readsym(char *isymbol) 3163e12c5d1SDavid du Colombier { 3173e12c5d1SDavid du Colombier char *p; 318*9a747e4fSDavid du Colombier Rune r; 3193e12c5d1SDavid du Colombier 3203e12c5d1SDavid du Colombier p = isymbol; 3213e12c5d1SDavid du Colombier do { 322*9a747e4fSDavid du Colombier if (p < &isymbol[MAXSYM-UTFmax-1]){ 323*9a747e4fSDavid du Colombier r = lastc; 324*9a747e4fSDavid du Colombier p += runetochar(p, &r); 325*9a747e4fSDavid du Colombier } 3263e12c5d1SDavid du Colombier readchar(); 3273e12c5d1SDavid du Colombier } while (symchar(1)); 3283e12c5d1SDavid du Colombier *p = 0; 3293e12c5d1SDavid du Colombier } 3303e12c5d1SDavid du Colombier 3313e12c5d1SDavid du Colombier void 3323e12c5d1SDavid du Colombier readfname(char *filename) 3333e12c5d1SDavid du Colombier { 3343e12c5d1SDavid du Colombier char *p; 335*9a747e4fSDavid du Colombier Rune c; 3363e12c5d1SDavid du Colombier 3373e12c5d1SDavid du Colombier /* snarf chars until un-escaped char in terminal char set */ 3383e12c5d1SDavid du Colombier p = filename; 3393e12c5d1SDavid du Colombier do { 340*9a747e4fSDavid du Colombier if ((c = lastc) != '\\' && p < &filename[MAXSYM-UTFmax-1]) 341*9a747e4fSDavid du Colombier p += runetochar(p, &c); 3423e12c5d1SDavid du Colombier readchar(); 3433e12c5d1SDavid du Colombier } while (c == '\\' || strchr(CMD_VERBS, lastc) == 0); 3443e12c5d1SDavid du Colombier *p = 0; 3453e12c5d1SDavid du Colombier reread(); 3463e12c5d1SDavid du Colombier } 3473e12c5d1SDavid du Colombier 3483e12c5d1SDavid du Colombier convdig(int c) 3493e12c5d1SDavid du Colombier { 3503e12c5d1SDavid du Colombier if (isdigit(c)) 3513e12c5d1SDavid du Colombier return(c-'0'); 3523e12c5d1SDavid du Colombier else if (!isxdigit(c)) 3533e12c5d1SDavid du Colombier return(MAXBASE); 3543e12c5d1SDavid du Colombier else if (isupper(c)) 3553e12c5d1SDavid du Colombier return(c-'A'+10); 3563e12c5d1SDavid du Colombier else 3573e12c5d1SDavid du Colombier return(c-'a'+10); 3583e12c5d1SDavid du Colombier } 3593e12c5d1SDavid du Colombier 3603e12c5d1SDavid du Colombier symchar(int dig) 3613e12c5d1SDavid du Colombier { 3623e12c5d1SDavid du Colombier if (lastc=='\\') { 3633e12c5d1SDavid du Colombier readchar(); 3643e12c5d1SDavid du Colombier return(TRUE); 3653e12c5d1SDavid du Colombier } 366*9a747e4fSDavid du Colombier return(isalpha(lastc) || lastc>0x80 || lastc=='_' || dig && isdigit(lastc)); 3673e12c5d1SDavid du Colombier } 3683e12c5d1SDavid du Colombier 3693e12c5d1SDavid du Colombier static long 3703e12c5d1SDavid du Colombier round(long a, long b) 3713e12c5d1SDavid du Colombier { 3723e12c5d1SDavid du Colombier long w; 3733e12c5d1SDavid du Colombier 3743e12c5d1SDavid du Colombier w = (a/b)*b; 3753e12c5d1SDavid du Colombier if (a!=w) 3763e12c5d1SDavid du Colombier w += b; 3773e12c5d1SDavid du Colombier return(w); 3783e12c5d1SDavid du Colombier } 379