1bd389b36SDavid du Colombier #include <u.h>
2bd389b36SDavid du Colombier #include <libc.h>
3bd389b36SDavid du Colombier #include <bio.h>
4bd389b36SDavid du Colombier #include <ctype.h>
5bd389b36SDavid du Colombier #include <mach.h>
6bd389b36SDavid du Colombier #define Extern extern
7bd389b36SDavid du Colombier #include "acid.h"
8bd389b36SDavid du Colombier
9219b2ee8SDavid du Colombier static int fsize[] =
10bd389b36SDavid du Colombier {
117dd7cddfSDavid du Colombier ['A'] 4,
127dd7cddfSDavid du Colombier ['B'] 4,
13bd389b36SDavid du Colombier ['C'] 1,
14bd389b36SDavid du Colombier ['D'] 4,
15219b2ee8SDavid du Colombier ['F'] 8,
16219b2ee8SDavid du Colombier ['G'] 8,
17bd389b36SDavid du Colombier ['O'] 4,
18bd389b36SDavid du Colombier ['Q'] 4,
19219b2ee8SDavid du Colombier ['R'] 4,
20219b2ee8SDavid du Colombier ['S'] 4,
21219b2ee8SDavid du Colombier ['U'] 4,
227dd7cddfSDavid du Colombier ['V'] 8,
231bd28109SDavid du Colombier ['W'] 8,
24219b2ee8SDavid du Colombier ['X'] 4,
257dd7cddfSDavid du Colombier ['Y'] 8,
267dd7cddfSDavid du Colombier ['Z'] 8,
27219b2ee8SDavid du Colombier ['a'] 4,
28219b2ee8SDavid du Colombier ['b'] 1,
29219b2ee8SDavid du Colombier ['c'] 1,
30219b2ee8SDavid du Colombier ['d'] 2,
31219b2ee8SDavid du Colombier ['f'] 4,
32219b2ee8SDavid du Colombier ['g'] 4,
33219b2ee8SDavid du Colombier ['o'] 2,
34219b2ee8SDavid du Colombier ['q'] 2,
35bd389b36SDavid du Colombier ['r'] 2,
36219b2ee8SDavid du Colombier ['s'] 4,
37219b2ee8SDavid du Colombier ['u'] 2,
38219b2ee8SDavid du Colombier ['x'] 2,
3937e88e97SDavid du Colombier ['3'] 10,
4037e88e97SDavid du Colombier ['8'] 10,
41bd389b36SDavid du Colombier };
42bd389b36SDavid du Colombier
43bd389b36SDavid du Colombier int
fmtsize(Value * v)44bd389b36SDavid du Colombier fmtsize(Value *v)
45bd389b36SDavid du Colombier {
46219b2ee8SDavid du Colombier int ret;
47219b2ee8SDavid du Colombier
48bd389b36SDavid du Colombier switch(v->fmt) {
49bd389b36SDavid du Colombier default:
50bd389b36SDavid du Colombier return fsize[v->fmt];
51bd389b36SDavid du Colombier case 'i':
52bd389b36SDavid du Colombier case 'I':
53219b2ee8SDavid du Colombier if(v->type != TINT || machdata == 0)
54bd389b36SDavid du Colombier error("no size for i fmt pointer ++/--");
55219b2ee8SDavid du Colombier ret = (*machdata->instsize)(cormap, v->ival);
56219b2ee8SDavid du Colombier if(ret < 0) {
57219b2ee8SDavid du Colombier ret = (*machdata->instsize)(symmap, v->ival);
58219b2ee8SDavid du Colombier if(ret < 0)
59219b2ee8SDavid du Colombier error("%r");
60219b2ee8SDavid du Colombier }
61219b2ee8SDavid du Colombier return ret;
62bd389b36SDavid du Colombier }
63bd389b36SDavid du Colombier }
64bd389b36SDavid du Colombier
65bd389b36SDavid du Colombier void
chklval(Node * lp)66bd389b36SDavid du Colombier chklval(Node *lp)
67bd389b36SDavid du Colombier {
68bd389b36SDavid du Colombier if(lp->op != ONAME)
69bd389b36SDavid du Colombier error("need l-value");
70bd389b36SDavid du Colombier }
71bd389b36SDavid du Colombier
72bd389b36SDavid du Colombier void
olist(Node * n,Node * res)73219b2ee8SDavid du Colombier olist(Node *n, Node *res)
74219b2ee8SDavid du Colombier {
75219b2ee8SDavid du Colombier expr(n->left, res);
76219b2ee8SDavid du Colombier expr(n->right, res);
77219b2ee8SDavid du Colombier }
78219b2ee8SDavid du Colombier
79219b2ee8SDavid du Colombier void
oeval(Node * n,Node * res)80219b2ee8SDavid du Colombier oeval(Node *n, Node *res)
81219b2ee8SDavid du Colombier {
82219b2ee8SDavid du Colombier expr(n->left, res);
83219b2ee8SDavid du Colombier if(res->type != TCODE)
84219b2ee8SDavid du Colombier error("bad type for eval");
85219b2ee8SDavid du Colombier expr(res->cc, res);
86219b2ee8SDavid du Colombier }
87219b2ee8SDavid du Colombier
88219b2ee8SDavid du Colombier void
ocast(Node * n,Node * res)89219b2ee8SDavid du Colombier ocast(Node *n, Node *res)
90219b2ee8SDavid du Colombier {
91219b2ee8SDavid du Colombier if(n->sym->lt == 0)
92219b2ee8SDavid du Colombier error("%s is not a complex type", n->sym->name);
93219b2ee8SDavid du Colombier
94219b2ee8SDavid du Colombier expr(n->left, res);
95219b2ee8SDavid du Colombier res->comt = n->sym->lt;
96219b2ee8SDavid du Colombier res->fmt = 'a';
97219b2ee8SDavid du Colombier }
98219b2ee8SDavid du Colombier
99219b2ee8SDavid du Colombier void
oindm(Node * n,Node * res)100219b2ee8SDavid du Colombier oindm(Node *n, Node *res)
101bd389b36SDavid du Colombier {
102bd389b36SDavid du Colombier Map *m;
103219b2ee8SDavid du Colombier Node l;
104bd389b36SDavid du Colombier
105bd389b36SDavid du Colombier m = cormap;
106bd389b36SDavid du Colombier if(m == 0)
107219b2ee8SDavid du Colombier m = symmap;
108219b2ee8SDavid du Colombier expr(n->left, &l);
109219b2ee8SDavid du Colombier if(l.type != TINT)
110219b2ee8SDavid du Colombier error("bad type for *");
111219b2ee8SDavid du Colombier if(m == 0)
112219b2ee8SDavid du Colombier error("no map for *");
113bd389b36SDavid du Colombier indir(m, l.ival, l.fmt, res);
114bd389b36SDavid du Colombier res->comt = l.comt;
115219b2ee8SDavid du Colombier }
116219b2ee8SDavid du Colombier
117219b2ee8SDavid du Colombier void
oindc(Node * n,Node * res)118219b2ee8SDavid du Colombier oindc(Node *n, Node *res)
119219b2ee8SDavid du Colombier {
120219b2ee8SDavid du Colombier Map *m;
121219b2ee8SDavid du Colombier Node l;
122219b2ee8SDavid du Colombier
123219b2ee8SDavid du Colombier m = symmap;
124219b2ee8SDavid du Colombier if(m == 0)
125219b2ee8SDavid du Colombier m = cormap;
126219b2ee8SDavid du Colombier expr(n->left, &l);
127219b2ee8SDavid du Colombier if(l.type != TINT)
128219b2ee8SDavid du Colombier error("bad type for @");
129219b2ee8SDavid du Colombier if(m == 0)
130219b2ee8SDavid du Colombier error("no map for @");
131219b2ee8SDavid du Colombier indir(m, l.ival, l.fmt, res);
132219b2ee8SDavid du Colombier res->comt = l.comt;
133219b2ee8SDavid du Colombier }
134219b2ee8SDavid du Colombier
135219b2ee8SDavid du Colombier void
oframe(Node * n,Node * res)136219b2ee8SDavid du Colombier oframe(Node *n, Node *res)
137219b2ee8SDavid du Colombier {
138219b2ee8SDavid du Colombier char *p;
139219b2ee8SDavid du Colombier Node *lp;
1404de34a7eSDavid du Colombier uvlong ival;
141219b2ee8SDavid du Colombier Frtype *f;
142219b2ee8SDavid du Colombier
143219b2ee8SDavid du Colombier p = n->sym->name;
144219b2ee8SDavid du Colombier while(*p && *p == '$')
145219b2ee8SDavid du Colombier p++;
146219b2ee8SDavid du Colombier lp = n->left;
147219b2ee8SDavid du Colombier if(localaddr(cormap, p, lp->sym->name, &ival, rget) < 0)
148219b2ee8SDavid du Colombier error("colon: %r");
149219b2ee8SDavid du Colombier
150219b2ee8SDavid du Colombier res->ival = ival;
151219b2ee8SDavid du Colombier res->op = OCONST;
152219b2ee8SDavid du Colombier res->fmt = 'X';
153219b2ee8SDavid du Colombier res->type = TINT;
154219b2ee8SDavid du Colombier
155219b2ee8SDavid du Colombier /* Try and set comt */
156219b2ee8SDavid du Colombier for(f = n->sym->local; f; f = f->next) {
157219b2ee8SDavid du Colombier if(f->var == lp->sym) {
158219b2ee8SDavid du Colombier res->comt = f->type;
159219b2ee8SDavid du Colombier res->fmt = 'a';
160bd389b36SDavid du Colombier break;
161219b2ee8SDavid du Colombier }
162219b2ee8SDavid du Colombier }
163219b2ee8SDavid du Colombier }
164219b2ee8SDavid du Colombier
165219b2ee8SDavid du Colombier void
oindex(Node * n,Node * res)166219b2ee8SDavid du Colombier oindex(Node *n, Node *res)
167219b2ee8SDavid du Colombier {
168219b2ee8SDavid du Colombier Node l, r;
169219b2ee8SDavid du Colombier
170219b2ee8SDavid du Colombier expr(n->left, &l);
171219b2ee8SDavid du Colombier expr(n->right, &r);
172219b2ee8SDavid du Colombier
173bd389b36SDavid du Colombier if(r.type != TINT)
174bd389b36SDavid du Colombier error("bad type for []");
175219b2ee8SDavid du Colombier
176bd389b36SDavid du Colombier switch(l.type) {
177bd389b36SDavid du Colombier default:
178bd389b36SDavid du Colombier error("lhs[] has bad type");
179bd389b36SDavid du Colombier case TINT:
180219b2ee8SDavid du Colombier indir(cormap, l.ival+(r.ival*fsize[l.fmt]), l.fmt, res);
181219b2ee8SDavid du Colombier res->comt = l.comt;
182219b2ee8SDavid du Colombier res->fmt = l.fmt;
183bd389b36SDavid du Colombier break;
184bd389b36SDavid du Colombier case TLIST:
185bd389b36SDavid du Colombier nthelem(l.l, r.ival, res);
186bd389b36SDavid du Colombier break;
187bd389b36SDavid du Colombier case TSTRING:
188bd389b36SDavid du Colombier res->ival = 0;
189219b2ee8SDavid du Colombier if(r.ival >= 0 && r.ival < l.string->len) {
190219b2ee8SDavid du Colombier int xx8; /* to get around bug in vc */
191219b2ee8SDavid du Colombier xx8 = r.ival;
192219b2ee8SDavid du Colombier res->ival = l.string->string[xx8];
193219b2ee8SDavid du Colombier }
194bd389b36SDavid du Colombier res->op = OCONST;
195bd389b36SDavid du Colombier res->type = TINT;
196bd389b36SDavid du Colombier res->fmt = 'c';
197bd389b36SDavid du Colombier break;
198bd389b36SDavid du Colombier }
199219b2ee8SDavid du Colombier }
200219b2ee8SDavid du Colombier
201219b2ee8SDavid du Colombier void
oappend(Node * n,Node * res)202219b2ee8SDavid du Colombier oappend(Node *n, Node *res)
203219b2ee8SDavid du Colombier {
2047c70c028SDavid du Colombier Value *v;
205219b2ee8SDavid du Colombier Node r, l;
2067c70c028SDavid du Colombier int empty;
207219b2ee8SDavid du Colombier
208219b2ee8SDavid du Colombier expr(n->left, &l);
209219b2ee8SDavid du Colombier expr(n->right, &r);
210bd389b36SDavid du Colombier if(l.type != TLIST)
211bd389b36SDavid du Colombier error("must append to list");
2127c70c028SDavid du Colombier empty = (l.l == nil && (n->left->op == ONAME));
213bd389b36SDavid du Colombier append(res, &l, &r);
2147c70c028SDavid du Colombier if(empty) {
2157c70c028SDavid du Colombier v = n->left->sym->v;
2167c70c028SDavid du Colombier v->type = res->type;
2177c70c028SDavid du Colombier v->Store = res->Store;
2187c70c028SDavid du Colombier v->comt = res->comt;
2197c70c028SDavid du Colombier }
220219b2ee8SDavid du Colombier }
221219b2ee8SDavid du Colombier
222219b2ee8SDavid du Colombier void
odelete(Node * n,Node * res)223219b2ee8SDavid du Colombier odelete(Node *n, Node *res)
224219b2ee8SDavid du Colombier {
225219b2ee8SDavid du Colombier Node l, r;
226219b2ee8SDavid du Colombier
227219b2ee8SDavid du Colombier expr(n->left, &l);
228219b2ee8SDavid du Colombier expr(n->right, &r);
229bd389b36SDavid du Colombier if(l.type != TLIST)
230bd389b36SDavid du Colombier error("must delete from list");
231bd389b36SDavid du Colombier if(r.type != TINT)
232bd389b36SDavid du Colombier error("delete index must be integer");
233bd389b36SDavid du Colombier
234bd389b36SDavid du Colombier delete(l.l, r.ival, res);
235219b2ee8SDavid du Colombier }
236219b2ee8SDavid du Colombier
237219b2ee8SDavid du Colombier void
ohead(Node * n,Node * res)238219b2ee8SDavid du Colombier ohead(Node *n, Node *res)
239219b2ee8SDavid du Colombier {
240219b2ee8SDavid du Colombier Node l;
241219b2ee8SDavid du Colombier
242219b2ee8SDavid du Colombier expr(n->left, &l);
243bd389b36SDavid du Colombier if(l.type != TLIST)
244bd389b36SDavid du Colombier error("head needs list");
245bd389b36SDavid du Colombier res->op = OCONST;
246bd389b36SDavid du Colombier if(l.l) {
247bd389b36SDavid du Colombier res->type = l.l->type;
248bd389b36SDavid du Colombier res->Store = l.l->Store;
249bd389b36SDavid du Colombier }
250bd389b36SDavid du Colombier else {
251bd389b36SDavid du Colombier res->type = TLIST;
252bd389b36SDavid du Colombier res->l = 0;
253bd389b36SDavid du Colombier }
254219b2ee8SDavid du Colombier }
255219b2ee8SDavid du Colombier
256219b2ee8SDavid du Colombier void
otail(Node * n,Node * res)257219b2ee8SDavid du Colombier otail(Node *n, Node *res)
258219b2ee8SDavid du Colombier {
259219b2ee8SDavid du Colombier Node l;
260219b2ee8SDavid du Colombier
261219b2ee8SDavid du Colombier expr(n->left, &l);
262bd389b36SDavid du Colombier if(l.type != TLIST)
263bd389b36SDavid du Colombier error("tail needs list");
264bd389b36SDavid du Colombier res->op = OCONST;
265bd389b36SDavid du Colombier res->type = TLIST;
266bd389b36SDavid du Colombier if(l.l)
267219b2ee8SDavid du Colombier res->l = l.l->next;
268bd389b36SDavid du Colombier else
269219b2ee8SDavid du Colombier res->l = 0;
270219b2ee8SDavid du Colombier }
271219b2ee8SDavid du Colombier
272219b2ee8SDavid du Colombier void
oconst(Node * n,Node * res)273219b2ee8SDavid du Colombier oconst(Node *n, Node *res)
274219b2ee8SDavid du Colombier {
275219b2ee8SDavid du Colombier res->op = OCONST;
276219b2ee8SDavid du Colombier res->type = n->type;
277219b2ee8SDavid du Colombier res->Store = n->Store;
278219b2ee8SDavid du Colombier res->comt = n->comt;
279219b2ee8SDavid du Colombier }
280219b2ee8SDavid du Colombier
281219b2ee8SDavid du Colombier void
oname(Node * n,Node * res)282219b2ee8SDavid du Colombier oname(Node *n, Node *res)
283219b2ee8SDavid du Colombier {
284219b2ee8SDavid du Colombier Value *v;
285219b2ee8SDavid du Colombier
286bd389b36SDavid du Colombier v = n->sym->v;
287bd389b36SDavid du Colombier if(v->set == 0)
288bd389b36SDavid du Colombier error("%s used but not set", n->sym->name);
289bd389b36SDavid du Colombier res->op = OCONST;
290bd389b36SDavid du Colombier res->type = v->type;
291bd389b36SDavid du Colombier res->Store = v->Store;
292219b2ee8SDavid du Colombier res->comt = v->comt;
293219b2ee8SDavid du Colombier }
294219b2ee8SDavid du Colombier
295219b2ee8SDavid du Colombier void
octruct(Node * n,Node * res)296219b2ee8SDavid du Colombier octruct(Node *n, Node *res)
297219b2ee8SDavid du Colombier {
298bd389b36SDavid du Colombier res->op = OCONST;
299bd389b36SDavid du Colombier res->type = TLIST;
300219b2ee8SDavid du Colombier res->l = construct(n->left);
301219b2ee8SDavid du Colombier }
302219b2ee8SDavid du Colombier
303219b2ee8SDavid du Colombier void
oasgn(Node * n,Node * res)304219b2ee8SDavid du Colombier oasgn(Node *n, Node *res)
305219b2ee8SDavid du Colombier {
306219b2ee8SDavid du Colombier Node *lp, r;
307219b2ee8SDavid du Colombier Value *v;
308219b2ee8SDavid du Colombier
309219b2ee8SDavid du Colombier lp = n->left;
310bd389b36SDavid du Colombier switch(lp->op) {
311bd389b36SDavid du Colombier case OINDM:
312219b2ee8SDavid du Colombier windir(cormap, lp->left, n->right, res);
313bd389b36SDavid du Colombier break;
314bd389b36SDavid du Colombier case OINDC:
315219b2ee8SDavid du Colombier windir(symmap, lp->left, n->right, res);
316bd389b36SDavid du Colombier break;
317bd389b36SDavid du Colombier default:
318bd389b36SDavid du Colombier chklval(lp);
319bd389b36SDavid du Colombier v = lp->sym->v;
320219b2ee8SDavid du Colombier expr(n->right, &r);
321bd389b36SDavid du Colombier v->set = 1;
322bd389b36SDavid du Colombier v->type = r.type;
323bd389b36SDavid du Colombier v->Store = r.Store;
324219b2ee8SDavid du Colombier res->op = OCONST;
325219b2ee8SDavid du Colombier res->type = v->type;
326219b2ee8SDavid du Colombier res->Store = v->Store;
327219b2ee8SDavid du Colombier res->comt = v->comt;
328bd389b36SDavid du Colombier }
329219b2ee8SDavid du Colombier }
330219b2ee8SDavid du Colombier
331219b2ee8SDavid du Colombier void
oadd(Node * n,Node * res)332219b2ee8SDavid du Colombier oadd(Node *n, Node *res)
333219b2ee8SDavid du Colombier {
334219b2ee8SDavid du Colombier Node l, r;
335219b2ee8SDavid du Colombier
3366f222ee0SDavid du Colombier if(n->right == nil){ /* unary + */
3376f222ee0SDavid du Colombier expr(n->left, res);
3386f222ee0SDavid du Colombier return;
3396f222ee0SDavid du Colombier }
340219b2ee8SDavid du Colombier expr(n->left, &l);
341219b2ee8SDavid du Colombier expr(n->right, &r);
342bd389b36SDavid du Colombier res->fmt = l.fmt;
343bd389b36SDavid du Colombier res->op = OCONST;
344bd389b36SDavid du Colombier res->type = TFLOAT;
345bd389b36SDavid du Colombier switch(l.type) {
346219b2ee8SDavid du Colombier default:
347219b2ee8SDavid du Colombier error("bad lhs type +");
348bd389b36SDavid du Colombier case TINT:
349bd389b36SDavid du Colombier switch(r.type) {
350bd389b36SDavid du Colombier case TINT:
351bd389b36SDavid du Colombier res->type = TINT;
352bd389b36SDavid du Colombier res->ival = l.ival+r.ival;
353bd389b36SDavid du Colombier break;
354bd389b36SDavid du Colombier case TFLOAT:
355bd389b36SDavid du Colombier res->fval = l.ival+r.fval;
356bd389b36SDavid du Colombier break;
357219b2ee8SDavid du Colombier default:
358219b2ee8SDavid du Colombier error("bad rhs type +");
359bd389b36SDavid du Colombier }
360bd389b36SDavid du Colombier break;
361bd389b36SDavid du Colombier case TFLOAT:
362bd389b36SDavid du Colombier switch(r.type) {
363bd389b36SDavid du Colombier case TINT:
364bd389b36SDavid du Colombier res->fval = l.fval+r.ival;
365bd389b36SDavid du Colombier break;
366bd389b36SDavid du Colombier case TFLOAT:
367bd389b36SDavid du Colombier res->fval = l.fval+r.fval;
368bd389b36SDavid du Colombier break;
369219b2ee8SDavid du Colombier default:
370219b2ee8SDavid du Colombier error("bad rhs type +");
371bd389b36SDavid du Colombier }
372bd389b36SDavid du Colombier break;
373bd389b36SDavid du Colombier case TSTRING:
374bd389b36SDavid du Colombier if(r.type == TSTRING) {
375bd389b36SDavid du Colombier res->type = TSTRING;
376bd389b36SDavid du Colombier res->fmt = 's';
377bd389b36SDavid du Colombier res->string = stradd(l.string, r.string);
378bd389b36SDavid du Colombier break;
379bd389b36SDavid du Colombier }
380ab3dc52fSDavid du Colombier if(r.type == TINT) {
381ab3dc52fSDavid du Colombier res->type = TSTRING;
382ab3dc52fSDavid du Colombier res->fmt = 's';
383ab3dc52fSDavid du Colombier res->string = straddrune(l.string, r.ival);
384ab3dc52fSDavid du Colombier break;
385ab3dc52fSDavid du Colombier }
386bd389b36SDavid du Colombier error("bad rhs for +");
387bd389b36SDavid du Colombier case TLIST:
388bd389b36SDavid du Colombier res->type = TLIST;
389bd389b36SDavid du Colombier switch(r.type) {
390bd389b36SDavid du Colombier case TLIST:
391bd389b36SDavid du Colombier res->l = addlist(l.l, r.l);
392bd389b36SDavid du Colombier break;
393bd389b36SDavid du Colombier default:
394bd389b36SDavid du Colombier r.left = 0;
395bd389b36SDavid du Colombier r.right = 0;
396bd389b36SDavid du Colombier res->l = addlist(l.l, construct(&r));
397bd389b36SDavid du Colombier break;
398bd389b36SDavid du Colombier }
399bd389b36SDavid du Colombier }
400219b2ee8SDavid du Colombier }
401219b2ee8SDavid du Colombier
402219b2ee8SDavid du Colombier void
osub(Node * n,Node * res)403219b2ee8SDavid du Colombier osub(Node *n, Node *res)
404219b2ee8SDavid du Colombier {
405219b2ee8SDavid du Colombier Node l, r;
406219b2ee8SDavid du Colombier
407219b2ee8SDavid du Colombier expr(n->left, &l);
408219b2ee8SDavid du Colombier expr(n->right, &r);
409bd389b36SDavid du Colombier res->fmt = l.fmt;
410bd389b36SDavid du Colombier res->op = OCONST;
411bd389b36SDavid du Colombier res->type = TFLOAT;
412bd389b36SDavid du Colombier switch(l.type) {
413219b2ee8SDavid du Colombier default:
414219b2ee8SDavid du Colombier error("bad lhs type -");
415bd389b36SDavid du Colombier case TINT:
416bd389b36SDavid du Colombier switch(r.type) {
417bd389b36SDavid du Colombier case TINT:
418bd389b36SDavid du Colombier res->type = TINT;
419bd389b36SDavid du Colombier res->ival = l.ival-r.ival;
420bd389b36SDavid du Colombier break;
421bd389b36SDavid du Colombier case TFLOAT:
422bd389b36SDavid du Colombier res->fval = l.ival-r.fval;
423bd389b36SDavid du Colombier break;
424219b2ee8SDavid du Colombier default:
425219b2ee8SDavid du Colombier error("bad rhs type -");
426bd389b36SDavid du Colombier }
427bd389b36SDavid du Colombier break;
428bd389b36SDavid du Colombier case TFLOAT:
429219b2ee8SDavid du Colombier switch(r.type) {
430bd389b36SDavid du Colombier case TINT:
431bd389b36SDavid du Colombier res->fval = l.fval-r.ival;
432bd389b36SDavid du Colombier break;
433bd389b36SDavid du Colombier case TFLOAT:
434bd389b36SDavid du Colombier res->fval = l.fval-r.fval;
435bd389b36SDavid du Colombier break;
436219b2ee8SDavid du Colombier default:
437219b2ee8SDavid du Colombier error("bad rhs type -");
438bd389b36SDavid du Colombier }
439bd389b36SDavid du Colombier break;
440bd389b36SDavid du Colombier }
441219b2ee8SDavid du Colombier }
442219b2ee8SDavid du Colombier
443219b2ee8SDavid du Colombier void
omul(Node * n,Node * res)444219b2ee8SDavid du Colombier omul(Node *n, Node *res)
445219b2ee8SDavid du Colombier {
446219b2ee8SDavid du Colombier Node l, r;
447219b2ee8SDavid du Colombier
448219b2ee8SDavid du Colombier expr(n->left, &l);
449219b2ee8SDavid du Colombier expr(n->right, &r);
450bd389b36SDavid du Colombier res->fmt = l.fmt;
451bd389b36SDavid du Colombier res->op = OCONST;
452bd389b36SDavid du Colombier res->type = TFLOAT;
453bd389b36SDavid du Colombier switch(l.type) {
454219b2ee8SDavid du Colombier default:
455219b2ee8SDavid du Colombier error("bad lhs type *");
456bd389b36SDavid du Colombier case TINT:
457bd389b36SDavid du Colombier switch(r.type) {
458bd389b36SDavid du Colombier case TINT:
459bd389b36SDavid du Colombier res->type = TINT;
460bd389b36SDavid du Colombier res->ival = l.ival*r.ival;
461bd389b36SDavid du Colombier break;
462bd389b36SDavid du Colombier case TFLOAT:
463bd389b36SDavid du Colombier res->fval = l.ival*r.fval;
464bd389b36SDavid du Colombier break;
465219b2ee8SDavid du Colombier default:
466219b2ee8SDavid du Colombier error("bad rhs type *");
467bd389b36SDavid du Colombier }
468bd389b36SDavid du Colombier break;
469bd389b36SDavid du Colombier case TFLOAT:
470219b2ee8SDavid du Colombier switch(r.type) {
471bd389b36SDavid du Colombier case TINT:
472bd389b36SDavid du Colombier res->fval = l.fval*r.ival;
473bd389b36SDavid du Colombier break;
474bd389b36SDavid du Colombier case TFLOAT:
475bd389b36SDavid du Colombier res->fval = l.fval*r.fval;
476bd389b36SDavid du Colombier break;
477219b2ee8SDavid du Colombier default:
478219b2ee8SDavid du Colombier error("bad rhs type *");
479bd389b36SDavid du Colombier }
480bd389b36SDavid du Colombier break;
481bd389b36SDavid du Colombier }
482219b2ee8SDavid du Colombier }
483219b2ee8SDavid du Colombier
484219b2ee8SDavid du Colombier void
odiv(Node * n,Node * res)485219b2ee8SDavid du Colombier odiv(Node *n, Node *res)
486219b2ee8SDavid du Colombier {
487219b2ee8SDavid du Colombier Node l, r;
488219b2ee8SDavid du Colombier
489219b2ee8SDavid du Colombier expr(n->left, &l);
490219b2ee8SDavid du Colombier expr(n->right, &r);
491bd389b36SDavid du Colombier res->fmt = l.fmt;
492bd389b36SDavid du Colombier res->op = OCONST;
493bd389b36SDavid du Colombier res->type = TFLOAT;
494bd389b36SDavid du Colombier switch(l.type) {
495219b2ee8SDavid du Colombier default:
496219b2ee8SDavid du Colombier error("bad lhs type /");
497bd389b36SDavid du Colombier case TINT:
498bd389b36SDavid du Colombier switch(r.type) {
499bd389b36SDavid du Colombier case TINT:
500bd389b36SDavid du Colombier res->type = TINT;
501219b2ee8SDavid du Colombier if(r.ival == 0)
502219b2ee8SDavid du Colombier error("zero divide");
503bd389b36SDavid du Colombier res->ival = l.ival/r.ival;
504bd389b36SDavid du Colombier break;
505bd389b36SDavid du Colombier case TFLOAT:
506219b2ee8SDavid du Colombier if(r.fval == 0)
507219b2ee8SDavid du Colombier error("zero divide");
508bd389b36SDavid du Colombier res->fval = l.ival/r.fval;
509bd389b36SDavid du Colombier break;
510219b2ee8SDavid du Colombier default:
511219b2ee8SDavid du Colombier error("bad rhs type /");
512bd389b36SDavid du Colombier }
513bd389b36SDavid du Colombier break;
514bd389b36SDavid du Colombier case TFLOAT:
515219b2ee8SDavid du Colombier switch(r.type) {
516bd389b36SDavid du Colombier case TINT:
517bd389b36SDavid du Colombier res->fval = l.fval/r.ival;
518bd389b36SDavid du Colombier break;
519bd389b36SDavid du Colombier case TFLOAT:
520bd389b36SDavid du Colombier res->fval = l.fval/r.fval;
521bd389b36SDavid du Colombier break;
522219b2ee8SDavid du Colombier default:
523219b2ee8SDavid du Colombier error("bad rhs type /");
524bd389b36SDavid du Colombier }
525bd389b36SDavid du Colombier break;
526bd389b36SDavid du Colombier }
527219b2ee8SDavid du Colombier }
528219b2ee8SDavid du Colombier
529219b2ee8SDavid du Colombier void
omod(Node * n,Node * res)530219b2ee8SDavid du Colombier omod(Node *n, Node *res)
531219b2ee8SDavid du Colombier {
532219b2ee8SDavid du Colombier Node l, r;
533219b2ee8SDavid du Colombier
534219b2ee8SDavid du Colombier expr(n->left, &l);
535219b2ee8SDavid du Colombier expr(n->right, &r);
536bd389b36SDavid du Colombier res->fmt = l.fmt;
537bd389b36SDavid du Colombier res->op = OCONST;
538bd389b36SDavid du Colombier res->type = TINT;
539bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT)
540bd389b36SDavid du Colombier error("bad expr type %");
541bd389b36SDavid du Colombier res->ival = l.ival%r.ival;
542219b2ee8SDavid du Colombier }
543219b2ee8SDavid du Colombier
544219b2ee8SDavid du Colombier void
olsh(Node * n,Node * res)545219b2ee8SDavid du Colombier olsh(Node *n, Node *res)
546219b2ee8SDavid du Colombier {
547219b2ee8SDavid du Colombier Node l, r;
548219b2ee8SDavid du Colombier
549219b2ee8SDavid du Colombier expr(n->left, &l);
550219b2ee8SDavid du Colombier expr(n->right, &r);
551bd389b36SDavid du Colombier res->fmt = l.fmt;
552bd389b36SDavid du Colombier res->op = OCONST;
553bd389b36SDavid du Colombier res->type = TINT;
554bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT)
555bd389b36SDavid du Colombier error("bad expr type <<");
556bd389b36SDavid du Colombier res->ival = l.ival<<r.ival;
557219b2ee8SDavid du Colombier }
558219b2ee8SDavid du Colombier
559219b2ee8SDavid du Colombier void
orsh(Node * n,Node * res)560219b2ee8SDavid du Colombier orsh(Node *n, Node *res)
561219b2ee8SDavid du Colombier {
562219b2ee8SDavid du Colombier Node l, r;
563219b2ee8SDavid du Colombier
564219b2ee8SDavid du Colombier expr(n->left, &l);
565219b2ee8SDavid du Colombier expr(n->right, &r);
566bd389b36SDavid du Colombier res->fmt = l.fmt;
567bd389b36SDavid du Colombier res->op = OCONST;
568bd389b36SDavid du Colombier res->type = TINT;
569bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT)
570bd389b36SDavid du Colombier error("bad expr type >>");
5714de34a7eSDavid du Colombier res->ival = (uvlong)l.ival>>r.ival;
572219b2ee8SDavid du Colombier }
573219b2ee8SDavid du Colombier
574219b2ee8SDavid du Colombier void
olt(Node * n,Node * res)575219b2ee8SDavid du Colombier olt(Node *n, Node *res)
576219b2ee8SDavid du Colombier {
577219b2ee8SDavid du Colombier Node l, r;
578219b2ee8SDavid du Colombier
579219b2ee8SDavid du Colombier expr(n->left, &l);
580219b2ee8SDavid du Colombier expr(n->right, &r);
581219b2ee8SDavid du Colombier
582bd389b36SDavid du Colombier res->fmt = l.fmt;
583bd389b36SDavid du Colombier res->op = OCONST;
584bd389b36SDavid du Colombier res->type = TINT;
585bd389b36SDavid du Colombier switch(l.type) {
586219b2ee8SDavid du Colombier default:
587219b2ee8SDavid du Colombier error("bad lhs type <");
588bd389b36SDavid du Colombier case TINT:
589bd389b36SDavid du Colombier switch(r.type) {
590bd389b36SDavid du Colombier case TINT:
591bd389b36SDavid du Colombier res->ival = l.ival < r.ival;
592bd389b36SDavid du Colombier break;
593bd389b36SDavid du Colombier case TFLOAT:
594bd389b36SDavid du Colombier res->ival = l.ival < r.fval;
595bd389b36SDavid du Colombier break;
596219b2ee8SDavid du Colombier default:
597219b2ee8SDavid du Colombier error("bad rhs type <");
598bd389b36SDavid du Colombier }
599bd389b36SDavid du Colombier break;
600bd389b36SDavid du Colombier case TFLOAT:
601219b2ee8SDavid du Colombier switch(r.type) {
602bd389b36SDavid du Colombier case TINT:
603bd389b36SDavid du Colombier res->ival = l.fval < r.ival;
604bd389b36SDavid du Colombier break;
605bd389b36SDavid du Colombier case TFLOAT:
606bd389b36SDavid du Colombier res->ival = l.fval < r.fval;
607bd389b36SDavid du Colombier break;
608219b2ee8SDavid du Colombier default:
609219b2ee8SDavid du Colombier error("bad rhs type <");
610bd389b36SDavid du Colombier }
611bd389b36SDavid du Colombier break;
612bd389b36SDavid du Colombier }
613219b2ee8SDavid du Colombier }
614219b2ee8SDavid du Colombier
615219b2ee8SDavid du Colombier void
ogt(Node * n,Node * res)616219b2ee8SDavid du Colombier ogt(Node *n, Node *res)
617219b2ee8SDavid du Colombier {
618219b2ee8SDavid du Colombier Node l, r;
619219b2ee8SDavid du Colombier
620219b2ee8SDavid du Colombier expr(n->left, &l);
621219b2ee8SDavid du Colombier expr(n->right, &r);
622bd389b36SDavid du Colombier res->fmt = 'D';
623bd389b36SDavid du Colombier res->op = OCONST;
624bd389b36SDavid du Colombier res->type = TINT;
625bd389b36SDavid du Colombier switch(l.type) {
626219b2ee8SDavid du Colombier default:
627219b2ee8SDavid du Colombier error("bad lhs type >");
628bd389b36SDavid du Colombier case TINT:
629bd389b36SDavid du Colombier switch(r.type) {
630bd389b36SDavid du Colombier case TINT:
631bd389b36SDavid du Colombier res->ival = l.ival > r.ival;
632bd389b36SDavid du Colombier break;
633bd389b36SDavid du Colombier case TFLOAT:
634bd389b36SDavid du Colombier res->ival = l.ival > r.fval;
635bd389b36SDavid du Colombier break;
636219b2ee8SDavid du Colombier default:
637219b2ee8SDavid du Colombier error("bad rhs type >");
638bd389b36SDavid du Colombier }
639bd389b36SDavid du Colombier break;
640bd389b36SDavid du Colombier case TFLOAT:
641219b2ee8SDavid du Colombier switch(r.type) {
642bd389b36SDavid du Colombier case TINT:
643bd389b36SDavid du Colombier res->ival = l.fval > r.ival;
644bd389b36SDavid du Colombier break;
645bd389b36SDavid du Colombier case TFLOAT:
646bd389b36SDavid du Colombier res->ival = l.fval > r.fval;
647bd389b36SDavid du Colombier break;
648219b2ee8SDavid du Colombier default:
649219b2ee8SDavid du Colombier error("bad rhs type >");
650bd389b36SDavid du Colombier }
651bd389b36SDavid du Colombier break;
652bd389b36SDavid du Colombier }
653219b2ee8SDavid du Colombier }
654219b2ee8SDavid du Colombier
655219b2ee8SDavid du Colombier void
oleq(Node * n,Node * res)656219b2ee8SDavid du Colombier oleq(Node *n, Node *res)
657219b2ee8SDavid du Colombier {
658219b2ee8SDavid du Colombier Node l, r;
659219b2ee8SDavid du Colombier
660219b2ee8SDavid du Colombier expr(n->left, &l);
661219b2ee8SDavid du Colombier expr(n->right, &r);
662bd389b36SDavid du Colombier res->fmt = 'D';
663bd389b36SDavid du Colombier res->op = OCONST;
664bd389b36SDavid du Colombier res->type = TINT;
665bd389b36SDavid du Colombier switch(l.type) {
666219b2ee8SDavid du Colombier default:
667219b2ee8SDavid du Colombier error("bad expr type <=");
668bd389b36SDavid du Colombier case TINT:
669bd389b36SDavid du Colombier switch(r.type) {
670bd389b36SDavid du Colombier case TINT:
671bd389b36SDavid du Colombier res->ival = l.ival <= r.ival;
672bd389b36SDavid du Colombier break;
673bd389b36SDavid du Colombier case TFLOAT:
674bd389b36SDavid du Colombier res->ival = l.ival <= r.fval;
675bd389b36SDavid du Colombier break;
676219b2ee8SDavid du Colombier default:
677bd389b36SDavid du Colombier error("bad expr type <=");
678bd389b36SDavid du Colombier }
679bd389b36SDavid du Colombier break;
680bd389b36SDavid du Colombier case TFLOAT:
681219b2ee8SDavid du Colombier switch(r.type) {
682bd389b36SDavid du Colombier case TINT:
683bd389b36SDavid du Colombier res->ival = l.fval <= r.ival;
684bd389b36SDavid du Colombier break;
685bd389b36SDavid du Colombier case TFLOAT:
686bd389b36SDavid du Colombier res->ival = l.fval <= r.fval;
687bd389b36SDavid du Colombier break;
688219b2ee8SDavid du Colombier default:
689bd389b36SDavid du Colombier error("bad expr type <=");
690bd389b36SDavid du Colombier }
691bd389b36SDavid du Colombier break;
692bd389b36SDavid du Colombier }
693219b2ee8SDavid du Colombier }
694219b2ee8SDavid du Colombier
695219b2ee8SDavid du Colombier void
ogeq(Node * n,Node * res)696219b2ee8SDavid du Colombier ogeq(Node *n, Node *res)
697219b2ee8SDavid du Colombier {
698219b2ee8SDavid du Colombier Node l, r;
699219b2ee8SDavid du Colombier
700219b2ee8SDavid du Colombier expr(n->left, &l);
701219b2ee8SDavid du Colombier expr(n->right, &r);
702bd389b36SDavid du Colombier res->fmt = 'D';
703bd389b36SDavid du Colombier res->op = OCONST;
704bd389b36SDavid du Colombier res->type = TINT;
705bd389b36SDavid du Colombier switch(l.type) {
706219b2ee8SDavid du Colombier default:
707219b2ee8SDavid du Colombier error("bad lhs type >=");
708bd389b36SDavid du Colombier case TINT:
709bd389b36SDavid du Colombier switch(r.type) {
710bd389b36SDavid du Colombier case TINT:
711bd389b36SDavid du Colombier res->ival = l.ival >= r.ival;
712bd389b36SDavid du Colombier break;
713bd389b36SDavid du Colombier case TFLOAT:
714bd389b36SDavid du Colombier res->ival = l.ival >= r.fval;
715bd389b36SDavid du Colombier break;
716219b2ee8SDavid du Colombier default:
717219b2ee8SDavid du Colombier error("bad rhs type >=");
718bd389b36SDavid du Colombier }
719bd389b36SDavid du Colombier break;
720bd389b36SDavid du Colombier case TFLOAT:
721219b2ee8SDavid du Colombier switch(r.type) {
722bd389b36SDavid du Colombier case TINT:
723bd389b36SDavid du Colombier res->ival = l.fval >= r.ival;
724bd389b36SDavid du Colombier break;
725bd389b36SDavid du Colombier case TFLOAT:
726bd389b36SDavid du Colombier res->ival = l.fval >= r.fval;
727bd389b36SDavid du Colombier break;
728219b2ee8SDavid du Colombier default:
729219b2ee8SDavid du Colombier error("bad rhs type >=");
730bd389b36SDavid du Colombier }
731bd389b36SDavid du Colombier break;
732bd389b36SDavid du Colombier }
733219b2ee8SDavid du Colombier }
734219b2ee8SDavid du Colombier
735219b2ee8SDavid du Colombier void
oeq(Node * n,Node * res)736219b2ee8SDavid du Colombier oeq(Node *n, Node *res)
737219b2ee8SDavid du Colombier {
738219b2ee8SDavid du Colombier Node l, r;
739219b2ee8SDavid du Colombier
740219b2ee8SDavid du Colombier expr(n->left, &l);
741219b2ee8SDavid du Colombier expr(n->right, &r);
742bd389b36SDavid du Colombier res->fmt = 'D';
743bd389b36SDavid du Colombier res->op = OCONST;
744bd389b36SDavid du Colombier res->type = TINT;
745219b2ee8SDavid du Colombier res->ival = 0;
746bd389b36SDavid du Colombier switch(l.type) {
747219b2ee8SDavid du Colombier default:
748219b2ee8SDavid du Colombier break;
749bd389b36SDavid du Colombier case TINT:
750bd389b36SDavid du Colombier switch(r.type) {
751bd389b36SDavid du Colombier case TINT:
752bd389b36SDavid du Colombier res->ival = l.ival == r.ival;
753bd389b36SDavid du Colombier break;
754bd389b36SDavid du Colombier case TFLOAT:
755bd389b36SDavid du Colombier res->ival = l.ival == r.fval;
756bd389b36SDavid du Colombier break;
757219b2ee8SDavid du Colombier default:
758219b2ee8SDavid du Colombier break;
759bd389b36SDavid du Colombier }
760bd389b36SDavid du Colombier break;
761bd389b36SDavid du Colombier case TFLOAT:
762219b2ee8SDavid du Colombier switch(r.type) {
763bd389b36SDavid du Colombier case TINT:
764bd389b36SDavid du Colombier res->ival = l.fval == r.ival;
765bd389b36SDavid du Colombier break;
766bd389b36SDavid du Colombier case TFLOAT:
767bd389b36SDavid du Colombier res->ival = l.fval == r.fval;
768bd389b36SDavid du Colombier break;
769219b2ee8SDavid du Colombier default:
770219b2ee8SDavid du Colombier break;
771bd389b36SDavid du Colombier }
772bd389b36SDavid du Colombier break;
773bd389b36SDavid du Colombier case TSTRING:
774bd389b36SDavid du Colombier if(r.type == TSTRING) {
775bd389b36SDavid du Colombier res->ival = scmp(r.string, l.string);
776bd389b36SDavid du Colombier break;
777bd389b36SDavid du Colombier }
778219b2ee8SDavid du Colombier break;
779bd389b36SDavid du Colombier case TLIST:
780bd389b36SDavid du Colombier if(r.type == TLIST) {
781bd389b36SDavid du Colombier res->ival = listcmp(l.l, r.l);
782bd389b36SDavid du Colombier break;
783bd389b36SDavid du Colombier }
784bd389b36SDavid du Colombier break;
785bd389b36SDavid du Colombier }
786219b2ee8SDavid du Colombier if(n->op == ONEQ)
787219b2ee8SDavid du Colombier res->ival = !res->ival;
788bd389b36SDavid du Colombier }
789219b2ee8SDavid du Colombier
790219b2ee8SDavid du Colombier
791219b2ee8SDavid du Colombier void
oland(Node * n,Node * res)792219b2ee8SDavid du Colombier oland(Node *n, Node *res)
793219b2ee8SDavid du Colombier {
794219b2ee8SDavid du Colombier Node l, r;
795219b2ee8SDavid du Colombier
796219b2ee8SDavid du Colombier expr(n->left, &l);
797219b2ee8SDavid du Colombier expr(n->right, &r);
798bd389b36SDavid du Colombier res->fmt = l.fmt;
799bd389b36SDavid du Colombier res->op = OCONST;
800bd389b36SDavid du Colombier res->type = TINT;
801bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT)
802bd389b36SDavid du Colombier error("bad expr type &");
803bd389b36SDavid du Colombier res->ival = l.ival&r.ival;
804219b2ee8SDavid du Colombier }
805219b2ee8SDavid du Colombier
806219b2ee8SDavid du Colombier void
oxor(Node * n,Node * res)807219b2ee8SDavid du Colombier oxor(Node *n, Node *res)
808219b2ee8SDavid du Colombier {
809219b2ee8SDavid du Colombier Node l, r;
810219b2ee8SDavid du Colombier
811219b2ee8SDavid du Colombier expr(n->left, &l);
812219b2ee8SDavid du Colombier expr(n->right, &r);
813bd389b36SDavid du Colombier res->fmt = l.fmt;
814bd389b36SDavid du Colombier res->op = OCONST;
815bd389b36SDavid du Colombier res->type = TINT;
816bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT)
817bd389b36SDavid du Colombier error("bad expr type ^");
818bd389b36SDavid du Colombier res->ival = l.ival^r.ival;
819219b2ee8SDavid du Colombier }
820219b2ee8SDavid du Colombier
821219b2ee8SDavid du Colombier void
olor(Node * n,Node * res)822219b2ee8SDavid du Colombier olor(Node *n, Node *res)
823219b2ee8SDavid du Colombier {
824219b2ee8SDavid du Colombier Node l, r;
825219b2ee8SDavid du Colombier
826219b2ee8SDavid du Colombier expr(n->left, &l);
827219b2ee8SDavid du Colombier expr(n->right, &r);
828bd389b36SDavid du Colombier res->fmt = l.fmt;
829bd389b36SDavid du Colombier res->op = OCONST;
830bd389b36SDavid du Colombier res->type = TINT;
831bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT)
832bd389b36SDavid du Colombier error("bad expr type |");
833bd389b36SDavid du Colombier res->ival = l.ival|r.ival;
834219b2ee8SDavid du Colombier }
835219b2ee8SDavid du Colombier
836219b2ee8SDavid du Colombier void
ocand(Node * n,Node * res)837219b2ee8SDavid du Colombier ocand(Node *n, Node *res)
838219b2ee8SDavid du Colombier {
839219b2ee8SDavid du Colombier Node l, r;
840219b2ee8SDavid du Colombier
841bd389b36SDavid du Colombier res->op = OCONST;
842bd389b36SDavid du Colombier res->type = TINT;
843219b2ee8SDavid du Colombier res->ival = 0;
844*b2495906SDavid du Colombier res->fmt = 'D';
845219b2ee8SDavid du Colombier expr(n->left, &l);
846219b2ee8SDavid du Colombier if(bool(&l) == 0)
847219b2ee8SDavid du Colombier return;
848219b2ee8SDavid du Colombier expr(n->right, &r);
849219b2ee8SDavid du Colombier if(bool(&r) == 0)
850219b2ee8SDavid du Colombier return;
851219b2ee8SDavid du Colombier res->ival = 1;
852219b2ee8SDavid du Colombier }
853219b2ee8SDavid du Colombier
854219b2ee8SDavid du Colombier void
onot(Node * n,Node * res)855219b2ee8SDavid du Colombier onot(Node *n, Node *res)
856219b2ee8SDavid du Colombier {
857219b2ee8SDavid du Colombier Node l;
858219b2ee8SDavid du Colombier
859bd389b36SDavid du Colombier res->op = OCONST;
860bd389b36SDavid du Colombier res->type = TINT;
861219b2ee8SDavid du Colombier res->ival = 0;
862219b2ee8SDavid du Colombier expr(n->left, &l);
863*b2495906SDavid du Colombier res->fmt = l.fmt;
864219b2ee8SDavid du Colombier if(bool(&l) == 0)
865219b2ee8SDavid du Colombier res->ival = 1;
866219b2ee8SDavid du Colombier }
867219b2ee8SDavid du Colombier
868219b2ee8SDavid du Colombier void
ocor(Node * n,Node * res)869219b2ee8SDavid du Colombier ocor(Node *n, Node *res)
870219b2ee8SDavid du Colombier {
871219b2ee8SDavid du Colombier Node l, r;
872219b2ee8SDavid du Colombier
873219b2ee8SDavid du Colombier res->op = OCONST;
874219b2ee8SDavid du Colombier res->type = TINT;
875219b2ee8SDavid du Colombier res->ival = 0;
876*b2495906SDavid du Colombier res->fmt = 'D';
877219b2ee8SDavid du Colombier expr(n->left, &l);
878219b2ee8SDavid du Colombier if(bool(&l)) {
879219b2ee8SDavid du Colombier res->ival = 1;
880219b2ee8SDavid du Colombier return;
881219b2ee8SDavid du Colombier }
882219b2ee8SDavid du Colombier expr(n->right, &r);
883219b2ee8SDavid du Colombier if(bool(&r)) {
884219b2ee8SDavid du Colombier res->ival = 1;
885219b2ee8SDavid du Colombier return;
886219b2ee8SDavid du Colombier }
887219b2ee8SDavid du Colombier }
888219b2ee8SDavid du Colombier
889219b2ee8SDavid du Colombier void
oeinc(Node * n,Node * res)890219b2ee8SDavid du Colombier oeinc(Node *n, Node *res)
891219b2ee8SDavid du Colombier {
892219b2ee8SDavid du Colombier Value *v;
893219b2ee8SDavid du Colombier
894219b2ee8SDavid du Colombier chklval(n->left);
895219b2ee8SDavid du Colombier v = n->left->sym->v;
896bd389b36SDavid du Colombier res->op = OCONST;
897bd389b36SDavid du Colombier res->type = v->type;
898bd389b36SDavid du Colombier switch(v->type) {
899bd389b36SDavid du Colombier case TINT:
900bd389b36SDavid du Colombier if(n->op == OEDEC)
901bd389b36SDavid du Colombier v->ival -= fmtsize(v);
902bd389b36SDavid du Colombier else
903bd389b36SDavid du Colombier v->ival += fmtsize(v);
904bd389b36SDavid du Colombier break;
905bd389b36SDavid du Colombier case TFLOAT:
906bd389b36SDavid du Colombier if(n->op == OEDEC)
907bd389b36SDavid du Colombier v->fval--;
908bd389b36SDavid du Colombier else
909bd389b36SDavid du Colombier v->fval++;
910bd389b36SDavid du Colombier break;
911bd389b36SDavid du Colombier default:
912bd389b36SDavid du Colombier error("bad type for pre --/++");
913bd389b36SDavid du Colombier }
914bd389b36SDavid du Colombier res->Store = v->Store;
915219b2ee8SDavid du Colombier }
916219b2ee8SDavid du Colombier
917219b2ee8SDavid du Colombier void
opinc(Node * n,Node * res)918219b2ee8SDavid du Colombier opinc(Node *n, Node *res)
919219b2ee8SDavid du Colombier {
920219b2ee8SDavid du Colombier Value *v;
921219b2ee8SDavid du Colombier
922219b2ee8SDavid du Colombier chklval(n->left);
923219b2ee8SDavid du Colombier v = n->left->sym->v;
924bd389b36SDavid du Colombier res->op = OCONST;
925bd389b36SDavid du Colombier res->type = v->type;
926bd389b36SDavid du Colombier res->Store = v->Store;
927bd389b36SDavid du Colombier switch(v->type) {
928bd389b36SDavid du Colombier case TINT:
929bd389b36SDavid du Colombier if(n->op == OPDEC)
930bd389b36SDavid du Colombier v->ival -= fmtsize(v);
931bd389b36SDavid du Colombier else
932bd389b36SDavid du Colombier v->ival += fmtsize(v);
933bd389b36SDavid du Colombier break;
934bd389b36SDavid du Colombier case TFLOAT:
935bd389b36SDavid du Colombier if(n->op == OPDEC)
936bd389b36SDavid du Colombier v->fval--;
937bd389b36SDavid du Colombier else
938bd389b36SDavid du Colombier v->fval++;
939bd389b36SDavid du Colombier break;
940bd389b36SDavid du Colombier default:
941bd389b36SDavid du Colombier error("bad type for post --/++");
942bd389b36SDavid du Colombier }
943219b2ee8SDavid du Colombier }
944219b2ee8SDavid du Colombier
945219b2ee8SDavid du Colombier void
ocall(Node * n,Node * res)946219b2ee8SDavid du Colombier ocall(Node *n, Node *res)
947219b2ee8SDavid du Colombier {
948219b2ee8SDavid du Colombier Lsym *s;
949219b2ee8SDavid du Colombier Rplace *rsav;
950219b2ee8SDavid du Colombier
951bd389b36SDavid du Colombier res->op = OCONST; /* Default return value */
952bd389b36SDavid du Colombier res->type = TLIST;
953bd389b36SDavid du Colombier res->l = 0;
954bd389b36SDavid du Colombier
955219b2ee8SDavid du Colombier chklval(n->left);
956219b2ee8SDavid du Colombier s = n->left->sym;
957bd389b36SDavid du Colombier
9580b459c2cSDavid du Colombier if(n->builtin && !s->builtin){
9590b459c2cSDavid du Colombier error("no builtin %s", s->name);
9600b459c2cSDavid du Colombier return;
9610b459c2cSDavid du Colombier }
9620b459c2cSDavid du Colombier if(s->builtin && (n->builtin || s->proc == 0)) {
963219b2ee8SDavid du Colombier (*s->builtin)(res, n->right);
964219b2ee8SDavid du Colombier return;
965bd389b36SDavid du Colombier }
966bd389b36SDavid du Colombier if(s->proc == 0)
967bd389b36SDavid du Colombier error("no function %s", s->name);
968bd389b36SDavid du Colombier
969bd389b36SDavid du Colombier rsav = ret;
970219b2ee8SDavid du Colombier call(s->name, n->right, s->proc->left, s->proc->right, res);
971bd389b36SDavid du Colombier ret = rsav;
972bd389b36SDavid du Colombier }
973219b2ee8SDavid du Colombier
974219b2ee8SDavid du Colombier void
ofmt(Node * n,Node * res)975219b2ee8SDavid du Colombier ofmt(Node *n, Node *res)
976219b2ee8SDavid du Colombier {
977219b2ee8SDavid du Colombier expr(n->left, res);
978219b2ee8SDavid du Colombier res->fmt = n->right->ival;
979bd389b36SDavid du Colombier }
980219b2ee8SDavid du Colombier
981219b2ee8SDavid du Colombier void
owhat(Node * n,Node * res)982219b2ee8SDavid du Colombier owhat(Node *n, Node *res)
983219b2ee8SDavid du Colombier {
984219b2ee8SDavid du Colombier res->op = OCONST; /* Default return value */
985219b2ee8SDavid du Colombier res->type = TLIST;
986219b2ee8SDavid du Colombier res->l = 0;
987219b2ee8SDavid du Colombier whatis(n->sym);
988219b2ee8SDavid du Colombier }
989219b2ee8SDavid du Colombier
990219b2ee8SDavid du Colombier void (*expop[])(Node*, Node*) =
991219b2ee8SDavid du Colombier {
992219b2ee8SDavid du Colombier [ONAME] oname,
993219b2ee8SDavid du Colombier [OCONST] oconst,
994219b2ee8SDavid du Colombier [OMUL] omul,
995219b2ee8SDavid du Colombier [ODIV] odiv,
996219b2ee8SDavid du Colombier [OMOD] omod,
997219b2ee8SDavid du Colombier [OADD] oadd,
998219b2ee8SDavid du Colombier [OSUB] osub,
999219b2ee8SDavid du Colombier [ORSH] orsh,
1000219b2ee8SDavid du Colombier [OLSH] olsh,
1001219b2ee8SDavid du Colombier [OLT] olt,
1002219b2ee8SDavid du Colombier [OGT] ogt,
1003219b2ee8SDavid du Colombier [OLEQ] oleq,
1004219b2ee8SDavid du Colombier [OGEQ] ogeq,
1005219b2ee8SDavid du Colombier [OEQ] oeq,
1006219b2ee8SDavid du Colombier [ONEQ] oeq,
1007219b2ee8SDavid du Colombier [OLAND] oland,
1008219b2ee8SDavid du Colombier [OXOR] oxor,
1009219b2ee8SDavid du Colombier [OLOR] olor,
1010219b2ee8SDavid du Colombier [OCAND] ocand,
1011219b2ee8SDavid du Colombier [OCOR] ocor,
1012219b2ee8SDavid du Colombier [OASGN] oasgn,
1013219b2ee8SDavid du Colombier [OINDM] oindm,
1014219b2ee8SDavid du Colombier [OEDEC] oeinc,
1015219b2ee8SDavid du Colombier [OEINC] oeinc,
1016219b2ee8SDavid du Colombier [OPINC] opinc,
1017219b2ee8SDavid du Colombier [OPDEC] opinc,
1018219b2ee8SDavid du Colombier [ONOT] onot,
1019219b2ee8SDavid du Colombier [OIF] 0,
1020219b2ee8SDavid du Colombier [ODO] 0,
1021219b2ee8SDavid du Colombier [OLIST] olist,
1022219b2ee8SDavid du Colombier [OCALL] ocall,
1023219b2ee8SDavid du Colombier [OCTRUCT] octruct,
1024219b2ee8SDavid du Colombier [OWHILE] 0,
1025219b2ee8SDavid du Colombier [OELSE] 0,
1026219b2ee8SDavid du Colombier [OHEAD] ohead,
1027219b2ee8SDavid du Colombier [OTAIL] otail,
1028219b2ee8SDavid du Colombier [OAPPEND] oappend,
1029219b2ee8SDavid du Colombier [ORET] 0,
1030219b2ee8SDavid du Colombier [OINDEX] oindex,
1031219b2ee8SDavid du Colombier [OINDC] oindc,
1032219b2ee8SDavid du Colombier [ODOT] odot,
1033219b2ee8SDavid du Colombier [OLOCAL] 0,
1034219b2ee8SDavid du Colombier [OFRAME] oframe,
1035219b2ee8SDavid du Colombier [OCOMPLEX] 0,
1036219b2ee8SDavid du Colombier [ODELETE] odelete,
1037219b2ee8SDavid du Colombier [OCAST] ocast,
1038219b2ee8SDavid du Colombier [OFMT] ofmt,
1039219b2ee8SDavid du Colombier [OEVAL] oeval,
1040219b2ee8SDavid du Colombier [OWHAT] owhat,
1041219b2ee8SDavid du Colombier };
1042