|
|
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.5 (Berkeley) 5/29/89
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:
206: if (!isdigit(lastc))
207: return (0);
208: if ((base = radix) < 0)
209: base = -base;
210: expv = 0;
211: while (base>10 ? isxdigit(lastc) : isdigit(lastc)) {
212: register m = MAXINT/base;
213:
214: if (expv>m) /* avoid overflow */
215: expv = (expv-m)*base+m*base;
216: else
217: expv *= base;
218: if ((d=convdig(lastc))>=base || d<0)
219: error(BADSYN);
220: expv += d; (void) readchar();
221: if (expv==0) {
222: if (lastc=='x' || lastc=='X') {
223: base=16; (void) readchar();
224: } else if (lastc=='t' || lastc=='T') {
225: base=10; (void) readchar();
226: } else if (lastc=='o' || lastc=='O') {
227: base=8; (void) readchar();
228: }
229: }
230: }
231: if (lastc=='.' && (base==10 || expv==0)) {
232: frpt=0; base=10;
233: while (isdigit(readchar())) {
234: if (frpt)
235: continue;
236: frpt++;
237: if (lastc - '0' >= 5)
238: expv++;
239: }
240: }
241: peekc=lastc;
242: return (1);
243: }
244:
245: static
246: readsym()
247: {
248: register char *p;
249:
250: p = isymbol;
251: do {
252: if (p < &isymbol[sizeof(isymbol)-1])
253: *p++ = lastc;
254: (void) readchar();
255: } while (symchar(1));
256: *p++ = 0;
257: }
258:
259: static
260: convdig(c)
261: char c;
262: {
263: if (isdigit(c))
264: return (c-'0');
265: if (isxdigit(c))
266: return (c-'a'+10);
267: return (-1);
268: }
269:
270: static
271: symchar(dig)
272: {
273:
274: if (lastc=='\\') {
275: (void) readchar();
276: return (1);
277: }
278: return (isalpha(lastc) || lastc=='_' || dig && isdigit(lastc));
279: }
280:
281: varchk(name)
282: register name;
283: {
284: if (isdigit(name))
285: return (name-'0');
286: if (isalpha(name))
287: return ((name&037)-1+10);
288: return (-1);
289: }
290:
291: static
292: chkloc(frame)
293: long frame;
294: {
295:
296: readsym();
297: do {
298: if (localsym(frame)==0)
299: error(BADLOC);
300: expv=localval;
301: } while (!eqsym(cursym->n_un.n_name,isymbol,'~'));
302: }
303:
304: eqsym(s1, s2, c)
305: register char *s1, *s2;
306: {
307:
308: if (streq(s1,s2))
309: return (1);
310: if (*s1 == c && streq(s1+1, s2))
311: return (1);
312: return (0);
313: }
314:
315: static
316: streq(s1, s2)
317: char *s1, *s2;
318: {
319:
320: while (*s1 == *s2++)
321: if (*s1++ == '\0')
322: return (1);
323: return (0);
324: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.