1*30107Ssam /* kdb_expr.c 7.1 86/11/20 */ 2*30107Ssam 3*30107Ssam #include "../kdb/defs.h" 4*30107Ssam 5*30107Ssam char *BADSYM; 6*30107Ssam char *BADVAR; 7*30107Ssam char *BADKET; 8*30107Ssam char *BADSYN; 9*30107Ssam char *NOCFN; 10*30107Ssam char *NOADR; 11*30107Ssam char *BADLOC; 12*30107Ssam 13*30107Ssam ADDR lastframe; 14*30107Ssam ADDR savlastf; 15*30107Ssam ADDR savframe; 16*30107Ssam ADDR savpc; 17*30107Ssam ADDR callpc; 18*30107Ssam 19*30107Ssam char *lp; 20*30107Ssam int radix; 21*30107Ssam char isymbol[1024]; 22*30107Ssam 23*30107Ssam char lastc, peekc; 24*30107Ssam 25*30107Ssam long ditto; 26*30107Ssam long expv; 27*30107Ssam 28*30107Ssam /* term | term dyadic expr | */ 29*30107Ssam expr(a) 30*30107Ssam { 31*30107Ssam register rc; 32*30107Ssam register long lhs; 33*30107Ssam 34*30107Ssam rdc(); lp--; rc=term(a); 35*30107Ssam 36*30107Ssam while (rc) { 37*30107Ssam lhs = expv; 38*30107Ssam switch ((int)readchar()) { 39*30107Ssam case '+': 40*30107Ssam term(a|1); expv += lhs; break; 41*30107Ssam case '-': 42*30107Ssam term(a|1); expv = lhs - expv; break; 43*30107Ssam case '#': 44*30107Ssam term(a|1); expv = round(lhs,expv); break; 45*30107Ssam case '*': 46*30107Ssam term(a|1); expv *= lhs; break; 47*30107Ssam case '%': 48*30107Ssam term(a|1); expv = lhs/expv; break; 49*30107Ssam case '&': 50*30107Ssam term(a|1); expv &= lhs; break; 51*30107Ssam case '|': 52*30107Ssam term(a|1); expv |= lhs; break; 53*30107Ssam case ')': 54*30107Ssam if ((a&2)==0) 55*30107Ssam error(BADKET); 56*30107Ssam default: 57*30107Ssam lp--; 58*30107Ssam return (rc); 59*30107Ssam } 60*30107Ssam } 61*30107Ssam return (rc); 62*30107Ssam } 63*30107Ssam 64*30107Ssam /* item | monadic item | (expr) | */ 65*30107Ssam static 66*30107Ssam term(a) 67*30107Ssam { 68*30107Ssam 69*30107Ssam switch ((int)readchar()) { 70*30107Ssam case '*': 71*30107Ssam term(a|1); expv=chkget(expv,DSP); 72*30107Ssam return(1); 73*30107Ssam case '@': 74*30107Ssam term(a|1); expv=chkget(expv,ISP); 75*30107Ssam return(1); 76*30107Ssam case '-': 77*30107Ssam term(a|1); expv = -expv; 78*30107Ssam return(1); 79*30107Ssam case '~': 80*30107Ssam term(a|1); expv = ~expv; 81*30107Ssam return(1); 82*30107Ssam case '#': 83*30107Ssam term(a|1); expv = !expv; 84*30107Ssam return(1); 85*30107Ssam case '(': 86*30107Ssam expr(2); 87*30107Ssam if (*lp!=')') 88*30107Ssam error(BADSYN); 89*30107Ssam lp++; 90*30107Ssam return(1); 91*30107Ssam } 92*30107Ssam lp--; 93*30107Ssam return (item(a)); 94*30107Ssam } 95*30107Ssam 96*30107Ssam /* name [ . local ] | number | . | ^ | <var | <register | 'x | | */ 97*30107Ssam static 98*30107Ssam item(a) 99*30107Ssam { 100*30107Ssam register base, d, regptr; 101*30107Ssam char savc; 102*30107Ssam register long frame; 103*30107Ssam register struct nlist *symp; 104*30107Ssam 105*30107Ssam readchar(); 106*30107Ssam if (symchar(0)) { 107*30107Ssam readsym(); 108*30107Ssam if (lastc=='.') { 109*30107Ssam frame = pcb.pcb_fp; lastframe = 0; 110*30107Ssam callpc= pcb.pcb_pc; 111*30107Ssam while (errflg==0) { 112*30107Ssam savpc=callpc; 113*30107Ssam findsym(callpc,ISYM); 114*30107Ssam if (eqsym(cursym->n_un.n_name,isymbol,'~')) 115*30107Ssam break; 116*30107Ssam callpc=get(frame-8, DSP); 117*30107Ssam lastframe=frame; 118*30107Ssam frame=get(frame, DSP)&ALIGN; 119*30107Ssam if (frame==0) 120*30107Ssam error(NOCFN); 121*30107Ssam } 122*30107Ssam savlastf=lastframe; savframe=frame; 123*30107Ssam readchar(); 124*30107Ssam if (symchar(0)) 125*30107Ssam chkloc(expv=frame); 126*30107Ssam } else if ((symp=lookup(isymbol))==0) 127*30107Ssam error(BADSYM); 128*30107Ssam else 129*30107Ssam expv = symp->n_value; 130*30107Ssam lp--; 131*30107Ssam } else if (getnum()) 132*30107Ssam ; 133*30107Ssam else if (lastc=='.') { 134*30107Ssam readchar(); 135*30107Ssam if (symchar(0)) { 136*30107Ssam lastframe=savlastf; callpc=savpc; 137*30107Ssam chkloc(savframe); 138*30107Ssam } else 139*30107Ssam expv=dot; 140*30107Ssam lp--; 141*30107Ssam } else if (lastc=='"') 142*30107Ssam expv=ditto; 143*30107Ssam else if (lastc=='+') 144*30107Ssam expv=inkdot(dotinc); 145*30107Ssam else if (lastc=='^') 146*30107Ssam expv=inkdot(-dotinc); 147*30107Ssam else if (lastc=='<') { 148*30107Ssam savc=rdc(); 149*30107Ssam if ((regptr=getreg(savc)) != -1) 150*30107Ssam expv = *(int *)regptr; 151*30107Ssam else if ((base=varchk(savc)) != -1) 152*30107Ssam expv=var[base]; 153*30107Ssam else 154*30107Ssam error(BADVAR); 155*30107Ssam } else if (lastc=='\'') { 156*30107Ssam d=4; expv=0; 157*30107Ssam while (quotchar()) { 158*30107Ssam if (d--) { 159*30107Ssam expv <<= 8; 160*30107Ssam expv |= lastc; 161*30107Ssam } else 162*30107Ssam error(BADSYN); 163*30107Ssam } 164*30107Ssam } else if (a) 165*30107Ssam error(NOADR); 166*30107Ssam else { 167*30107Ssam lp--; 168*30107Ssam return(0); 169*30107Ssam } 170*30107Ssam return (1); 171*30107Ssam } 172*30107Ssam 173*30107Ssam /* service routines for expression reading */ 174*30107Ssam static 175*30107Ssam getnum() 176*30107Ssam { 177*30107Ssam register base,d,frpt; 178*30107Ssam union { float r; long i;} real; 179*30107Ssam 180*30107Ssam if (!isdigit(lastc)) 181*30107Ssam return (0); 182*30107Ssam if ((base = radix) < 0) 183*30107Ssam base = -base; 184*30107Ssam expv = 0; 185*30107Ssam while (base>10 ? isxdigit(lastc) : isdigit(lastc)) { 186*30107Ssam register m = MAXINT/base; 187*30107Ssam 188*30107Ssam if (expv>m) /* avoid overflow */ 189*30107Ssam expv = (expv-m)*base+m*base; 190*30107Ssam else 191*30107Ssam expv *= base; 192*30107Ssam if ((d=convdig(lastc))>=base || d<0) 193*30107Ssam error(BADSYN); 194*30107Ssam expv += d; readchar(); 195*30107Ssam if (expv==0) { 196*30107Ssam if (lastc=='x' || lastc=='X') { 197*30107Ssam base=16; readchar(); 198*30107Ssam } else if (lastc=='t' || lastc=='T') { 199*30107Ssam base=10; readchar(); 200*30107Ssam } else if (lastc=='o' || lastc=='O') { 201*30107Ssam base=8; readchar(); 202*30107Ssam } 203*30107Ssam } 204*30107Ssam } 205*30107Ssam if (lastc=='.' && (base==10 || expv==0)) { 206*30107Ssam real.r=expv; frpt=0; base=10; 207*30107Ssam while (isdigit(readchar())) { 208*30107Ssam real.r *= base; frpt++; 209*30107Ssam real.r += lastc-'0'; 210*30107Ssam } 211*30107Ssam while (frpt--) 212*30107Ssam real.r /= base; 213*30107Ssam expv = real.i; 214*30107Ssam } 215*30107Ssam peekc=lastc; 216*30107Ssam return (1); 217*30107Ssam } 218*30107Ssam 219*30107Ssam static 220*30107Ssam readsym() 221*30107Ssam { 222*30107Ssam register char *p; 223*30107Ssam 224*30107Ssam p = isymbol; 225*30107Ssam do { 226*30107Ssam if (p < &isymbol[sizeof(isymbol)-1]) 227*30107Ssam *p++ = lastc; 228*30107Ssam readchar(); 229*30107Ssam } while (symchar(1)); 230*30107Ssam *p++ = 0; 231*30107Ssam } 232*30107Ssam 233*30107Ssam static 234*30107Ssam convdig(c) 235*30107Ssam char c; 236*30107Ssam { 237*30107Ssam if (isdigit(c)) 238*30107Ssam return (c-'0'); 239*30107Ssam if (isxdigit(c)) 240*30107Ssam return (c-'a'+10); 241*30107Ssam return (-1); 242*30107Ssam } 243*30107Ssam 244*30107Ssam static 245*30107Ssam symchar(dig) 246*30107Ssam { 247*30107Ssam 248*30107Ssam if (lastc=='\\') { 249*30107Ssam readchar(); 250*30107Ssam return (TRUE); 251*30107Ssam } 252*30107Ssam return (isalpha(lastc) || lastc=='_' || dig && isdigit(lastc)); 253*30107Ssam } 254*30107Ssam 255*30107Ssam varchk(name) 256*30107Ssam register name; 257*30107Ssam { 258*30107Ssam if (isdigit(name)) 259*30107Ssam return (name-'0'); 260*30107Ssam if (isalpha(name)) 261*30107Ssam return ((name&037)-1+10); 262*30107Ssam return (-1); 263*30107Ssam } 264*30107Ssam 265*30107Ssam static 266*30107Ssam chkloc(frame) 267*30107Ssam long frame; 268*30107Ssam { 269*30107Ssam 270*30107Ssam readsym(); 271*30107Ssam do { 272*30107Ssam if (localsym(frame)==0) 273*30107Ssam error(BADLOC); 274*30107Ssam expv=localval; 275*30107Ssam } while (!eqsym(cursym->n_un.n_name,isymbol,'~')); 276*30107Ssam } 277*30107Ssam 278*30107Ssam eqsym(s1, s2, c) 279*30107Ssam register char *s1, *s2; 280*30107Ssam { 281*30107Ssam 282*30107Ssam if (streq(s1,s2)) 283*30107Ssam return (1); 284*30107Ssam if (*s1 == c && streq(s1+1, s2)) 285*30107Ssam return (1); 286*30107Ssam return (0); 287*30107Ssam } 288*30107Ssam 289*30107Ssam static 290*30107Ssam streq(s1, s2) 291*30107Ssam char *s1, *s2; 292*30107Ssam { 293*30107Ssam 294*30107Ssam while (*s1 == *s2++) 295*30107Ssam if (*s1++ == '\0') 296*30107Ssam return (1); 297*30107Ssam return (0); 298*30107Ssam } 299*30107Ssam 300*30107Ssam static 301*30107Ssam round(a,b) 302*30107Ssam register long a, b; 303*30107Ssam { 304*30107Ssam register long w; 305*30107Ssam 306*30107Ssam w = (a/b)*b; 307*30107Ssam if (a!=w) 308*30107Ssam w += b; 309*30107Ssam return (w); 310*30107Ssam } 311