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;
13*4de34a7eSDavid du Colombier uvlong expv;
14219b2ee8SDavid du Colombier
15219b2ee8SDavid du Colombier static WORD
ascval(void)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);
229a747e4fSDavid 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
fpin(char * buf)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
defval(WORD w)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
expr(int a)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
term(int a)1203e12c5d1SDavid du Colombier term(int a)
1213e12c5d1SDavid du Colombier { /* item | monadic item | (expr) | */
122*4de34a7eSDavid du Colombier ADDR e;
1233e12c5d1SDavid du Colombier
1243e12c5d1SDavid du Colombier switch ((int)readchar()) {
1253e12c5d1SDavid du Colombier
1263e12c5d1SDavid du Colombier case '*':
1273e12c5d1SDavid du Colombier term(a|1);
128*4de34a7eSDavid du Colombier if (geta(cormap, 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);
135*4de34a7eSDavid du Colombier if (geta(symmap, 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
item(int a)1623e12c5d1SDavid du Colombier item(int a)
163219b2ee8SDavid du Colombier { /* name [ . local ] | number | . | ^ | <register | 'x | | */
164219b2ee8SDavid du Colombier char *base;
1653e12c5d1SDavid du Colombier char savc;
166*4de34a7eSDavid du Colombier uvlong 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 */
getnum(int (* rdf)(void))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
readsym(char * isymbol)3153e12c5d1SDavid du Colombier readsym(char *isymbol)
3163e12c5d1SDavid du Colombier {
3173e12c5d1SDavid du Colombier char *p;
3189a747e4fSDavid du Colombier Rune r;
3193e12c5d1SDavid du Colombier
3203e12c5d1SDavid du Colombier p = isymbol;
3213e12c5d1SDavid du Colombier do {
3229a747e4fSDavid du Colombier if (p < &isymbol[MAXSYM-UTFmax-1]){
3239a747e4fSDavid du Colombier r = lastc;
3249a747e4fSDavid du Colombier p += runetochar(p, &r);
3259a747e4fSDavid 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
readfname(char * filename)3323e12c5d1SDavid du Colombier readfname(char *filename)
3333e12c5d1SDavid du Colombier {
3343e12c5d1SDavid du Colombier char *p;
3359a747e4fSDavid 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 {
3409a747e4fSDavid du Colombier if ((c = lastc) != '\\' && p < &filename[MAXSYM-UTFmax-1])
3419a747e4fSDavid 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
convdig(int c)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
symchar(int dig)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 }
3669a747e4fSDavid du Colombier return(isalpha(lastc) || lastc>0x80 || lastc=='_' || dig && isdigit(lastc));
3673e12c5d1SDavid du Colombier }
3683e12c5d1SDavid du Colombier
3693e12c5d1SDavid du Colombier static long
round(long a,long b)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