1 /* kdb_expr.c 7.2 86/11/20 */ 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==0) { 112 savpc=callpc; 113 findsym(callpc,ISYM); 114 if (eqsym(cursym->n_un.n_name,isymbol,'~')) 115 break; 116 callpc=get(frame-8, DSP); 117 lastframe=frame; 118 frame=get(frame, DSP)&ALIGN; 119 if (frame==0) 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 } else if (getnum()) 132 ; 133 else if (lastc=='.') { 134 readchar(); 135 if (symchar(0)) { 136 lastframe=savlastf; callpc=savpc; 137 chkloc(savframe); 138 } else 139 expv=dot; 140 lp--; 141 } else if (lastc=='"') 142 expv=ditto; 143 else if (lastc=='+') 144 expv=inkdot(dotinc); 145 else if (lastc=='^') 146 expv=inkdot(-dotinc); 147 else if (lastc=='<') { 148 savc=rdc(); 149 if ((regptr=getreg(savc)) != -1) 150 expv = *(int *)regptr; 151 else if ((base=varchk(savc)) != -1) 152 expv=var[base]; 153 else 154 error(BADVAR); 155 } else if (lastc=='\'') { 156 d=4; expv=0; 157 while (quotchar()) { 158 if (d--) { 159 expv <<= 8; 160 expv |= lastc; 161 } else 162 error(BADSYN); 163 } 164 } else if (a) 165 error(NOADR); 166 else { 167 lp--; 168 return(0); 169 } 170 return (1); 171 } 172 173 /* service routines for expression reading */ 174 static 175 getnum() 176 { 177 register base,d,frpt; 178 union { float r; long i;} real; 179 180 if (!isdigit(lastc)) 181 return (0); 182 if ((base = radix) < 0) 183 base = -base; 184 expv = 0; 185 while (base>10 ? isxdigit(lastc) : isdigit(lastc)) { 186 register m = MAXINT/base; 187 188 if (expv>m) /* avoid overflow */ 189 expv = (expv-m)*base+m*base; 190 else 191 expv *= base; 192 if ((d=convdig(lastc))>=base || d<0) 193 error(BADSYN); 194 expv += d; readchar(); 195 if (expv==0) { 196 if (lastc=='x' || lastc=='X') { 197 base=16; readchar(); 198 } else if (lastc=='t' || lastc=='T') { 199 base=10; readchar(); 200 } else if (lastc=='o' || lastc=='O') { 201 base=8; readchar(); 202 } 203 } 204 } 205 if (lastc=='.' && (base==10 || expv==0)) { 206 real.r=expv; frpt=0; base=10; 207 while (isdigit(readchar())) { 208 real.r *= base; frpt++; 209 real.r += lastc-'0'; 210 } 211 while (frpt--) 212 real.r /= base; 213 expv = real.i; 214 } 215 peekc=lastc; 216 return (1); 217 } 218 219 static 220 readsym() 221 { 222 register char *p; 223 224 p = isymbol; 225 do { 226 if (p < &isymbol[sizeof(isymbol)-1]) 227 *p++ = lastc; 228 readchar(); 229 } while (symchar(1)); 230 *p++ = 0; 231 } 232 233 static 234 convdig(c) 235 char c; 236 { 237 if (isdigit(c)) 238 return (c-'0'); 239 if (isxdigit(c)) 240 return (c-'a'+10); 241 return (-1); 242 } 243 244 static 245 symchar(dig) 246 { 247 248 if (lastc=='\\') { 249 readchar(); 250 return (1); 251 } 252 return (isalpha(lastc) || lastc=='_' || dig && isdigit(lastc)); 253 } 254 255 varchk(name) 256 register name; 257 { 258 if (isdigit(name)) 259 return (name-'0'); 260 if (isalpha(name)) 261 return ((name&037)-1+10); 262 return (-1); 263 } 264 265 static 266 chkloc(frame) 267 long frame; 268 { 269 270 readsym(); 271 do { 272 if (localsym(frame)==0) 273 error(BADLOC); 274 expv=localval; 275 } while (!eqsym(cursym->n_un.n_name,isymbol,'~')); 276 } 277 278 eqsym(s1, s2, c) 279 register char *s1, *s2; 280 { 281 282 if (streq(s1,s2)) 283 return (1); 284 if (*s1 == c && streq(s1+1, s2)) 285 return (1); 286 return (0); 287 } 288 289 static 290 streq(s1, s2) 291 char *s1, *s2; 292 { 293 294 while (*s1 == *s2++) 295 if (*s1++ == '\0') 296 return (1); 297 return (0); 298 } 299 300 static 301 round(a,b) 302 register long a, b; 303 { 304 register long w; 305 306 w = (a/b)*b; 307 if (a!=w) 308 w += b; 309 return (w); 310 } 311