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