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