|
|
1.1 root 1: /* C compiler & debugger: expression evaluation */
2:
3: #include "c.h"
4:
5: typedef struct {
6: Tree p; /* associated tree */
7: Value r; /* the register */
8: } Register;
9: static char *errcode; /* evaluation error string */
10: static int nextr;
11: static Register regs[30];
12:
13: dclproto(static Value *eval,(Tree))
14: dclproto(static Value *treereg,(Tree))
15:
16: /* evaluate - evaluate tree p */
17: Symbol evaluate(p) Tree p; {
18: static struct symbol sym;
19:
20: nextr = 1;
21: errcode = 0;
22: sym.u.c.v = *eval(p);
23: if (errcode)
24: return 0;
25: sym.type = p->type;
26: return &sym;
27: }
28:
29: /* eval - recursively evaluate tree p, return allocated register */
30: static Value *eval(p) Tree p; {
31: Value *r, *r1 = 0, *r2 = 0;
32: Tree left, right;
33:
34: if (r = treereg(p))
35: return r;
36: if (nextr > sizeof regs/sizeof regs[0]) {
37: error("expression too complicated\n");
38: return ®s[0].r;
39: }
40: regs[nextr].p = p;
41: r = ®s[nextr++].r;
42: switch (generic(p->op)) { /* control flow operators */
43: case AND:
44: r1 = eval(p->kids[0]);
45: if (r1->i)
46: r1 = eval(p->kids[1]);
47: r->i = r1->i;
48: return r;
49: case COND:
50: r = eval(p->kids[0]);
51: r1 = eval(p->kids[r->i ? 1 : 2]);
52: *r = *r1;
53: return r;
54: case NOT:
55: r1 = eval(p->kids[0]);
56: r->i = !r1->i;
57: return r;
58: case OR:
59: r1 = eval(p->kids[0]);
60: if (r1->i == 0)
61: r1 = eval(p->kids[1]);
62: r->i = r1->i;
63: return r;
64: }
65: if (left = p->kids[0])
66: r1 = eval(left);
67: if (right = p->kids[1])
68: r2 = eval(right);
69: switch (p->op) {
70: case ADD+D: r->d = r1->d + r2->d; break;
71: case ADD+F: r->f = r1->f + r2->f; break;
72: case ADD+I: r->i = r1->i + r2->i; break;
73: case ADD+P:
74: if (isptr(left->type))
75: r->s = r1->s + r2->i;
76: else
77: r->s = r1->i + r2->s;
78: break;
79: case ADD+U: r->u = r1->u + r2->u; break;
80: case ADDRF+P:
81: case ADDRG+P:
82: case ADDRL+P: goto bad;
83: case ARG+B:
84: case ARG+C:
85: case ARG+D:
86: case ARG+F:
87: case ARG+I:
88: case ARG+P:
89: case ARG+S: goto bad;
90: case ASGN+B:
91: case ASGN+C:
92: case ASGN+D:
93: case ASGN+F:
94: case ASGN+I:
95: case ASGN+P:
96: case ASGN+S: goto bad;
97: case BAND+I: r->i = r1->i&r2->i; break;
98: case BAND+U: r->u = r1->u&r2->u; break;
99: case BCOM+U: r->u = ~r1->u; break;
100: case BOR+I: r->i = r1->i|r2->i; break;
101: case BOR+U: r->u = r1->u|r2->u; break;
102: case BXOR+I: r->i = r1->i^r2->i; break;
103: case BXOR+U: r->u = r1->u^r2->u; break;
104: case CALL+B:
105: case CALL+D:
106: case CALL+F:
107: case CALL+I:
108: case CALL+V: goto bad;
109: case CNST+C:
110: case CNST+D:
111: case CNST+F:
112: case CNST+I:
113: case CNST+P:
114: case CNST+S:
115: case CNST+U: *r = p->u.v; break;
116: case CVC+I: r->i = r1->sc; break;
117: case CVC+U: r->u = r1->uc; break;
118: case CVD+F: r->f = r1->d; break;
119: case CVD+I: r->i = r1->d; break;
120: case CVD+U: r->u = r1->d; break;
121: case CVF+D: r->d = r1->f; break;
122: case CVI+C: r->sc = r1->i; break;
123: case CVI+D: r->d = r1->i; break;
124: case CVI+S: r->ss = r1->i; break;
125: case CVI+U: r->u = r1->i; break;
126: case CVP+U: r->u = (unsigned)r1->p; break;
127: case CVS+I: r->i = r1->ss; break;
128: case CVS+U: r->u = r1->us; break;
129: case CVU+C: r->uc = r1->u; break;
130: case CVU+D: r->d = r1->u; break;
131: case CVU+I: r->i = r1->u; break;
132: case CVU+P: r->p = (char *)r1->u; break;
133: case CVU+S: r->us = r1->u; break;
134: case DIV+D:
135: if (r2->d == 0.0)
136: errcode = "division by 0.0";
137: else
138: r->d = r1->d/r2->d;
139: break;
140: case DIV+F:
141: if (r2->f == 0.0)
142: errcode = "division by 0";
143: else
144: r->f = r1->f/r2->f;
145: break;
146: case DIV+I:
147: if (r2->i == 0)
148: errcode = "division by 0";
149: else
150: r->i = r1->i/r2->i;
151: break;
152: case DIV+U:
153: if (r2->u == 0)
154: errcode = "division by 0";
155: else
156: r->u = r1->u/r2->u;
157: break;
158: case EQ+D: r->i = r1->d == r2->d; break;
159: case EQ+F: r->i = r1->f == r2->f; break;
160: case EQ+I: r->i = r1->i == r2->i; break;
161: case EQ+U: r->i = r1->u == r2->u; break;
162: case FIELD: goto bad;
163: case GE+D: r->i = r1->d >= r2->d; break;
164: case GE+F: r->i = r1->f >= r2->f; break;
165: case GE+I: r->i = r1->i >= r2->i; break;
166: case GE+U: r->i = r1->u >= r2->u; break;
167: case GT+D: r->i = r1->d > r2->d; break;
168: case GT+F: r->i = r1->f > r2->f; break;
169: case GT+I: r->i = r1->i > r2->i; break;
170: case GT+U: r->i = r1->u > r2->u; break;
171: case INDIR+B:
172: case INDIR+C:
173: case INDIR+D:
174: case INDIR+F:
175: case INDIR+I:
176: case INDIR+P:
177: case INDIR+S: goto bad;
178: case JUMP+V:
179: fatal("eval", "unexpected %s operator\n", "JUMP+V");
180: case LE+D: r->i = r1->d <= r2->d; break;
181: case LE+F: r->i = r1->f <= r2->f; break;
182: case LE+I: r->i = r1->i <= r2->i; break;
183: case LE+U: r->i = r1->u <= r2->u; break;
184: case LSH+I: r->i = r1->i<<r2->i; break;
185: case LSH+U: r->u = r1->u<<r2->u; break;
186: case LT+D: r->i = r1->d < r2->d; break;
187: case LT+F: r->i = r1->f < r2->f; break;
188: case LT+I: r->i = r1->i < r2->i; break;
189: case LT+U: r->i = r1->u < r2->u; break;
190: case MOD+I:
191: if (r2->i == 0)
192: errcode = "division by 0";
193: else
194: r->i = r1->i%r2->i;
195: break;
196: case MOD+U:
197: if (r2->u == 0)
198: errcode = "division by 0";
199: else
200: r->u = r1->u%r2->u;
201: break;
202: case MUL+D: r->d = r1->d*r2->d; break;
203: case MUL+F: r->f = r1->f*r2->f; break;
204: case MUL+I: r->i = r1->i*r2->i; break;
205: case MUL+U: r->u = r1->u*r2->u; break;
206: case NE+D: r->i = r1->d != r2->d; break;
207: case NE+F: r->i = r1->f != r2->f; break;
208: case NE+I: r->i = r1->i != r2->i; break;
209: case NE+U: r->i = r1->u != r2->i; break;
210: case NEG+D: r->d = -r1->d; break;
211: case NEG+F: r->f = -r1->f; break;
212: case NEG+I: r->i = -r1->i; break;
213: case RET+B:
214: case RET+D:
215: case RET+F:
216: case RET+I:
217: case RET+V: goto bad;
218: case RIGHT: r->d = r2->d; break;
219: case RSH+I: r->i = r1->i>>r2->i; break;
220: case RSH+U: r->u = r1->u>>r2->u; break;
221: case SUB+D: r->d = r1->d - r2->d; break;
222: case SUB+F: r->f = r1->f - r2->f; break;
223: case SUB+I: r->i = r1->i - r2->i; break;
224: case SUB+P: r->i = r1->s - r2->s; break;
225: case SUB+U: r->u = r1->u - r2->u; break;
226: default: bad:
227: fatal("eval", "unknown operator %d\n", p->op);
228: }
229: return r;
230: }
231:
232: /* treereg - return register associated with tree p or 0 */
233: static Value *treereg(p) Tree p; {
234: int i;
235:
236: for (i = 0; i < nextr; i++)
237: if (regs[i].p == p)
238: return ®s[i].r;
239: return 0;
240: }
241:
242: /* vtoa - return string for the constant v of type ty */
243: char *vtoa(ty, v) Type ty; Value v; {
244: static char buf[MAXLINE];
245:
246: ty = unqual(ty);
247: switch (ty->op) {
248: case CHAR:
249: sprint(buf, "%d", v.uc);
250: break;
251: case SHORT:
252: sprint(buf, "%d", v.ss);
253: break;
254: case INT:
255: sprint(buf, "%d", v.i);
256: break;
257: case UNSIGNED:
258: if ((v.u&~0x7fff) == 0)
259: sprint(buf, "%d", v.u);
260: else
261: sprint(buf, "0x%x", v.u);
262: break;
263: case FLOAT:
264: if (v.f == 0.0)
265: return "0";
266: sprintf(buf, "%.*g", 8, v.f);
267: break;
268: case DOUBLE:
269: if (v.d == 0.0)
270: return "0";
271: sprintf(buf, "%.*g", 18, v.d);
272: break;
273: case ARRAY:
274: if (ty->type->op == CHAR)
275: return v.s;
276: /* else fall thru */
277: case POINTER: case FUNCTION:
278: if (((unsigned)v.p&~0x7fff) == 0)
279: sprint(buf, "%d", v.p);
280: else
281: sprint(buf, "0x%x", v.p);
282: break;
283: default:
284: assert(0);
285: }
286: return buf;
287: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.