1 #include <lib9.h>
2 #include <bio.h>
3 #include <ctype.h>
4 #include "mach.h"
5 #define Extern extern
6 #include "acid.h"
7
8 static int fsize[] =
9 {
10 0,0,0,0,0,0,0,0, /* 0-7 */
11 0,0,0,0,0,0,0,0, /* 8-15 */
12 0,0,0,0,0,0,0,0, /* 16-23 */
13 0,0,0,0,0,0,0,0, /* 24-31 */
14 0,0,0,0,0,0,0,0, /* 32-39 */
15 0,0,0,0,0,0,0,0, /* 40-47 */
16 0,0,0,0,0,0,0,0, /* 48-55 */
17 0,0,0,0,0,0,0,0, /* 56-63 */
18 0, /* 64 */
19 4, /* 65 ['A'] 4, */
20 4, /* 66 ['B'] 4, */
21 1, /* 67 ['C'] 1, */
22 4, /* 68 ['D'] 4, */
23 0, /* 69 */
24 8, /* 70 ['F'] 8, */
25 8, /* 71 ['G'] 8, */
26 0,0,0,0,0,0,0, /* 72-78 */
27 4, /* 79 ['O'] 4, */
28 0, /* 80 */
29 4, /* 81 ['Q'] 4, */
30 4, /* 82 ['R'] 4, */
31 4, /* 83 ['S'] 4, */
32 0, /* 84 */
33 4, /* 85 ['U'] 4, */
34 8, /* 86 ['V'] 8, */
35 0, /* 87 */
36 4, /* 88 ['X'] 4, */
37 8, /* 89 ['Y'] 8, */
38 8, /* 90 ['Z'] 8, */
39 0,0,0,0,0,0, /* 91-96 */
40 4, /* 97 ['a'] 4, */
41 1, /* 98 ['b'] 1, */
42 1, /* 99 ['c'] 1, */
43 2, /* 100 ['d'] 2, */
44 0, /* 101 */
45 4, /* 102 ['f'] 4, */
46 4, /* 103 ['g'] 4, */
47 0,0,0,0,0,0,0, /* 104-110 */
48 2, /* 111 ['o'] 2, */
49 0, /* 112 */
50 2, /* 113 ['q'] 2, */
51 2, /* 114 ['r'] 2, */
52 4, /* 115 ['s'] 4, */
53 0, /* 116 */
54 2, /* 117 ['u'] 2, */
55 0,0, /* 118-119 */
56 2, /* 120 ['x'] 2, */
57 };
58
59 int
fmtsize(Value * v)60 fmtsize(Value *v)
61 {
62 int ret;
63
64 switch(v->vstore.fmt) {
65 default:
66 return fsize[v->vstore.fmt];
67 case 'i':
68 case 'I':
69 if(v->type != TINT || machdata == 0)
70 error("no size for i fmt pointer ++/--");
71 ret = (*machdata->instsize)(cormap, v->vstore.u0.sival);
72 if(ret < 0) {
73 ret = (*machdata->instsize)(symmap, v->vstore.u0.sival);
74 if(ret < 0)
75 error("%r");
76 }
77 return ret;
78 }
79 }
80
81 void
chklval(Node * lp)82 chklval(Node *lp)
83 {
84 if(lp->op != ONAME)
85 error("need l-value");
86 }
87
88 void
olist(Node * n,Node * res)89 olist(Node *n, Node *res)
90 {
91 expr(n->left, res);
92 expr(n->right, res);
93 }
94
95 void
oeval(Node * n,Node * res)96 oeval(Node *n, Node *res)
97 {
98 expr(n->left, res);
99 if(res->type != TCODE)
100 error("bad type for eval");
101 expr(res->nstore.u0.scc, res);
102 }
103
104 void
ocast(Node * n,Node * res)105 ocast(Node *n, Node *res)
106 {
107 if(n->sym->lt == 0)
108 error("%s is not a complex type", n->sym->name);
109
110 expr(n->left, res);
111 res->nstore.comt = n->sym->lt;
112 res->nstore.fmt = 'a';
113 }
114
115 void
oindm(Node * n,Node * res)116 oindm(Node *n, Node *res)
117 {
118 Map *m;
119 Node l;
120
121 m = cormap;
122 if(m == 0)
123 m = symmap;
124 expr(n->left, &l);
125 if(l.type != TINT)
126 error("bad type for *");
127 if(m == 0)
128 error("no map for *");
129 indir(m, l.nstore.u0.sival, l.nstore.fmt, res);
130 res->nstore.comt = l.nstore.comt;
131 }
132
133 void
oindc(Node * n,Node * res)134 oindc(Node *n, Node *res)
135 {
136 Map *m;
137 Node l;
138
139 m = symmap;
140 if(m == 0)
141 m = cormap;
142 expr(n->left, &l);
143 if(l.type != TINT)
144 error("bad type for @");
145 if(m == 0)
146 error("no map for @");
147 indir(m, l.nstore.u0.sival, l.nstore.fmt, res);
148 res->nstore.comt = l.nstore.comt;
149 }
150
151 void
oframe(Node * n,Node * res)152 oframe(Node *n, Node *res)
153 {
154 char *p;
155 Node *lp;
156 uvlong ival;
157 Frtype *f;
158
159 p = n->sym->name;
160 while(*p && *p == '$')
161 p++;
162 lp = n->left;
163 if(localaddr(cormap, p, lp->sym->name, &ival, rget) < 0)
164 error("colon: %r");
165
166 res->nstore.u0.sival = ival;
167 res->op = OCONST;
168 res->nstore.fmt = 'X';
169 res->type = TINT;
170
171 /* Try and set comt */
172 for(f = n->sym->local; f; f = f->next) {
173 if(f->var == lp->sym) {
174 res->nstore.comt = f->type;
175 res->nstore.fmt = 'a';
176 break;
177 }
178 }
179 }
180
181 void
oindex(Node * n,Node * res)182 oindex(Node *n, Node *res)
183 {
184 Node l, r;
185
186 expr(n->left, &l);
187 expr(n->right, &r);
188
189 if(r.type != TINT)
190 error("bad type for []");
191
192 switch(l.type) {
193 default:
194 error("lhs[] has bad type");
195 case TINT:
196 indir(cormap, l.nstore.u0.sival+(r.nstore.u0.sival*fsize[l.nstore.fmt]), l.nstore.fmt, res);
197 res->nstore.comt = l.nstore.comt;
198 res->nstore.fmt = l.nstore.fmt;
199 break;
200 case TLIST:
201 nthelem(l.nstore.u0.sl, r.nstore.u0.sival, res);
202 break;
203 case TSTRING:
204 res->nstore.u0.sival = 0;
205 if(r.nstore.u0.sival >= 0 && r.nstore.u0.sival < l.nstore.u0.sstring->len) {
206 int xx8; /* to get around bug in vc */
207 xx8 = r.nstore.u0.sival;
208 res->nstore.u0.sival = l.nstore.u0.sstring->string[xx8];
209 }
210 res->op = OCONST;
211 res->type = TINT;
212 res->nstore.fmt = 'c';
213 break;
214 }
215 }
216
217 void
oappend(Node * n,Node * res)218 oappend(Node *n, Node *res)
219 {
220 Node r, l;
221
222 expr(n->left, &l);
223 expr(n->right, &r);
224 if(l.type != TLIST)
225 error("must append to list");
226 append(res, &l, &r);
227 }
228
229 void
odelete(Node * n,Node * res)230 odelete(Node *n, Node *res)
231 {
232 Node l, r;
233
234 expr(n->left, &l);
235 expr(n->right, &r);
236 if(l.type != TLIST)
237 error("must delete from list");
238 if(r.type != TINT)
239 error("delete index must be integer");
240
241 delete(l.nstore.u0.sl, r.nstore.u0.sival, res);
242 }
243
244 void
ohead(Node * n,Node * res)245 ohead(Node *n, Node *res)
246 {
247 Node l;
248
249 expr(n->left, &l);
250 if(l.type != TLIST)
251 error("head needs list");
252 res->op = OCONST;
253 if(l.nstore.u0.sl) {
254 res->type = l.nstore.u0.sl->type;
255 res->nstore = l.nstore.u0.sl->lstore;
256 }
257 else {
258 res->type = TLIST;
259 res->nstore.u0.sl = 0;
260 }
261 }
262
263 void
otail(Node * n,Node * res)264 otail(Node *n, Node *res)
265 {
266 Node l;
267
268 expr(n->left, &l);
269 if(l.type != TLIST)
270 error("tail needs list");
271 res->op = OCONST;
272 res->type = TLIST;
273 if(l.nstore.u0.sl)
274 res->nstore.u0.sl = l.nstore.u0.sl->next;
275 else
276 res->nstore.u0.sl = 0;
277 }
278
279 void
oconst(Node * n,Node * res)280 oconst(Node *n, Node *res)
281 {
282 res->op = OCONST;
283 res->type = n->type;
284 res->nstore = n->nstore;
285 res->nstore.comt = n->nstore.comt;
286 }
287
288 void
oname(Node * n,Node * res)289 oname(Node *n, Node *res)
290 {
291 Value *v;
292
293 v = n->sym->v;
294 if(v->set == 0)
295 error("%s used but not set", n->sym->name);
296 res->op = OCONST;
297 res->type = v->type;
298 res->nstore = v->vstore;
299 res->nstore.comt = v->vstore.comt;
300 }
301
302 void
octruct(Node * n,Node * res)303 octruct(Node *n, Node *res)
304 {
305 res->op = OCONST;
306 res->type = TLIST;
307 res->nstore.u0.sl = construct(n->left);
308 }
309
310 void
oasgn(Node * n,Node * res)311 oasgn(Node *n, Node *res)
312 {
313 Node *lp, r;
314 Value *v;
315
316 lp = n->left;
317 switch(lp->op) {
318 case OINDM:
319 windir(cormap, lp->left, n->right, res);
320 break;
321 case OINDC:
322 windir(symmap, lp->left, n->right, res);
323 break;
324 default:
325 chklval(lp);
326 v = lp->sym->v;
327 expr(n->right, &r);
328 v->set = 1;
329 v->type = r.type;
330 v->vstore = r.nstore;
331 res->op = OCONST;
332 res->type = v->type;
333 res->nstore = v->vstore;
334 res->nstore.comt = v->vstore.comt;
335 }
336 }
337
338 void
oadd(Node * n,Node * res)339 oadd(Node *n, Node *res)
340 {
341 Node l, r;
342
343 expr(n->left, &l);
344 expr(n->right, &r);
345 res->nstore.fmt = l.nstore.fmt;
346 res->op = OCONST;
347 res->type = TFLOAT;
348 switch(l.type) {
349 default:
350 error("bad lhs type +");
351 case TINT:
352 switch(r.type) {
353 case TINT:
354 res->type = TINT;
355 res->nstore.u0.sival = l.nstore.u0.sival+r.nstore.u0.sival;
356 break;
357 case TFLOAT:
358 res->nstore.u0.sfval = l.nstore.u0.sival+r.nstore.u0.sfval;
359 break;
360 default:
361 error("bad rhs type +");
362 }
363 break;
364 case TFLOAT:
365 switch(r.type) {
366 case TINT:
367 res->nstore.u0.sfval = l.nstore.u0.sfval+r.nstore.u0.sival;
368 break;
369 case TFLOAT:
370 res->nstore.u0.sfval = l.nstore.u0.sfval+r.nstore.u0.sfval;
371 break;
372 default:
373 error("bad rhs type +");
374 }
375 break;
376 case TSTRING:
377 if(r.type == TSTRING) {
378 res->type = TSTRING;
379 res->nstore.fmt = 's';
380 res->nstore.u0.sstring = stradd(l.nstore.u0.sstring, r.nstore.u0.sstring);
381 break;
382 }
383 error("bad rhs for +");
384 case TLIST:
385 res->type = TLIST;
386 switch(r.type) {
387 case TLIST:
388 res->nstore.u0.sl = addlist(l.nstore.u0.sl, r.nstore.u0.sl);
389 break;
390 default:
391 r.left = 0;
392 r.right = 0;
393 res->nstore.u0.sl = addlist(l.nstore.u0.sl, construct(&r));
394 break;
395 }
396 }
397 }
398
399 void
osub(Node * n,Node * res)400 osub(Node *n, Node *res)
401 {
402 Node l, r;
403
404 expr(n->left, &l);
405 expr(n->right, &r);
406 res->nstore.fmt = l.nstore.fmt;
407 res->op = OCONST;
408 res->type = TFLOAT;
409 switch(l.type) {
410 default:
411 error("bad lhs type -");
412 case TINT:
413 switch(r.type) {
414 case TINT:
415 res->type = TINT;
416 res->nstore.u0.sival = l.nstore.u0.sival-r.nstore.u0.sival;
417 break;
418 case TFLOAT:
419 res->nstore.u0.sfval = l.nstore.u0.sival-r.nstore.u0.sfval;
420 break;
421 default:
422 error("bad rhs type -");
423 }
424 break;
425 case TFLOAT:
426 switch(r.type) {
427 case TINT:
428 res->nstore.u0.sfval = l.nstore.u0.sfval-r.nstore.u0.sival;
429 break;
430 case TFLOAT:
431 res->nstore.u0.sfval = l.nstore.u0.sfval-r.nstore.u0.sfval;
432 break;
433 default:
434 error("bad rhs type -");
435 }
436 break;
437 }
438 }
439
440 void
omul(Node * n,Node * res)441 omul(Node *n, Node *res)
442 {
443 Node l, r;
444
445 expr(n->left, &l);
446 expr(n->right, &r);
447 res->nstore.fmt = l.nstore.fmt;
448 res->op = OCONST;
449 res->type = TFLOAT;
450 switch(l.type) {
451 default:
452 error("bad lhs type *");
453 case TINT:
454 switch(r.type) {
455 case TINT:
456 res->type = TINT;
457 res->nstore.u0.sival = l.nstore.u0.sival*r.nstore.u0.sival;
458 break;
459 case TFLOAT:
460 res->nstore.u0.sfval = l.nstore.u0.sival*r.nstore.u0.sfval;
461 break;
462 default:
463 error("bad rhs type *");
464 }
465 break;
466 case TFLOAT:
467 switch(r.type) {
468 case TINT:
469 res->nstore.u0.sfval = l.nstore.u0.sfval*r.nstore.u0.sival;
470 break;
471 case TFLOAT:
472 res->nstore.u0.sfval = l.nstore.u0.sfval*r.nstore.u0.sfval;
473 break;
474 default:
475 error("bad rhs type *");
476 }
477 break;
478 }
479 }
480
481 void
odiv(Node * n,Node * res)482 odiv(Node *n, Node *res)
483 {
484 Node l, r;
485
486 expr(n->left, &l);
487 expr(n->right, &r);
488 res->nstore.fmt = l.nstore.fmt;
489 res->op = OCONST;
490 res->type = TFLOAT;
491 switch(l.type) {
492 default:
493 error("bad lhs type /");
494 case TINT:
495 switch(r.type) {
496 case TINT:
497 res->type = TINT;
498 if(r.nstore.u0.sival == 0)
499 error("zero divide");
500 res->nstore.u0.sival = l.nstore.u0.sival/r.nstore.u0.sival;
501 break;
502 case TFLOAT:
503 if(r.nstore.u0.sfval == 0)
504 error("zero divide");
505 res->nstore.u0.sfval = l.nstore.u0.sival/r.nstore.u0.sfval;
506 break;
507 default:
508 error("bad rhs type /");
509 }
510 break;
511 case TFLOAT:
512 switch(r.type) {
513 case TINT:
514 res->nstore.u0.sfval = l.nstore.u0.sfval/r.nstore.u0.sival;
515 break;
516 case TFLOAT:
517 res->nstore.u0.sfval = l.nstore.u0.sfval/r.nstore.u0.sfval;
518 break;
519 default:
520 error("bad rhs type /");
521 }
522 break;
523 }
524 }
525
526 void
omod(Node * n,Node * res)527 omod(Node *n, Node *res)
528 {
529 Node l, r;
530
531 expr(n->left, &l);
532 expr(n->right, &r);
533 res->nstore.fmt = l.nstore.fmt;
534 res->op = OCONST;
535 res->type = TINT;
536 if(l.type != TINT || r.type != TINT)
537 error("bad expr type %");
538 res->nstore.u0.sival = l.nstore.u0.sival%r.nstore.u0.sival;
539 }
540
541 void
olsh(Node * n,Node * res)542 olsh(Node *n, Node *res)
543 {
544 Node l, r;
545
546 expr(n->left, &l);
547 expr(n->right, &r);
548 res->nstore.fmt = l.nstore.fmt;
549 res->op = OCONST;
550 res->type = TINT;
551 if(l.type != TINT || r.type != TINT)
552 error("bad expr type <<");
553 res->nstore.u0.sival = l.nstore.u0.sival<<r.nstore.u0.sival;
554 }
555
556 void
orsh(Node * n,Node * res)557 orsh(Node *n, Node *res)
558 {
559 Node l, r;
560
561 expr(n->left, &l);
562 expr(n->right, &r);
563 res->nstore.fmt = l.nstore.fmt;
564 res->op = OCONST;
565 res->type = TINT;
566 if(l.type != TINT || r.type != TINT)
567 error("bad expr type >>");
568 res->nstore.u0.sival = l.nstore.u0.sival>>r.nstore.u0.sival;
569 }
570
571 void
olt(Node * n,Node * res)572 olt(Node *n, Node *res)
573 {
574 Node l, r;
575
576 expr(n->left, &l);
577 expr(n->right, &r);
578
579 res->nstore.fmt = l.nstore.fmt;
580 res->op = OCONST;
581 res->type = TINT;
582 switch(l.type) {
583 default:
584 error("bad lhs type <");
585 case TINT:
586 switch(r.type) {
587 case TINT:
588 res->nstore.u0.sival = l.nstore.u0.sival < r.nstore.u0.sival;
589 break;
590 case TFLOAT:
591 res->nstore.u0.sival = l.nstore.u0.sival < r.nstore.u0.sfval;
592 break;
593 default:
594 error("bad rhs type <");
595 }
596 break;
597 case TFLOAT:
598 switch(r.type) {
599 case TINT:
600 res->nstore.u0.sival = l.nstore.u0.sfval < r.nstore.u0.sival;
601 break;
602 case TFLOAT:
603 res->nstore.u0.sival = l.nstore.u0.sfval < r.nstore.u0.sfval;
604 break;
605 default:
606 error("bad rhs type <");
607 }
608 break;
609 }
610 }
611
612 void
ogt(Node * n,Node * res)613 ogt(Node *n, Node *res)
614 {
615 Node l, r;
616
617 expr(n->left, &l);
618 expr(n->right, &r);
619 res->nstore.fmt = 'D';
620 res->op = OCONST;
621 res->type = TINT;
622 switch(l.type) {
623 default:
624 error("bad lhs type >");
625 case TINT:
626 switch(r.type) {
627 case TINT:
628 res->nstore.u0.sival = l.nstore.u0.sival > r.nstore.u0.sival;
629 break;
630 case TFLOAT:
631 res->nstore.u0.sival = l.nstore.u0.sival > r.nstore.u0.sfval;
632 break;
633 default:
634 error("bad rhs type >");
635 }
636 break;
637 case TFLOAT:
638 switch(r.type) {
639 case TINT:
640 res->nstore.u0.sival = l.nstore.u0.sfval > r.nstore.u0.sival;
641 break;
642 case TFLOAT:
643 res->nstore.u0.sival = l.nstore.u0.sfval > r.nstore.u0.sfval;
644 break;
645 default:
646 error("bad rhs type >");
647 }
648 break;
649 }
650 }
651
652 void
oleq(Node * n,Node * res)653 oleq(Node *n, Node *res)
654 {
655 Node l, r;
656
657 expr(n->left, &l);
658 expr(n->right, &r);
659 res->nstore.fmt = 'D';
660 res->op = OCONST;
661 res->type = TINT;
662 switch(l.type) {
663 default:
664 error("bad expr type <=");
665 case TINT:
666 switch(r.type) {
667 case TINT:
668 res->nstore.u0.sival = l.nstore.u0.sival <= r.nstore.u0.sival;
669 break;
670 case TFLOAT:
671 res->nstore.u0.sival = l.nstore.u0.sival <= r.nstore.u0.sfval;
672 break;
673 default:
674 error("bad expr type <=");
675 }
676 break;
677 case TFLOAT:
678 switch(r.type) {
679 case TINT:
680 res->nstore.u0.sival = l.nstore.u0.sfval <= r.nstore.u0.sival;
681 break;
682 case TFLOAT:
683 res->nstore.u0.sival = l.nstore.u0.sfval <= r.nstore.u0.sfval;
684 break;
685 default:
686 error("bad expr type <=");
687 }
688 break;
689 }
690 }
691
692 void
ogeq(Node * n,Node * res)693 ogeq(Node *n, Node *res)
694 {
695 Node l, r;
696
697 expr(n->left, &l);
698 expr(n->right, &r);
699 res->nstore.fmt = 'D';
700 res->op = OCONST;
701 res->type = TINT;
702 switch(l.type) {
703 default:
704 error("bad lhs type >=");
705 case TINT:
706 switch(r.type) {
707 case TINT:
708 res->nstore.u0.sival = l.nstore.u0.sival >= r.nstore.u0.sival;
709 break;
710 case TFLOAT:
711 res->nstore.u0.sival = l.nstore.u0.sival >= r.nstore.u0.sfval;
712 break;
713 default:
714 error("bad rhs type >=");
715 }
716 break;
717 case TFLOAT:
718 switch(r.type) {
719 case TINT:
720 res->nstore.u0.sival = l.nstore.u0.sfval >= r.nstore.u0.sival;
721 break;
722 case TFLOAT:
723 res->nstore.u0.sival = l.nstore.u0.sfval >= r.nstore.u0.sfval;
724 break;
725 default:
726 error("bad rhs type >=");
727 }
728 break;
729 }
730 }
731
732 void
oeq(Node * n,Node * res)733 oeq(Node *n, Node *res)
734 {
735 Node l, r;
736
737 expr(n->left, &l);
738 expr(n->right, &r);
739 res->nstore.fmt = 'D';
740 res->op = OCONST;
741 res->type = TINT;
742 res->nstore.u0.sival = 0;
743 switch(l.type) {
744 default:
745 break;
746 case TINT:
747 switch(r.type) {
748 case TINT:
749 res->nstore.u0.sival = l.nstore.u0.sival == r.nstore.u0.sival;
750 break;
751 case TFLOAT:
752 res->nstore.u0.sival = l.nstore.u0.sival == r.nstore.u0.sfval;
753 break;
754 default:
755 break;
756 }
757 break;
758 case TFLOAT:
759 switch(r.type) {
760 case TINT:
761 res->nstore.u0.sival = l.nstore.u0.sfval == r.nstore.u0.sival;
762 break;
763 case TFLOAT:
764 res->nstore.u0.sival = l.nstore.u0.sfval == r.nstore.u0.sfval;
765 break;
766 default:
767 break;
768 }
769 break;
770 case TSTRING:
771 if(r.type == TSTRING) {
772 res->nstore.u0.sival = scmp(r.nstore.u0.sstring, l.nstore.u0.sstring);
773 break;
774 }
775 break;
776 case TLIST:
777 if(r.type == TLIST) {
778 res->nstore.u0.sival = listcmp(l.nstore.u0.sl, r.nstore.u0.sl);
779 break;
780 }
781 break;
782 }
783 if(n->op == ONEQ)
784 res->nstore.u0.sival = !res->nstore.u0.sival;
785 }
786
787
788 void
oland(Node * n,Node * res)789 oland(Node *n, Node *res)
790 {
791 Node l, r;
792
793 expr(n->left, &l);
794 expr(n->right, &r);
795 res->nstore.fmt = l.nstore.fmt;
796 res->op = OCONST;
797 res->type = TINT;
798 if(l.type != TINT || r.type != TINT)
799 error("bad expr type &");
800 res->nstore.u0.sival = l.nstore.u0.sival&r.nstore.u0.sival;
801 }
802
803 void
oxor(Node * n,Node * res)804 oxor(Node *n, Node *res)
805 {
806 Node l, r;
807
808 expr(n->left, &l);
809 expr(n->right, &r);
810 res->nstore.fmt = l.nstore.fmt;
811 res->op = OCONST;
812 res->type = TINT;
813 if(l.type != TINT || r.type != TINT)
814 error("bad expr type ^");
815 res->nstore.u0.sival = l.nstore.u0.sival^r.nstore.u0.sival;
816 }
817
818 void
olor(Node * n,Node * res)819 olor(Node *n, Node *res)
820 {
821 Node l, r;
822
823 expr(n->left, &l);
824 expr(n->right, &r);
825 res->nstore.fmt = l.nstore.fmt;
826 res->op = OCONST;
827 res->type = TINT;
828 if(l.type != TINT || r.type != TINT)
829 error("bad expr type |");
830 res->nstore.u0.sival = l.nstore.u0.sival|r.nstore.u0.sival;
831 }
832
833 void
ocand(Node * n,Node * res)834 ocand(Node *n, Node *res)
835 {
836 Node l, r;
837
838 res->op = OCONST;
839 res->type = TINT;
840 res->nstore.u0.sival = 0;
841 expr(n->left, &l);
842 res->nstore.fmt = l.nstore.fmt;
843 if(boolx(&l) == 0)
844 return;
845 expr(n->right, &r);
846 if(boolx(&r) == 0)
847 return;
848 res->nstore.u0.sival = 1;
849 }
850
851 void
onot(Node * n,Node * res)852 onot(Node *n, Node *res)
853 {
854 Node l;
855
856 res->op = OCONST;
857 res->type = TINT;
858 res->nstore.u0.sival = 0;
859 expr(n->left, &l);
860 if(boolx(&l) == 0)
861 res->nstore.u0.sival = 1;
862 }
863
864 void
ocor(Node * n,Node * res)865 ocor(Node *n, Node *res)
866 {
867 Node l, r;
868
869 res->op = OCONST;
870 res->type = TINT;
871 res->nstore.u0.sival = 0;
872 expr(n->left, &l);
873 if(boolx(&l)) {
874 res->nstore.u0.sival = 1;
875 return;
876 }
877 expr(n->right, &r);
878 if(boolx(&r)) {
879 res->nstore.u0.sival = 1;
880 return;
881 }
882 }
883
884 void
oeinc(Node * n,Node * res)885 oeinc(Node *n, Node *res)
886 {
887 Value *v;
888
889 chklval(n->left);
890 v = n->left->sym->v;
891 res->op = OCONST;
892 res->type = v->type;
893 switch(v->type) {
894 case TINT:
895 if(n->op == OEDEC)
896 v->vstore.u0.sival -= fmtsize(v);
897 else
898 v->vstore.u0.sival += fmtsize(v);
899 break;
900 case TFLOAT:
901 if(n->op == OEDEC)
902 v->vstore.u0.sfval--;
903 else
904 v->vstore.u0.sfval++;
905 break;
906 default:
907 error("bad type for pre --/++");
908 }
909 res->nstore = v->vstore;
910 }
911
912 void
opinc(Node * n,Node * res)913 opinc(Node *n, Node *res)
914 {
915 Value *v;
916
917 chklval(n->left);
918 v = n->left->sym->v;
919 res->op = OCONST;
920 res->type = v->type;
921 res->nstore = v->vstore;
922 switch(v->type) {
923 case TINT:
924 if(n->op == OPDEC)
925 v->vstore.u0.sival -= fmtsize(v);
926 else
927 v->vstore.u0.sival += fmtsize(v);
928 break;
929 case TFLOAT:
930 if(n->op == OPDEC)
931 v->vstore.u0.sfval--;
932 else
933 v->vstore.u0.sfval++;
934 break;
935 default:
936 error("bad type for post --/++");
937 }
938 }
939
940 void
ocall(Node * n,Node * res)941 ocall(Node *n, Node *res)
942 {
943 Lsym *s;
944 Rplace *rsav;
945
946 res->op = OCONST; /* Default return value */
947 res->type = TLIST;
948 res->nstore.u0.sl = 0;
949
950 chklval(n->left);
951 s = n->left->sym;
952
953 if(s->builtin) {
954 (*s->builtin)(res, n->right);
955 return;
956 }
957 if(s->proc == 0)
958 error("no function %s", s->name);
959
960 rsav = ret;
961 call(s->name, n->right, s->proc->left, s->proc->right, res);
962 ret = rsav;
963 }
964
965 void
ofmt(Node * n,Node * res)966 ofmt(Node *n, Node *res)
967 {
968 expr(n->left, res);
969 res->nstore.fmt = n->right->nstore.u0.sival;
970 }
971
972 void
owhat(Node * n,Node * res)973 owhat(Node *n, Node *res)
974 {
975 res->op = OCONST; /* Default return value */
976 res->type = TLIST;
977 res->nstore.u0.sl = 0;
978 whatis(n->sym);
979 }
980
981 void (*expop[])(Node*, Node*) =
982 {
983 oname, /* [ONAME] oname, */
984 oconst, /* [OCONST] oconst, */
985 omul, /* [OMUL] omul, */
986 odiv, /* [ODIV] odiv, */
987 omod, /* [OMOD] omod, */
988 oadd, /* [OADD] oadd, */
989 osub, /* [OSUB] osub, */
990 orsh, /* [ORSH] orsh, */
991 olsh, /* [OLSH] olsh, */
992 olt, /* [OLT] olt, */
993 ogt, /* [OGT] ogt, */
994 oleq, /* [OLEQ] oleq, */
995 ogeq, /* [OGEQ] ogeq, */
996 oeq, /* [OEQ] oeq, */
997 oeq, /* [ONEQ] oeq, */
998 oland, /* [OLAND] oland, */
999 oxor, /* [OXOR] oxor, */
1000 olor, /* [OLOR] olor, */
1001 ocand, /* [OCAND] ocand, */
1002 ocor, /* [OCOR] ocor, */
1003 oasgn, /* [OASGN] oasgn, */
1004 oindm, /* [OINDM] oindm, */
1005 oeinc, /* [OEDEC] oeinc, */
1006 oeinc, /* [OEINC] oeinc, */
1007 opinc, /* [OPINC] opinc, */
1008 opinc, /* [OPDEC] opinc, */
1009 onot, /* [ONOT] onot, */
1010 0, /* [OIF] 0, */
1011 0, /* [ODO] 0, */
1012 olist, /* [OLIST] olist, */
1013 ocall, /* [OCALL] ocall, */
1014 octruct, /* [OCTRUCT] octruct, */
1015 0, /* [OWHILE] 0, */
1016 0, /* [OELSE] 0, */
1017 ohead, /* [OHEAD] ohead, */
1018 otail, /* [OTAIL] otail, */
1019 oappend, /* [OAPPEND] oappend, */
1020 0, /* [ORET] 0, */
1021 oindex, /* [OINDEX] oindex, */
1022 oindc, /* [OINDC] oindc, */
1023 odot, /* [ODOT] odot, */
1024 0, /* [OLOCAL] 0, */
1025 oframe, /* [OFRAME] oframe, */
1026 0, /* [OCOMPLEX] 0, */
1027 odelete, /* [ODELETE] odelete, */
1028 ocast, /* [OCAST] ocast, */
1029 ofmt, /* [OFMT] ofmt, */
1030 oeval, /* [OEVAL] oeval, */
1031 owhat, /* [OWHAT] owhat, */
1032 };
1033