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