|
|
1.1 root 1: /*
2: * A debugger.
3: * Expression evaluator.
4: */
5: #include <stdio.h>
6: #include <ctype.h>
7: #include "trace.h"
8:
9: #define VALUE (-2) /* must be distinct from chars */
10: #define VILLEGAL (-3) /* ditto */
11: #define PRCFULL (0<<8) /* precedence wall for full expression */
12: #define PRECADD (1<<8) /* precedence of addops */
13: #define PRECMUL (2<<8) /* precedence of mulops */
14: #define PRIMARY (4<<8) /* precedence of primary expression */
15: #define tk_preced(op) ((op)&(~0<<8))
16: #define tk_char(op) ((op)&0377)
17:
18: /*
19: * Evaluate an expression list.
20: */
21: int
22: explist(vlist)
23: VAL vlist[VALSIZE];
24: {
25: register VAL *vp;
26: register int c, n;
27:
28: vp = vlist;
29: n = VALSIZE;
30: do {
31: if (expressn(vp, PRCFULL)<0)
32: return (0);
33: vp++;
34: --n;
35: } while ((c=getn()) == ',');
36: ungetn(c);
37: while (n--)
38: vp++->v_flag = VNULL;
39: return (1);
40: }
41:
42: /*
43: * Recursive expression reader;
44: * returns -1 for error, 0 for null expr, 1 for good expr.
45: */
46: int
47: expressn(left, wall)
48: register VAL *left;
49: int wall;
50: {
51: VAL v;
52: register VAL *right = &v;
53: int token, result;
54:
55: token = lextoken(left);
56: if (token==VALUE)
57: ;
58: else if (token==VILLEGAL)
59: return (-1);
60: else switch (tk_char(token)) {
61: case '~':
62: if (expressn(left, PRIMARY)<=0)
63: return (-1);
64: left->v_nval = ~left->v_nval;
65: break;
66: case '-':
67: if (expressn(left, PRIMARY)<=0)
68: return (-1);
69: left->v_nval = -left->v_nval;
70: break;
71: case '*':
72: if (expressn(left, PRIMARY)<=0)
73: return (-1);
74: add = left->v_nval;
75: getb(left->v_flag&VLVAL ? left->v_segn : 0,
76: &result, sizeof result);
77: left->v_nval = (long)(unsigned int)result;
78: left->v_flag = VLVAL;
79: left->v_segn = 0;
80: break;
81: case '(':
82: if (expressn(left, PRCFULL)<=0)
83: return (-1);
84: if ((token=lextoken(NULL))==')')
85: break;
86: else {
87: unlex(token);
88: printe("Missing ')'");
89: return (-1);
90: }
91: default:
92: unlex(token);
93: left->v_flag = VNULL;
94: return (0);
95: }
96: for (;;) {
97: token = lextoken(NULL);
98: if (tk_preced(token) <= wall) {
99: unlex(token);
100: return (1);
101: } else switch (tk_char(token)) {
102: case '*':
103: if ((result=expressn(right, PRECMUL))<=0)
104: break;
105: left->v_nval *= right->v_nval;
106: continue;
107: case '/':
108: if ((result=expressn(right, PRECMUL))<=0)
109: break;
110: left->v_nval /= right->v_nval;
111: continue;
112: case '+':
113: if ((result=expressn(right, PRECADD))<=0)
114: break;
115: left->v_nval += right->v_nval;
116: continue;
117: case '-':
118: if ((result=expressn(right, PRECADD))<=0)
119: break;
120: left->v_nval -= right->v_nval;
121: continue;
122: default:
123: unlex(token);
124: printe("Unimplemented operator");
125: return (-1);
126: }
127: if (result==0)
128: printe("Missing operand");
129: return (-1);
130: }
131: }
132:
133: /*
134: * Lex a token. If value, store in given val ptr.
135: */
136: int
137: lextoken(vp)
138: VAL *vp;
139: {
140: register int c;
141:
142: for (;;) switch (c=getn()) {
143: case ' ':
144: case '\t':
145: continue;
146: case '.':
147: if (vp==NULL) {
148: printe("Missing opr before '.'");
149: ungetn(c);
150: return (VILLEGAL);
151: }
152: vp->v_flag = VLVAL;
153: vp->v_segn = cseg;
154: vp->v_nval = dot;
155: return (VALUE);
156: /*
157: * only binary ops need be mentioned explicitly
158: * so precedences can be added
159: */
160: case '*':
161: case '/':
162: return (c|PRECMUL);
163: case '+':
164: case '-':
165: return (c|PRECADD);
166: default:
167: if ('0'<=c && c<='9' || c == '#')
168: return (readval(vp, c));
169: else if ('a'<=c && c<='z' || 'A'<=c && c<='Z' || c=='_')
170: return (readvar(vp, c));
171: else
172: return (c);
173: }
174: }
175: /*
176: * Push token back on input stream
177: */
178: unlex(c)
179: int c;
180: {
181: if (c!=VILLEGAL && c!=VALUE)
182: ungetn(tk_char(c));
183: }
184:
185: /*
186: * Read a number.
187: */
188: readval(vp, c)
189: VAL *vp;
190: register int c;
191: {
192: register unsigned long l = 0;
193: register int i, base = dbase;
194:
195: if (vp==NULL) {
196: printe("Missing opr before number");
197: ungetn(c);
198: return (VILLEGAL);
199: }
200: if (c=='0') {
201: if ((c=getn())=='x') {
202: base = 16;
203: } else {
204: ungetn(c);
205: if( c != '|')
206: base = 8;
207: }
208: }
209: else if( c == '#')
210: base = 10;
211: else
212: ungetn( c);
213: for (;;) {
214: if ((10<=(i=(c=getn())-('a'-10))
215: || 10<=(i=c-('A'-10))
216: || 0<=(i=c-'0') && i<=9
217: )&& i<base)
218: l = l*base + i;
219: #if FORZ8001
220: else if( c == '|') {
221: long seg;
222:
223: seg = l & 127;
224: l = 0;
225: for( ;;) {
226: if( ( 10 <= ( i = ( c = getn()) - ('a'-10))
227: || 10 <= ( i = c - ('A'-10))
228: || 0 <= ( i = c - '0') && i <= 9 )
229: && i < base)
230: l = l*base + i;
231: else
232: break;
233: }
234: l += seg << 24;
235: break;
236: }
237: #endif
238: else
239: break;
240: }
241: ungetn(c);
242: vp->v_flag = 0;
243: vp->v_nval = l;
244: return (VALUE);
245: }
246:
247: /*
248: * Read symbol and place value in given val struct
249: */
250: readvar(vp, c)
251: VAL *vp;
252: {
253: ungetn(c);
254: if (vp==NULL) {
255: printe("Missing opr before symbol");
256: return (VILLEGAL);
257: }
258: return (getsval(vp) ? VALUE : VILLEGAL);
259: }
260:
261: /*
262: * Given a value, return it's segment. If there is no segment associated
263: * with it, return `v'.
264: */
265: vsegno(vp, v)
266: register VAL *vp;
267: {
268: if ((vp->v_flag&VLVAL) == 0)
269: return (v);
270: return (vp->v_segn);
271: }
272:
273: /*
274: * Evaluate a value as an lvalue and return it. If the value is
275: * null, return `v'.
276: */
277: long
278: lvalue(vp, v)
279: register VAL *vp;
280: long v;
281: {
282: if (vp->v_flag&VNULL)
283: return (v);
284: return (vp->v_nval);
285: }
286:
287: /*
288: * Evaluate a value as an rvalue and return it. If the value is
289: * null, return `v'.
290: */
291: long
292: rvalue(vp, v)
293: register VAL *vp;
294: long v;
295: {
296: if (vp->v_flag&VNULL)
297: return (v);
298: return (vp->v_nval);
299: }
300:
301: /*
302: * If the given value is null, return 1, else 0.
303: */
304: nvalue(vp)
305: VAL *vp;
306: {
307: return (vp->v_flag&VNULL);
308: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.