1*30136Ssam /* kdb_expr.c 7.3 86/11/23 */ 230107Ssam 330107Ssam #include "../kdb/defs.h" 430107Ssam 530107Ssam char *BADSYM; 630107Ssam char *BADVAR; 730107Ssam char *BADKET; 830107Ssam char *BADSYN; 930107Ssam char *NOCFN; 1030107Ssam char *NOADR; 1130107Ssam char *BADLOC; 1230107Ssam 1330107Ssam ADDR lastframe; 1430107Ssam ADDR savlastf; 1530107Ssam ADDR savframe; 1630107Ssam ADDR savpc; 1730107Ssam ADDR callpc; 1830107Ssam 1930107Ssam char *lp; 2030107Ssam int radix; 2130107Ssam char isymbol[1024]; 2230107Ssam 2330107Ssam char lastc, peekc; 2430107Ssam 2530107Ssam long ditto; 2630107Ssam long expv; 2730107Ssam 2830107Ssam /* term | term dyadic expr | */ 2930107Ssam expr(a) 3030107Ssam { 3130107Ssam register rc; 3230107Ssam register long lhs; 3330107Ssam 3430107Ssam rdc(); lp--; rc=term(a); 3530107Ssam 3630107Ssam while (rc) { 3730107Ssam lhs = expv; 3830107Ssam switch ((int)readchar()) { 3930107Ssam case '+': 4030107Ssam term(a|1); expv += lhs; break; 4130107Ssam case '-': 4230107Ssam term(a|1); expv = lhs - expv; break; 4330107Ssam case '#': 4430107Ssam term(a|1); expv = round(lhs,expv); break; 4530107Ssam case '*': 4630107Ssam term(a|1); expv *= lhs; break; 4730107Ssam case '%': 4830107Ssam term(a|1); expv = lhs/expv; break; 4930107Ssam case '&': 5030107Ssam term(a|1); expv &= lhs; break; 5130107Ssam case '|': 5230107Ssam term(a|1); expv |= lhs; break; 5330107Ssam case ')': 5430107Ssam if ((a&2)==0) 5530107Ssam error(BADKET); 5630107Ssam default: 5730107Ssam lp--; 5830107Ssam return (rc); 5930107Ssam } 6030107Ssam } 6130107Ssam return (rc); 6230107Ssam } 6330107Ssam 6430107Ssam /* item | monadic item | (expr) | */ 6530107Ssam static 6630107Ssam term(a) 6730107Ssam { 6830107Ssam 6930107Ssam switch ((int)readchar()) { 7030107Ssam case '*': 7130107Ssam term(a|1); expv=chkget(expv,DSP); 7230107Ssam return(1); 7330107Ssam case '@': 7430107Ssam term(a|1); expv=chkget(expv,ISP); 7530107Ssam return(1); 7630107Ssam case '-': 7730107Ssam term(a|1); expv = -expv; 7830107Ssam return(1); 7930107Ssam case '~': 8030107Ssam term(a|1); expv = ~expv; 8130107Ssam return(1); 8230107Ssam case '#': 8330107Ssam term(a|1); expv = !expv; 8430107Ssam return(1); 8530107Ssam case '(': 8630107Ssam expr(2); 8730107Ssam if (*lp!=')') 8830107Ssam error(BADSYN); 8930107Ssam lp++; 9030107Ssam return(1); 9130107Ssam } 9230107Ssam lp--; 9330107Ssam return (item(a)); 9430107Ssam } 9530107Ssam 9630107Ssam /* name [ . local ] | number | . | ^ | <var | <register | 'x | | */ 9730107Ssam static 9830107Ssam item(a) 9930107Ssam { 10030107Ssam register base, d, regptr; 10130107Ssam char savc; 10230107Ssam register long frame; 10330107Ssam register struct nlist *symp; 10430107Ssam 10530107Ssam readchar(); 10630107Ssam if (symchar(0)) { 10730107Ssam readsym(); 10830107Ssam if (lastc=='.') { 10930107Ssam frame = pcb.pcb_fp; lastframe = 0; 110*30136Ssam callpc = pcb.pcb_pc; 111*30136Ssam while (!errflg) { 112*30136Ssam savpc = callpc; 113*30136Ssam findsym(callpc,ISYM); 114*30136Ssam if (eqsym(cursym->n_un.n_name,isymbol,'~')) 115*30136Ssam break; 116*30136Ssam callpc = getprevpc(frame); 117*30136Ssam lastframe = frame; 118*30136Ssam frame = getprevframe(frame); 119*30136Ssam if (frame == NOFRAME) 120*30136Ssam error(NOCFN); 12130107Ssam } 122*30136Ssam savlastf = lastframe; savframe = frame; 12330107Ssam readchar(); 12430107Ssam if (symchar(0)) 12530107Ssam chkloc(expv=frame); 12630107Ssam } else if ((symp=lookup(isymbol))==0) 12730107Ssam error(BADSYM); 12830107Ssam else 12930107Ssam expv = symp->n_value; 13030107Ssam lp--; 131*30136Ssam return (1); 132*30136Ssam } 133*30136Ssam if (getnum()) 134*30136Ssam return (1); 135*30136Ssam switch (lastc) { 136*30136Ssam case '.': 13730107Ssam readchar(); 13830107Ssam if (symchar(0)) { 13930107Ssam lastframe=savlastf; callpc=savpc; 14030107Ssam chkloc(savframe); 14130107Ssam } else 14230107Ssam expv=dot; 14330107Ssam lp--; 144*30136Ssam break; 145*30136Ssam case '"': 14630107Ssam expv=ditto; 147*30136Ssam break; 148*30136Ssam case '+': 14930107Ssam expv=inkdot(dotinc); 150*30136Ssam break; 151*30136Ssam case '^': 15230107Ssam expv=inkdot(-dotinc); 153*30136Ssam break; 154*30136Ssam case '<': 15530107Ssam savc=rdc(); 15630107Ssam if ((regptr=getreg(savc)) != -1) 15730107Ssam expv = *(int *)regptr; 15830107Ssam else if ((base=varchk(savc)) != -1) 15930107Ssam expv=var[base]; 16030107Ssam else 16130107Ssam error(BADVAR); 162*30136Ssam break; 163*30136Ssam case '\'': 16430107Ssam d=4; expv=0; 16530107Ssam while (quotchar()) { 16630107Ssam if (d--) { 16730107Ssam expv <<= 8; 16830107Ssam expv |= lastc; 16930107Ssam } else 17030107Ssam error(BADSYN); 17130107Ssam } 172*30136Ssam break; 173*30136Ssam default: 174*30136Ssam if (a) 175*30136Ssam error(NOADR); 17630107Ssam lp--; 17730107Ssam return(0); 17830107Ssam } 17930107Ssam return (1); 18030107Ssam } 18130107Ssam 18230107Ssam /* service routines for expression reading */ 18330107Ssam static 18430107Ssam getnum() 18530107Ssam { 18630107Ssam register base,d,frpt; 18730107Ssam union { float r; long i;} real; 18830107Ssam 18930107Ssam if (!isdigit(lastc)) 19030107Ssam return (0); 19130107Ssam if ((base = radix) < 0) 19230107Ssam base = -base; 19330107Ssam expv = 0; 19430107Ssam while (base>10 ? isxdigit(lastc) : isdigit(lastc)) { 19530107Ssam register m = MAXINT/base; 19630107Ssam 19730107Ssam if (expv>m) /* avoid overflow */ 19830107Ssam expv = (expv-m)*base+m*base; 19930107Ssam else 20030107Ssam expv *= base; 20130107Ssam if ((d=convdig(lastc))>=base || d<0) 20230107Ssam error(BADSYN); 20330107Ssam expv += d; readchar(); 20430107Ssam if (expv==0) { 20530107Ssam if (lastc=='x' || lastc=='X') { 20630107Ssam base=16; readchar(); 20730107Ssam } else if (lastc=='t' || lastc=='T') { 20830107Ssam base=10; readchar(); 20930107Ssam } else if (lastc=='o' || lastc=='O') { 21030107Ssam base=8; readchar(); 21130107Ssam } 21230107Ssam } 21330107Ssam } 21430107Ssam if (lastc=='.' && (base==10 || expv==0)) { 21530107Ssam real.r=expv; frpt=0; base=10; 21630107Ssam while (isdigit(readchar())) { 21730107Ssam real.r *= base; frpt++; 21830107Ssam real.r += lastc-'0'; 21930107Ssam } 22030107Ssam while (frpt--) 22130107Ssam real.r /= base; 22230107Ssam expv = real.i; 22330107Ssam } 22430107Ssam peekc=lastc; 22530107Ssam return (1); 22630107Ssam } 22730107Ssam 22830107Ssam static 22930107Ssam readsym() 23030107Ssam { 23130107Ssam register char *p; 23230107Ssam 23330107Ssam p = isymbol; 23430107Ssam do { 23530107Ssam if (p < &isymbol[sizeof(isymbol)-1]) 23630107Ssam *p++ = lastc; 23730107Ssam readchar(); 23830107Ssam } while (symchar(1)); 23930107Ssam *p++ = 0; 24030107Ssam } 24130107Ssam 24230107Ssam static 24330107Ssam convdig(c) 24430107Ssam char c; 24530107Ssam { 24630107Ssam if (isdigit(c)) 24730107Ssam return (c-'0'); 24830107Ssam if (isxdigit(c)) 24930107Ssam return (c-'a'+10); 25030107Ssam return (-1); 25130107Ssam } 25230107Ssam 25330107Ssam static 25430107Ssam symchar(dig) 25530107Ssam { 25630107Ssam 25730107Ssam if (lastc=='\\') { 25830107Ssam readchar(); 25930118Ssam return (1); 26030107Ssam } 26130107Ssam return (isalpha(lastc) || lastc=='_' || dig && isdigit(lastc)); 26230107Ssam } 26330107Ssam 26430107Ssam varchk(name) 26530107Ssam register name; 26630107Ssam { 26730107Ssam if (isdigit(name)) 26830107Ssam return (name-'0'); 26930107Ssam if (isalpha(name)) 27030107Ssam return ((name&037)-1+10); 27130107Ssam return (-1); 27230107Ssam } 27330107Ssam 27430107Ssam static 27530107Ssam chkloc(frame) 27630107Ssam long frame; 27730107Ssam { 27830107Ssam 27930107Ssam readsym(); 28030107Ssam do { 28130107Ssam if (localsym(frame)==0) 28230107Ssam error(BADLOC); 28330107Ssam expv=localval; 28430107Ssam } while (!eqsym(cursym->n_un.n_name,isymbol,'~')); 28530107Ssam } 28630107Ssam 28730107Ssam eqsym(s1, s2, c) 28830107Ssam register char *s1, *s2; 28930107Ssam { 29030107Ssam 29130107Ssam if (streq(s1,s2)) 29230107Ssam return (1); 29330107Ssam if (*s1 == c && streq(s1+1, s2)) 29430107Ssam return (1); 29530107Ssam return (0); 29630107Ssam } 29730107Ssam 29830107Ssam static 29930107Ssam streq(s1, s2) 30030107Ssam char *s1, *s2; 30130107Ssam { 30230107Ssam 30330107Ssam while (*s1 == *s2++) 30430107Ssam if (*s1++ == '\0') 30530107Ssam return (1); 30630107Ssam return (0); 30730107Ssam } 30830107Ssam 30930107Ssam static 31030107Ssam round(a,b) 31130107Ssam register long a, b; 31230107Ssam { 31330107Ssam register long w; 31430107Ssam 31530107Ssam w = (a/b)*b; 31630107Ssam if (a!=w) 31730107Ssam w += b; 31830107Ssam return (w); 31930107Ssam } 320