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 char lastc, peekc; 133e12c5d1SDavid du Colombier 143e12c5d1SDavid du Colombier extern ADDR ditto; 15*7dd7cddfSDavid du Colombier vlong expv; 16219b2ee8SDavid du Colombier 17219b2ee8SDavid du Colombier static WORD 18219b2ee8SDavid du Colombier ascval(void) 19219b2ee8SDavid du Colombier { 20219b2ee8SDavid du Colombier Rune r; 21219b2ee8SDavid du Colombier int i; 22219b2ee8SDavid du Colombier char buf[UTFmax+1]; 23219b2ee8SDavid du Colombier 24219b2ee8SDavid du Colombier for (i = 0; i < UTFmax; i++) { /* extract a rune */ 25219b2ee8SDavid du Colombier if (fullrune(buf, i)) 26219b2ee8SDavid du Colombier break; 27219b2ee8SDavid du Colombier if (readchar() == 0) 28219b2ee8SDavid du Colombier return (0); 29219b2ee8SDavid du Colombier buf[i] = lastc; 30219b2ee8SDavid du Colombier } 31219b2ee8SDavid du Colombier buf[i] = 0; 32219b2ee8SDavid du Colombier chartorune(&r, buf); 33219b2ee8SDavid du Colombier while(quotchar()) /*discard chars to ending quote */ 34219b2ee8SDavid du Colombier ; 35219b2ee8SDavid du Colombier return((WORD) r); 36219b2ee8SDavid du Colombier } 37219b2ee8SDavid du Colombier 38219b2ee8SDavid du Colombier /* 39219b2ee8SDavid du Colombier * read a floating point number 40219b2ee8SDavid du Colombier * the result must fit in a WORD 41219b2ee8SDavid du Colombier */ 42219b2ee8SDavid du Colombier 43219b2ee8SDavid du Colombier static WORD 44219b2ee8SDavid du Colombier fpin(char *buf) 45219b2ee8SDavid du Colombier { 46219b2ee8SDavid du Colombier union { 47219b2ee8SDavid du Colombier WORD w; 48219b2ee8SDavid du Colombier float f; 49219b2ee8SDavid du Colombier } x; 50219b2ee8SDavid du Colombier 51219b2ee8SDavid du Colombier x.f = atof(buf); 52219b2ee8SDavid du Colombier return (x.w); 53219b2ee8SDavid du Colombier } 543e12c5d1SDavid du Colombier 553e12c5d1SDavid du Colombier WORD 563e12c5d1SDavid du Colombier defval(WORD w) 573e12c5d1SDavid du Colombier { 583e12c5d1SDavid du Colombier if (expr(0)) 593e12c5d1SDavid du Colombier return (expv); 603e12c5d1SDavid du Colombier else 613e12c5d1SDavid du Colombier return (w); 623e12c5d1SDavid du Colombier } 633e12c5d1SDavid du Colombier 643e12c5d1SDavid du Colombier expr(int a) 653e12c5d1SDavid du Colombier { /* term | term dyadic expr | */ 663e12c5d1SDavid du Colombier int rc; 673e12c5d1SDavid du Colombier WORD lhs; 683e12c5d1SDavid du Colombier 693e12c5d1SDavid du Colombier rdc(); 703e12c5d1SDavid du Colombier reread(); 713e12c5d1SDavid du Colombier rc=term(a); 723e12c5d1SDavid du Colombier while (rc) { 733e12c5d1SDavid du Colombier lhs = expv; 743e12c5d1SDavid du Colombier switch ((int)readchar()) { 753e12c5d1SDavid du Colombier 763e12c5d1SDavid du Colombier case '+': 773e12c5d1SDavid du Colombier term(a|1); 783e12c5d1SDavid du Colombier expv += lhs; 793e12c5d1SDavid du Colombier break; 803e12c5d1SDavid du Colombier 813e12c5d1SDavid du Colombier case '-': 823e12c5d1SDavid du Colombier term(a|1); 833e12c5d1SDavid du Colombier expv = lhs - expv; 843e12c5d1SDavid du Colombier break; 853e12c5d1SDavid du Colombier 863e12c5d1SDavid du Colombier case '#': 873e12c5d1SDavid du Colombier term(a|1); 883e12c5d1SDavid du Colombier expv = round(lhs,expv); 893e12c5d1SDavid du Colombier break; 903e12c5d1SDavid du Colombier 913e12c5d1SDavid du Colombier case '*': 923e12c5d1SDavid du Colombier term(a|1); 933e12c5d1SDavid du Colombier expv *= lhs; 943e12c5d1SDavid du Colombier break; 953e12c5d1SDavid du Colombier 963e12c5d1SDavid du Colombier case '%': 973e12c5d1SDavid du Colombier term(a|1); 983e12c5d1SDavid du Colombier if(expv != 0) 993e12c5d1SDavid du Colombier expv = lhs/expv; 1003e12c5d1SDavid du Colombier else{ 1013e12c5d1SDavid du Colombier if(lhs) 1023e12c5d1SDavid du Colombier expv = 1; 1033e12c5d1SDavid du Colombier else 1043e12c5d1SDavid du Colombier expv = 0; 1053e12c5d1SDavid du Colombier } 1063e12c5d1SDavid du Colombier break; 1073e12c5d1SDavid du Colombier 1083e12c5d1SDavid du Colombier case '&': 1093e12c5d1SDavid du Colombier term(a|1); 1103e12c5d1SDavid du Colombier expv &= lhs; 1113e12c5d1SDavid du Colombier break; 1123e12c5d1SDavid du Colombier 1133e12c5d1SDavid du Colombier case '|': 1143e12c5d1SDavid du Colombier term(a|1); 1153e12c5d1SDavid du Colombier expv |= lhs; 1163e12c5d1SDavid du Colombier break; 1173e12c5d1SDavid du Colombier 1183e12c5d1SDavid du Colombier case ')': 1193e12c5d1SDavid du Colombier if ((a&2)==0) 1203e12c5d1SDavid du Colombier error("unexpected `)'"); 1213e12c5d1SDavid du Colombier 1223e12c5d1SDavid du Colombier default: 1233e12c5d1SDavid du Colombier reread(); 1243e12c5d1SDavid du Colombier return(rc); 1253e12c5d1SDavid du Colombier } 1263e12c5d1SDavid du Colombier } 1273e12c5d1SDavid du Colombier return(rc); 1283e12c5d1SDavid du Colombier } 1293e12c5d1SDavid du Colombier 1303e12c5d1SDavid du Colombier term(int a) 1313e12c5d1SDavid du Colombier { /* item | monadic item | (expr) | */ 132*7dd7cddfSDavid du Colombier WORD e; 1333e12c5d1SDavid du Colombier 1343e12c5d1SDavid du Colombier switch ((int)readchar()) { 1353e12c5d1SDavid du Colombier 1363e12c5d1SDavid du Colombier case '*': 1373e12c5d1SDavid du Colombier term(a|1); 138*7dd7cddfSDavid du Colombier if (get4(cormap, (ADDR)expv, &e) < 0) 139219b2ee8SDavid du Colombier error("%r"); 140*7dd7cddfSDavid du Colombier expv = e; 1413e12c5d1SDavid du Colombier return(1); 1423e12c5d1SDavid du Colombier 1433e12c5d1SDavid du Colombier case '@': 1443e12c5d1SDavid du Colombier term(a|1); 145*7dd7cddfSDavid du Colombier if (get4(symmap, (ADDR)expv, &e) < 0) 146219b2ee8SDavid du Colombier error("%r"); 147*7dd7cddfSDavid du Colombier expv = e; 1483e12c5d1SDavid du Colombier return(1); 1493e12c5d1SDavid du Colombier 1503e12c5d1SDavid du Colombier case '-': 1513e12c5d1SDavid du Colombier term(a|1); 1523e12c5d1SDavid du Colombier expv = -expv; 1533e12c5d1SDavid du Colombier return(1); 1543e12c5d1SDavid du Colombier 1553e12c5d1SDavid du Colombier case '~': 1563e12c5d1SDavid du Colombier term(a|1); 1573e12c5d1SDavid du Colombier expv = ~expv; 1583e12c5d1SDavid du Colombier return(1); 1593e12c5d1SDavid du Colombier 1603e12c5d1SDavid du Colombier case '(': 1613e12c5d1SDavid du Colombier expr(2); 1623e12c5d1SDavid du Colombier if (readchar()!=')') 1633e12c5d1SDavid du Colombier error("syntax error: `)' expected"); 1643e12c5d1SDavid du Colombier return(1); 1653e12c5d1SDavid du Colombier 1663e12c5d1SDavid du Colombier default: 1673e12c5d1SDavid du Colombier reread(); 1683e12c5d1SDavid du Colombier return(item(a)); 1693e12c5d1SDavid du Colombier } 1703e12c5d1SDavid du Colombier } 1713e12c5d1SDavid du Colombier 1723e12c5d1SDavid du Colombier item(int a) 173219b2ee8SDavid du Colombier { /* name [ . local ] | number | . | ^ | <register | 'x | | */ 174219b2ee8SDavid du Colombier char *base; 1753e12c5d1SDavid du Colombier char savc; 176*7dd7cddfSDavid du Colombier WORD e; 1773e12c5d1SDavid du Colombier Symbol s; 1783e12c5d1SDavid du Colombier char gsym[MAXSYM], lsym[MAXSYM]; 1793e12c5d1SDavid du Colombier 1803e12c5d1SDavid du Colombier readchar(); 1813e12c5d1SDavid du Colombier if (isfileref()) { 1823e12c5d1SDavid du Colombier readfname(gsym); 1833e12c5d1SDavid du Colombier rdc(); /* skip white space */ 1843e12c5d1SDavid du Colombier if (lastc == ':') { /* it better be */ 1853e12c5d1SDavid du Colombier rdc(); /* skip white space */ 1863e12c5d1SDavid du Colombier if (!getnum(readchar)) 1873e12c5d1SDavid du Colombier error("bad number"); 1883e12c5d1SDavid du Colombier if (expv == 0) 1893e12c5d1SDavid du Colombier expv = 1; /* file begins at line 1 */ 1903e12c5d1SDavid du Colombier expv = file2pc(gsym, expv); 1913e12c5d1SDavid du Colombier if (expv == -1) 192219b2ee8SDavid du Colombier error("%r"); 1933e12c5d1SDavid du Colombier return 1; 1943e12c5d1SDavid du Colombier } 1953e12c5d1SDavid du Colombier error("bad file location"); 1963e12c5d1SDavid du Colombier } else if (symchar(0)) { 1973e12c5d1SDavid du Colombier readsym(gsym); 1983e12c5d1SDavid du Colombier if (lastc=='.') { 1993e12c5d1SDavid du Colombier readchar(); /* ugh */ 200219b2ee8SDavid du Colombier if (lastc == '.') { 201219b2ee8SDavid du Colombier lsym[0] = '.'; 202219b2ee8SDavid du Colombier readchar(); 203219b2ee8SDavid du Colombier readsym(lsym+1); 204219b2ee8SDavid du Colombier } else if (symchar(0)) { 2053e12c5d1SDavid du Colombier readsym(lsym); 206219b2ee8SDavid du Colombier } else 207219b2ee8SDavid du Colombier lsym[0] = 0; 208*7dd7cddfSDavid du Colombier if (localaddr(cormap, gsym, lsym, &e, rget) < 0) 209219b2ee8SDavid du Colombier error("%r"); 210*7dd7cddfSDavid du Colombier expv = e; 2113e12c5d1SDavid du Colombier } 2123e12c5d1SDavid du Colombier else { 2133e12c5d1SDavid du Colombier if (lookup(0, gsym, &s) == 0) 2143e12c5d1SDavid du Colombier error("symbol not found"); 2153e12c5d1SDavid du Colombier expv = s.value; 2163e12c5d1SDavid du Colombier } 2173e12c5d1SDavid du Colombier reread(); 2183e12c5d1SDavid du Colombier } else if (getnum(readchar)) { 2193e12c5d1SDavid du Colombier ; 2203e12c5d1SDavid du Colombier } else if (lastc=='.') { 2213e12c5d1SDavid du Colombier readchar(); 222219b2ee8SDavid du Colombier if (!symchar(0) && lastc != '.') { 2233e12c5d1SDavid du Colombier expv = dot; 2243e12c5d1SDavid du Colombier } else { 225219b2ee8SDavid du Colombier if (findsym(rget(cormap, mach->pc), CTEXT, &s) == 0) 226219b2ee8SDavid du Colombier error("no current function"); 227219b2ee8SDavid du Colombier if (lastc == '.') { 228219b2ee8SDavid du Colombier lsym[0] = '.'; 229219b2ee8SDavid du Colombier readchar(); 230219b2ee8SDavid du Colombier readsym(lsym+1); 231219b2ee8SDavid du Colombier } else 2323e12c5d1SDavid du Colombier readsym(lsym); 233*7dd7cddfSDavid du Colombier if (localaddr(cormap, s.name, lsym, &e, rget) < 0) 234219b2ee8SDavid du Colombier error("%r"); 235*7dd7cddfSDavid du Colombier expv = e; 2363e12c5d1SDavid du Colombier } 2373e12c5d1SDavid du Colombier reread(); 2383e12c5d1SDavid du Colombier } else if (lastc=='"') { 2393e12c5d1SDavid du Colombier expv=ditto; 2403e12c5d1SDavid du Colombier } else if (lastc=='+') { 2413e12c5d1SDavid du Colombier expv=inkdot(dotinc); 2423e12c5d1SDavid du Colombier } else if (lastc=='^') { 2433e12c5d1SDavid du Colombier expv=inkdot(-dotinc); 2443e12c5d1SDavid du Colombier } else if (lastc=='<') { 2453e12c5d1SDavid du Colombier savc=rdc(); 246219b2ee8SDavid du Colombier base = regname(savc); 247219b2ee8SDavid du Colombier expv = rget(cormap, base); 2483e12c5d1SDavid du Colombier } 2493e12c5d1SDavid du Colombier else if (lastc=='\'') 2503e12c5d1SDavid du Colombier expv = ascval(); 2513e12c5d1SDavid du Colombier else if (a) 2523e12c5d1SDavid du Colombier error("address expected"); 2533e12c5d1SDavid du Colombier else { 2543e12c5d1SDavid du Colombier reread(); 2553e12c5d1SDavid du Colombier return(0); 2563e12c5d1SDavid du Colombier } 2573e12c5d1SDavid du Colombier return(1); 2583e12c5d1SDavid du Colombier } 2593e12c5d1SDavid du Colombier 2603e12c5d1SDavid du Colombier #define MAXBASE 16 2613e12c5d1SDavid du Colombier 2623e12c5d1SDavid du Colombier /* service routines for expression reading */ 2633e12c5d1SDavid du Colombier getnum(int (*rdf)(void)) 2643e12c5d1SDavid du Colombier { 2653e12c5d1SDavid du Colombier char *cp; 2663e12c5d1SDavid du Colombier int base, d; 2673e12c5d1SDavid du Colombier BOOL fpnum; 2683e12c5d1SDavid du Colombier char num[MAXLIN]; 2693e12c5d1SDavid du Colombier 2703e12c5d1SDavid du Colombier base = 0; 2713e12c5d1SDavid du Colombier fpnum = FALSE; 2723e12c5d1SDavid du Colombier if (lastc == '#') { 2733e12c5d1SDavid du Colombier base = 16; 2743e12c5d1SDavid du Colombier (*rdf)(); 2753e12c5d1SDavid du Colombier } 2763e12c5d1SDavid du Colombier if (convdig(lastc) >= MAXBASE) 2773e12c5d1SDavid du Colombier return (0); 2783e12c5d1SDavid du Colombier if (lastc == '0') 2793e12c5d1SDavid du Colombier switch ((*rdf)()) { 2803e12c5d1SDavid du Colombier case 'x': 2813e12c5d1SDavid du Colombier case 'X': 2823e12c5d1SDavid du Colombier base = 16; 2833e12c5d1SDavid du Colombier (*rdf)(); 2843e12c5d1SDavid du Colombier break; 2853e12c5d1SDavid du Colombier 2863e12c5d1SDavid du Colombier case 't': 2873e12c5d1SDavid du Colombier case 'T': 2883e12c5d1SDavid du Colombier base = 10; 2893e12c5d1SDavid du Colombier (*rdf)(); 2903e12c5d1SDavid du Colombier break; 2913e12c5d1SDavid du Colombier 2923e12c5d1SDavid du Colombier case 'o': 2933e12c5d1SDavid du Colombier case 'O': 2943e12c5d1SDavid du Colombier base = 8; 2953e12c5d1SDavid du Colombier (*rdf)(); 2963e12c5d1SDavid du Colombier break; 2973e12c5d1SDavid du Colombier default: 2983e12c5d1SDavid du Colombier if (base == 0) 2993e12c5d1SDavid du Colombier base = 8; 3003e12c5d1SDavid du Colombier break; 3013e12c5d1SDavid du Colombier } 3023e12c5d1SDavid du Colombier if (base == 0) 3033e12c5d1SDavid du Colombier base = 10; 3043e12c5d1SDavid du Colombier expv = 0; 3053e12c5d1SDavid du Colombier for (cp = num, *cp = lastc; ;(*rdf)()) { 3063e12c5d1SDavid du Colombier if ((d = convdig(lastc)) < base) { 3073e12c5d1SDavid du Colombier expv *= base; 3083e12c5d1SDavid du Colombier expv += d; 3093e12c5d1SDavid du Colombier *cp++ = lastc; 3103e12c5d1SDavid du Colombier } 3113e12c5d1SDavid du Colombier else if (lastc == '.') { 3123e12c5d1SDavid du Colombier fpnum = TRUE; 3133e12c5d1SDavid du Colombier *cp++ = lastc; 3143e12c5d1SDavid du Colombier } else { 3153e12c5d1SDavid du Colombier reread(); 3163e12c5d1SDavid du Colombier break; 3173e12c5d1SDavid du Colombier } 3183e12c5d1SDavid du Colombier } 3193e12c5d1SDavid du Colombier if (fpnum) 3203e12c5d1SDavid du Colombier expv = fpin(num); 3213e12c5d1SDavid du Colombier return (1); 3223e12c5d1SDavid du Colombier } 3233e12c5d1SDavid du Colombier 3243e12c5d1SDavid du Colombier void 3253e12c5d1SDavid du Colombier readsym(char *isymbol) 3263e12c5d1SDavid du Colombier { 3273e12c5d1SDavid du Colombier char *p; 3283e12c5d1SDavid du Colombier 3293e12c5d1SDavid du Colombier p = isymbol; 3303e12c5d1SDavid du Colombier do { 3313e12c5d1SDavid du Colombier if (p < &isymbol[MAXSYM-1]) 3323e12c5d1SDavid du Colombier *p++ = lastc; 3333e12c5d1SDavid du Colombier readchar(); 3343e12c5d1SDavid du Colombier } while (symchar(1)); 3353e12c5d1SDavid du Colombier *p = 0; 3363e12c5d1SDavid du Colombier } 3373e12c5d1SDavid du Colombier 3383e12c5d1SDavid du Colombier void 3393e12c5d1SDavid du Colombier readfname(char *filename) 3403e12c5d1SDavid du Colombier { 3413e12c5d1SDavid du Colombier char *p; 3423e12c5d1SDavid du Colombier char c; 3433e12c5d1SDavid du Colombier 3443e12c5d1SDavid du Colombier /* snarf chars until un-escaped char in terminal char set */ 3453e12c5d1SDavid du Colombier p = filename; 3463e12c5d1SDavid du Colombier do { 3473e12c5d1SDavid du Colombier if ((c = lastc) != '\\' && p < &filename[MAXSYM-1]) 3483e12c5d1SDavid du Colombier *p++ = c; 3493e12c5d1SDavid du Colombier readchar(); 3503e12c5d1SDavid du Colombier } while (c == '\\' || strchr(CMD_VERBS, lastc) == 0); 3513e12c5d1SDavid du Colombier *p = 0; 3523e12c5d1SDavid du Colombier reread(); 3533e12c5d1SDavid du Colombier } 3543e12c5d1SDavid du Colombier 3553e12c5d1SDavid du Colombier convdig(int c) 3563e12c5d1SDavid du Colombier { 3573e12c5d1SDavid du Colombier if (isdigit(c)) 3583e12c5d1SDavid du Colombier return(c-'0'); 3593e12c5d1SDavid du Colombier else if (!isxdigit(c)) 3603e12c5d1SDavid du Colombier return(MAXBASE); 3613e12c5d1SDavid du Colombier else if (isupper(c)) 3623e12c5d1SDavid du Colombier return(c-'A'+10); 3633e12c5d1SDavid du Colombier else 3643e12c5d1SDavid du Colombier return(c-'a'+10); 3653e12c5d1SDavid du Colombier } 3663e12c5d1SDavid du Colombier 3673e12c5d1SDavid du Colombier symchar(int dig) 3683e12c5d1SDavid du Colombier { 3693e12c5d1SDavid du Colombier if (lastc=='\\') { 3703e12c5d1SDavid du Colombier readchar(); 3713e12c5d1SDavid du Colombier return(TRUE); 3723e12c5d1SDavid du Colombier } 3733e12c5d1SDavid du Colombier return(isalpha(lastc) || lastc=='_' || dig && isdigit(lastc)); 3743e12c5d1SDavid du Colombier } 3753e12c5d1SDavid du Colombier 3763e12c5d1SDavid du Colombier static long 3773e12c5d1SDavid du Colombier round(long a, long b) 3783e12c5d1SDavid du Colombier { 3793e12c5d1SDavid du Colombier long w; 3803e12c5d1SDavid du Colombier 3813e12c5d1SDavid du Colombier w = (a/b)*b; 3823e12c5d1SDavid du Colombier if (a!=w) 3833e12c5d1SDavid du Colombier w += b; 3843e12c5d1SDavid du Colombier return(w); 3853e12c5d1SDavid du Colombier } 386