1 #include "limbo.h"
2
3 static vlong
ipow(vlong x,int n)4 ipow(vlong x, int n)
5 {
6 int inv;
7 vlong r;
8
9 inv = 0;
10 if(n < 0){
11 n = -n;
12 inv = 1;
13 }
14 r = 1;
15 for(;;){
16 if(n&1)
17 r *= x;
18 if((n >>= 1) == 0)
19 break;
20 x *= x;
21 }
22 if(inv)
23 r = 1/r;
24 return r;
25 }
26
27 double
rpow(double x,int n)28 rpow(double x, int n)
29 {
30 int inv;
31 double r;
32
33 inv = 0;
34 if(n < 0){
35 n = -n;
36 inv = 1;
37 }
38 r = 1;
39 for(;;){
40 if(n&1)
41 r *= x;
42 if((n >>= 1) == 0)
43 break;
44 x *= x;
45 }
46 if(inv)
47 r = 1/r;
48 return r;
49 }
50
51 Long
real2fix(double v,Type * t)52 real2fix(double v, Type *t)
53 {
54 v /= scale(t);
55 v = v < 0 ? v-0.5: v+0.5;
56 return v;
57 }
58
59 Long
fix2fix(Long v,Type * f,Type * t)60 fix2fix(Long v, Type *f, Type *t)
61 {
62 double r;
63
64 r = (double)v * (scale(f)/scale(t));
65 r = r < 0 ? r-0.5: r+0.5;
66 return r;
67 }
68
69 double
fix2real(Long v,Type * f)70 fix2real(Long v, Type *f)
71 {
72 return (double)v * scale(f);
73 }
74
75 int
istuple(Node * n)76 istuple(Node *n)
77 {
78 Decl *d;
79
80 switch(n->op){
81 case Otuple:
82 return 1;
83 case Oname:
84 d = n->decl;
85 if(d->importid != nil)
86 d = d->importid;
87 return d->store == Dconst && (n->ty->kind == Ttuple || n->ty->kind == Tadt);
88 case Odot:
89 return 0; /* istuple(n->left); */
90 }
91 return 0;
92 }
93
94 static Node*
tuplemem(Node * n,Decl * d)95 tuplemem(Node *n, Decl *d)
96 {
97 Type *ty;
98 Decl *ids;
99
100 ty = n->ty;
101 n = n->left;
102 for(ids = ty->ids; ids != nil; ids = ids->next){
103 if(ids->sym == d->sym)
104 break;
105 else
106 n = n->right;
107 }
108 if(n == nil)
109 fatal("tuplemem cannot cope !\n");
110 return n->left;
111 }
112
113 int
varcom(Decl * v)114 varcom(Decl *v)
115 {
116 Node *n, tn;
117
118 n = v->init;
119 n = fold(n);
120 v->init = n;
121 if(debug['v'])
122 print("variable '%D' val %V\n", v, n);
123 if(n == nil)
124 return 1;
125
126 tn = znode;
127 tn.op = Oname;
128 tn.decl = v;
129 tn.src = v->src;
130 tn.ty = v->ty;
131 return initable(&tn, n, 0);
132 }
133
134 int
initable(Node * v,Node * n,int allocdep)135 initable(Node *v, Node *n, int allocdep)
136 {
137 Node *e;
138
139 switch(n->ty->kind){
140 case Tiface:
141 case Tgoto:
142 case Tcase:
143 case Tcasel:
144 case Tcasec:
145 case Talt:
146 case Texcept:
147 return 1;
148 case Tint:
149 case Tbig:
150 case Tbyte:
151 case Treal:
152 case Tstring:
153 case Tfix:
154 if(n->op != Oconst)
155 break;
156 return 1;
157 case Tadt:
158 case Tadtpick:
159 case Ttuple:
160 if(n->op == Otuple)
161 n = n->left;
162 else if(n->op == Ocall)
163 n = n->right;
164 else
165 break;
166 for(; n != nil; n = n->right)
167 if(!initable(v, n->left, allocdep))
168 return 0;
169 return 1;
170 case Tarray:
171 if(n->op != Oarray)
172 break;
173 if(allocdep >= DADEPTH){
174 nerror(v, "%Vs initializer has arrays nested more than %d deep", v, allocdep);
175 return 0;
176 }
177 allocdep++;
178 usedesc(mktdesc(n->ty->tof));
179 if(n->left->op != Oconst){
180 nerror(v, "%Vs size is not a constant", v);
181 return 0;
182 }
183 for(e = n->right; e != nil; e = e->right)
184 if(!initable(v, e->left->right, allocdep))
185 return 0;
186 return 1;
187 case Tany:
188 return 1;
189 case Tref:
190 case Tlist:
191 case Tpoly:
192 default:
193 nerror(v, "can't initialize %Q", v);
194 return 0;
195 }
196 nerror(v, "%Vs initializer, %V, is not a constant expression", v, n);
197 return 0;
198 }
199
200 /*
201 * merge together two sorted lists, yielding a sorted list
202 */
203 static Node*
elemmerge(Node * e,Node * f)204 elemmerge(Node *e, Node *f)
205 {
206 Node rock, *r;
207
208 r = &rock;
209 while(e != nil && f != nil){
210 if(e->left->left->val <= f->left->left->val){
211 r->right = e;
212 e = e->right;
213 }else{
214 r->right = f;
215 f = f->right;
216 }
217 r = r->right;
218 }
219 if(e != nil)
220 r->right = e;
221 else
222 r->right = f;
223 return rock.right;
224 }
225
226 /*
227 * recursively split lists and remerge them after they are sorted
228 */
229 static Node*
recelemsort(Node * e,int n)230 recelemsort(Node *e, int n)
231 {
232 Node *r, *ee;
233 int i, m;
234
235 if(n <= 1)
236 return e;
237 m = n / 2 - 1;
238 ee = e;
239 for(i = 0; i < m; i++)
240 ee = ee->right;
241 r = ee->right;
242 ee->right = nil;
243 return elemmerge(recelemsort(e, n / 2),
244 recelemsort(r, (n + 1) / 2));
245 }
246
247 /*
248 * sort the elems by index; wild card is first
249 */
250 Node*
elemsort(Node * e)251 elemsort(Node *e)
252 {
253 Node *ee;
254 int n;
255
256 n = 0;
257 for(ee = e; ee != nil; ee = ee->right){
258 if(ee->left->left->op == Owild)
259 ee->left->left->val = -1;
260 n++;
261 }
262 return recelemsort(e, n);
263 }
264
265 int
sametree(Node * n1,Node * n2)266 sametree(Node *n1, Node *n2)
267 {
268 if(n1 == n2)
269 return 1;
270 if(n1 == nil || n2 == nil)
271 return 0;
272 if(n1->op != n2->op || n1->ty != n2->ty)
273 return 0;
274 if(n1->op == Oconst){
275 switch(n1->ty->kind){
276 case Tbig:
277 case Tbyte:
278 case Tint:
279 return n1->val == n2->val;
280 case Treal:
281 return n1->rval == n2->rval;
282 case Tfix:
283 return n1->val == n2->val && tequal(n1->ty, n2->ty);
284 case Tstring:
285 return n1->decl->sym == n2->decl->sym;
286 }
287 return 0;
288 }
289 return n1->decl == n2->decl && sametree(n1->left, n2->left) && sametree(n1->right, n2->right);
290 }
291
292 int
occurs(Decl * d,Node * n)293 occurs(Decl *d, Node *n)
294 {
295 if(n == nil)
296 return 0;
297 if(n->op == Oname){
298 if(d == n->decl)
299 return 1;
300 return 0;
301 }
302 return occurs(d, n->left) + occurs(d, n->right);
303 }
304
305 /*
306 * left and right subtrees the same
307 */
308 Node*
folds(Node * n)309 folds(Node *n)
310 {
311 if(hasside(n, 1))
312 return n;
313 switch(n->op){
314 case Oeq:
315 case Oleq:
316 case Ogeq:
317 n->val = 1;
318 break;
319 case Osub:
320 n->val = 0;
321 n->rval = 0.0;
322 break;
323 case Oxor:
324 case Oneq:
325 case Olt:
326 case Ogt:
327 n->val = 0;
328 break;
329 case Oand:
330 case Oor:
331 case Oandand:
332 case Ooror:
333 return n->left;
334 default:
335 return n;
336 }
337 n->op = Oconst;
338 n->left = n->right = nil;
339 n->decl = nil;
340 return n;
341 }
342
343 /*
344 * constant folding for typechecked expressions,
345 */
346 Node*
fold(Node * n)347 fold(Node *n)
348 {
349 if(n == nil)
350 return nil;
351 if(debug['F'])
352 print("fold %n\n", n);
353 n = efold(n);
354 if(debug['F'])
355 print("folded %n\n", n);
356 return n;
357 }
358
359 Node*
efold(Node * n)360 efold(Node *n)
361 {
362 Decl *d;
363 Node *left, *right;
364
365 if(n == nil)
366 return nil;
367
368 left = n->left;
369 right = n->right;
370 switch(n->op){
371 case Oname:
372 d = n->decl;
373 if(d->importid != nil)
374 d = d->importid;
375 if(d->store != Dconst){
376 if(d->store == Dtag){
377 n->op = Oconst;
378 n->ty = tint;
379 n->val = d->tag;
380 }
381 break;
382 }
383 switch(n->ty->kind){
384 case Tbig:
385 n->op = Oconst;
386 n->val = d->init->val;
387 break;
388 case Tbyte:
389 n->op = Oconst;
390 n->val = d->init->val & 0xff;
391 break;
392 case Tint:
393 case Tfix:
394 n->op = Oconst;
395 n->val = d->init->val;
396 break;
397 case Treal:
398 n->op = Oconst;
399 n->rval = d->init->rval;
400 break;
401 case Tstring:
402 n->op = Oconst;
403 n->decl = d->init->decl;
404 break;
405 case Ttuple:
406 *n = *d->init;
407 break;
408 case Tadt:
409 *n = *d->init;
410 n = rewrite(n); /* was call */
411 break;
412 case Texception:
413 if(!n->ty->cons)
414 fatal("non-const exception type in efold");
415 n->op = Oconst;
416 break;
417 default:
418 fatal("unknown const type %T in efold", n->ty);
419 break;
420 }
421 break;
422 case Oadd:
423 left = efold(left);
424 right = efold(right);
425 n->left = left;
426 n->right = right;
427 if(n->ty == tstring && right->op == Oconst){
428 if(left->op == Oconst)
429 n = mksconst(&n->src, stringcat(left->decl->sym, right->decl->sym));
430 else if(left->op == Oadd && left->ty == tstring && left->right->op == Oconst){
431 left->right = mksconst(&n->src, stringcat(left->right->decl->sym, right->decl->sym));
432 n = left;
433 }
434 }
435 break;
436 case Olen:
437 left = efold(left);
438 n->left = left;
439 if(left->ty == tstring && left->op == Oconst)
440 n = mkconst(&n->src, utflen(left->decl->sym->name));
441 break;
442 case Oslice:
443 if(right->left->op == Onothing)
444 right->left = mkconst(&right->left->src, 0);
445 n->left = efold(left);
446 n->right = efold(right);
447 break;
448 case Oinds:
449 n->left = left = efold(left);
450 n->right = right = efold(right);
451 if(right->op == Oconst && left->op == Oconst){
452 ;
453 }
454 break;
455 case Ocast:
456 n->op = Ocast;
457 left = efold(left);
458 n->left = left;
459 if(n->ty == left->ty || n->ty->kind == Tfix && tequal(n->ty, left->ty))
460 return left;
461 if(left->op == Oconst)
462 return foldcast(n, left);
463 break;
464 case Odot:
465 case Omdot:
466 /*
467 * what about side effects from left?
468 */
469 d = right->decl;
470 switch(d->store){
471 case Dconst:
472 case Dtag:
473 case Dtype:
474 /*
475 * set it up as a name and let that case do the hard work
476 */
477 n->op = Oname;
478 n->decl = d;
479 n->left = nil;
480 n->right = nil;
481 return efold(n);
482 }
483 n->left = efold(left);
484 if(n->left->op == Otuple)
485 n = tuplemem(n->left, d);
486 else
487 n->right = efold(right);
488 break;
489 case Otagof:
490 if(n->decl != nil){
491 n->op = Oconst;
492 n->left = nil;
493 n->right = nil;
494 n->val = n->decl->tag;
495 return efold(n);
496 }
497 n->left = efold(left);
498 break;
499 case Oif:
500 n->left = left = efold(left);
501 n->right = right = efold(right);
502 if(left->op == Oconst){
503 if(left->val)
504 return right->left;
505 else
506 return right->right;
507 }
508 break;
509 default:
510 n->left = efold(left);
511 n->right = efold(right);
512 break;
513 }
514
515 left = n->left;
516 right = n->right;
517 if(left == nil)
518 return n;
519
520 if(right == nil){
521 if(left->op == Oconst){
522 if(left->ty == tint || left->ty == tbyte || left->ty == tbig)
523 return foldc(n);
524 if(left->ty == treal)
525 return foldr(n);
526 }
527 return n;
528 }
529
530 if(left->op == Oconst){
531 switch(n->op){
532 case Olsh:
533 case Orsh:
534 if(left->val == 0 && !hasside(right, 1))
535 return left;
536 break;
537 case Ooror:
538 if(left->ty == tint || left->ty == tbyte || left->ty == tbig){
539 if(left->val == 0){
540 n = mkbin(Oneq, right, mkconst(&right->src, 0));
541 n->ty = right->ty;
542 n->left->ty = right->ty;
543 return efold(n);
544 }
545 left->val = 1;
546 return left;
547 }
548 break;
549 case Oandand:
550 if(left->ty == tint || left->ty == tbyte || left->ty == tbig){
551 if(left->val == 0)
552 return left;
553 n = mkbin(Oneq, right, mkconst(&right->src, 0));
554 n->ty = right->ty;
555 n->left->ty = right->ty;
556 return efold(n);
557 }
558 break;
559 }
560 }
561 if(left->op == Oconst && right->op != Oconst
562 && opcommute[n->op]
563 && n->ty != tstring){
564 n->op = opcommute[n->op];
565 n->left = right;
566 n->right = left;
567 left = right;
568 right = n->right;
569 }
570 if(right->op == Oconst && left->op == n->op && left->right->op == Oconst
571 && (n->op == Oadd || n->op == Omul || n->op == Oor || n->op == Oxor || n->op == Oand)
572 && n->ty != tstring){
573 n->left = left->left;
574 left->left = right;
575 right = efold(left);
576 n->right = right;
577 left = n->left;
578 }
579 if(right->op == Oconst){
580 if(n->op == Oexp && left->ty == treal){
581 if(left->op == Oconst)
582 return foldr(n);
583 return n;
584 }
585 if(right->ty == tint || right->ty == tbyte || left->ty == tbig){
586 if(left->op == Oconst)
587 return foldc(n);
588 return foldvc(n);
589 }
590 if(right->ty == treal && left->op == Oconst)
591 return foldr(n);
592 }
593 if(sametree(left, right))
594 return folds(n);
595 return n;
596 }
597
598 /*
599 * does evaluating the node have any side effects?
600 */
601 int
hasside(Node * n,int strict)602 hasside(Node *n, int strict)
603 {
604 for(; n != nil; n = n->right){
605 if(sideeffect[n->op] && (strict || n->op != Oadr && n->op != Oind))
606 return 1;
607 if(hasside(n->left, strict))
608 return 1;
609 }
610 return 0;
611 }
612
613 int
hascall(Node * n)614 hascall(Node *n)
615 {
616 for(; n != nil; n = n->right){
617 if(n->op == Ocall || n->op == Ospawn)
618 return 1;
619 if(hascall(n->left))
620 return 1;
621 }
622 return 0;
623 }
624
625 int
hasasgns(Node * n)626 hasasgns(Node *n)
627 {
628 if(n == nil)
629 return 0;
630 if(n->op != Ocall && isused[n->op] && n->op != Onothing)
631 return 1;
632 return hasasgns(n->left) || hasasgns(n->right);
633 }
634
635 int
nodes(Node * n)636 nodes(Node *n)
637 {
638 if(n == nil)
639 return 0;
640 return 1+nodes(n->left)+nodes(n->right);
641 }
642
643 Node*
foldcast(Node * n,Node * left)644 foldcast(Node *n, Node *left)
645 {
646 Real r;
647 char *buf, *e;
648
649 switch(left->ty->kind){
650 case Tint:
651 left->val &= 0xffffffff;
652 if(left->val & 0x80000000)
653 left->val |= (Long)0xffffffff << 32;
654 return foldcasti(n, left);
655 case Tbyte:
656 left->val &= 0xff;
657 return foldcasti(n, left);
658 case Tbig:
659 return foldcasti(n, left);
660 case Treal:
661 switch(n->ty->kind){
662 case Tint:
663 case Tbyte:
664 case Tbig:
665 r = left->rval;
666 left->val = r < 0 ? r - .5 : r + .5;
667 break;
668 case Tfix:
669 left->val = real2fix(left->rval, n->ty);
670 break;
671 case Tstring:
672 buf = allocmem(NumSize);
673 e = seprint(buf, buf+NumSize, "%g", left->rval);
674 return mksconst(&n->src, enterstring(buf, e-buf));
675 default:
676 return n;
677 }
678 break;
679 case Tfix:
680 switch(n->ty->kind){
681 case Tint:
682 case Tbyte:
683 case Tbig:
684 left->val = fix2real(left->val, left->ty);
685 break;
686 case Treal:
687 left->rval = fix2real(left->val, left->ty);
688 break;
689 case Tfix:
690 if(tequal(left->ty, n->ty))
691 return left;
692 left->val = fix2fix(left->val, left->ty, n->ty);
693 break;
694 case Tstring:
695 buf = allocmem(NumSize);
696 e = seprint(buf, buf+NumSize, "%g", fix2real(left->val, left->ty));
697 return mksconst(&n->src, enterstring(buf, e-buf));
698 default:
699 return n;
700 }
701 break;
702 case Tstring:
703 switch(n->ty->kind){
704 case Tint:
705 case Tbyte:
706 case Tbig:
707 left->val = strtoi(left->decl->sym->name, 10);
708 break;
709 case Treal:
710 left->rval = strtod(left->decl->sym->name, nil);
711 break;
712 case Tfix:
713 left->val = real2fix(strtod(left->decl->sym->name, nil), n->ty);
714 break;
715 default:
716 return n;
717 }
718 break;
719 default:
720 return n;
721 }
722 left->ty = n->ty;
723 left->src = n->src;
724 return left;
725 }
726
727 /*
728 * left is some kind of int type
729 */
730 Node*
foldcasti(Node * n,Node * left)731 foldcasti(Node *n, Node *left)
732 {
733 char *buf, *e;
734
735 switch(n->ty->kind){
736 case Tint:
737 left->val &= 0xffffffff;
738 if(left->val & 0x80000000)
739 left->val |= (Long)0xffffffff << 32;
740 break;
741 case Tbyte:
742 left->val &= 0xff;
743 break;
744 case Tbig:
745 break;
746 case Treal:
747 left->rval = left->val;
748 break;
749 case Tfix:
750 left->val = real2fix(left->val, n->ty);
751 break;
752 case Tstring:
753 buf = allocmem(NumSize);
754 e = seprint(buf, buf+NumSize, "%lld", left->val);
755 return mksconst(&n->src, enterstring(buf, e-buf));
756 default:
757 return n;
758 }
759 left->ty = n->ty;
760 left->src = n->src;
761 return left;
762 }
763
764 /*
765 * right is a const int
766 */
767 Node*
foldvc(Node * n)768 foldvc(Node *n)
769 {
770 Node *left, *right;
771
772 left = n->left;
773 right = n->right;
774 switch(n->op){
775 case Oadd:
776 case Osub:
777 case Oor:
778 case Oxor:
779 case Olsh:
780 case Orsh:
781 case Ooror:
782 if(right->val == 0)
783 return left;
784 if(n->op == Ooror && !hasside(left, 1))
785 return right;
786 break;
787 case Oand:
788 if(right->val == 0 && !hasside(left, 1))
789 return right;
790 break;
791 case Omul:
792 if(right->val == 1)
793 return left;
794 if(right->val == 0 && !hasside(left, 1))
795 return right;
796 break;
797 case Odiv:
798 if(right->val == 1)
799 return left;
800 break;
801 case Omod:
802 if(right->val == 1 && !hasside(left, 1)){
803 right->val = 0;
804 return right;
805 }
806 break;
807 case Oexp:
808 if(right->val == 0){
809 right->val = 1;
810 return right;
811 }
812 if(right->val == 1)
813 return left;
814 break;
815 case Oandand:
816 if(right->val != 0)
817 return left;
818 if(!hasside(left, 1))
819 return right;
820 break;
821 case Oneq:
822 if(!isrelop[left->op])
823 return n;
824 if(right->val == 0)
825 return left;
826 n->op = Onot;
827 n->right = nil;
828 break;
829 case Oeq:
830 if(!isrelop[left->op])
831 return n;
832 if(right->val != 0)
833 return left;
834 n->op = Onot;
835 n->right = nil;
836 break;
837 }
838 return n;
839 }
840
841 /*
842 * left and right are const ints
843 */
844 Node*
foldc(Node * n)845 foldc(Node *n)
846 {
847 Node *left, *right;
848 Long lv, v;
849 int rv, nb;
850
851 left = n->left;
852 right = n->right;
853 switch(n->op){
854 case Oadd:
855 v = left->val + right->val;
856 break;
857 case Osub:
858 v = left->val - right->val;
859 break;
860 case Omul:
861 v = left->val * right->val;
862 break;
863 case Odiv:
864 if(right->val == 0){
865 nerror(n, "divide by 0 in constant expression");
866 return n;
867 }
868 v = left->val / right->val;
869 break;
870 case Omod:
871 if(right->val == 0){
872 nerror(n, "mod by 0 in constant expression");
873 return n;
874 }
875 v = left->val % right->val;
876 break;
877 case Oexp:
878 if(left->val == 0 && right->val < 0){
879 nerror(n, "0 to negative power in constant expression");
880 return n;
881 }
882 v = ipow(left->val, right->val);
883 break;
884 case Oand:
885 v = left->val & right->val;
886 break;
887 case Oor:
888 v = left->val | right->val;
889 break;
890 case Oxor:
891 v = left->val ^ right->val;
892 break;
893 case Olsh:
894 lv = left->val;
895 rv = right->val;
896 if(rv < 0 || rv >= n->ty->size * 8){
897 nwarn(n, "shift amount %d out of range", rv);
898 rv = 0;
899 }
900 if(rv == 0){
901 v = lv;
902 break;
903 }
904 v = lv << rv;
905 break;
906 case Orsh:
907 lv = left->val;
908 rv = right->val;
909 nb = n->ty->size * 8;
910 if(rv < 0 || rv >= nb){
911 nwarn(n, "shift amount %d out of range", rv);
912 rv = 0;
913 }
914 if(rv == 0){
915 v = lv;
916 break;
917 }
918 v = lv >> rv;
919
920 /*
921 * properly sign extend c right shifts
922 */
923 if((n->ty == tint || n->ty == tbig)
924 && rv != 0
925 && (lv & (1<<(nb-1)))){
926 lv = 0;
927 lv = ~lv;
928 v |= lv << (nb - rv);
929 }
930 break;
931 case Oneg:
932 v = -left->val;
933 break;
934 case Ocomp:
935 v = ~left->val;
936 break;
937 case Oeq:
938 v = left->val == right->val;
939 break;
940 case Oneq:
941 v = left->val != right->val;
942 break;
943 case Ogt:
944 v = left->val > right->val;
945 break;
946 case Ogeq:
947 v = left->val >= right->val;
948 break;
949 case Olt:
950 v = left->val < right->val;
951 break;
952 case Oleq:
953 v = left->val <= right->val;
954 break;
955 case Oandand:
956 v = left->val && right->val;
957 break;
958 case Ooror:
959 v = left->val || right->val;
960 break;
961 case Onot:
962 v = !left->val;
963 break;
964 default:
965 return n;
966 }
967 if(n->ty == tint){
968 v &= 0xffffffff;
969 if(v & 0x80000000)
970 v |= (Long)0xffffffff << 32;
971 }else if(n->ty == tbyte)
972 v &= 0xff;
973 n->left = nil;
974 n->right = nil;
975 n->decl = nil;
976 n->op = Oconst;
977 n->val = v;
978 return n;
979 }
980
981 /*
982 * left and right are const reals
983 */
984 Node*
foldr(Node * n)985 foldr(Node *n)
986 {
987 Node *left, *right;
988 double rv;
989 Long v;
990
991 rv = 0.;
992 v = 0;
993
994 left = n->left;
995 right = n->right;
996 switch(n->op){
997 case Ocast:
998 return n;
999 case Oadd:
1000 rv = left->rval + right->rval;
1001 break;
1002 case Osub:
1003 rv = left->rval - right->rval;
1004 break;
1005 case Omul:
1006 rv = left->rval * right->rval;
1007 break;
1008 case Odiv:
1009 rv = left->rval / right->rval;
1010 break;
1011 case Oexp:
1012 rv = rpow(left->rval, right->val);
1013 break;
1014 case Oneg:
1015 rv = -left->rval;
1016 break;
1017 case Oinv:
1018 if(left->rval == 0.0){
1019 error(n->src.start, "divide by 0 in fixed point type");
1020 return n;
1021 }
1022 rv = 1/left->rval;
1023 break;
1024 case Oeq:
1025 v = left->rval == right->rval;
1026 break;
1027 case Oneq:
1028 v = left->rval != right->rval;
1029 break;
1030 case Ogt:
1031 v = left->rval > right->rval;
1032 break;
1033 case Ogeq:
1034 v = left->rval >= right->rval;
1035 break;
1036 case Olt:
1037 v = left->rval < right->rval;
1038 break;
1039 case Oleq:
1040 v = left->rval <= right->rval;
1041 break;
1042 default:
1043 return n;
1044 }
1045 n->left = nil;
1046 n->right = nil;
1047
1048 if(isNaN(rv))
1049 rv = canonnan;
1050
1051 n->rval = rv;
1052 n->val = v;
1053
1054 n->op = Oconst;
1055 return n;
1056 }
1057
1058 Node*
varinit(Decl * d,Node * e)1059 varinit(Decl *d, Node *e)
1060 {
1061 Node *n;
1062
1063 n = mkdeclname(&e->src, d);
1064 if(d->next == nil)
1065 return mkbin(Oas, n, e);
1066 return mkbin(Oas, n, varinit(d->next, e));
1067 }
1068
1069 /*
1070 * given: an Oseq list with left == next or the last child
1071 * make a list with the right == next
1072 * ie: Oseq(Oseq(a, b),c) ==> Oseq(a, Oseq(b, Oseq(c, nil))))
1073 */
1074 Node*
rotater(Node * e)1075 rotater(Node *e)
1076 {
1077 Node *left;
1078
1079 if(e == nil)
1080 return e;
1081 if(e->op != Oseq)
1082 return mkunary(Oseq, e);
1083 e->right = mkunary(Oseq, e->right);
1084 while(e->left->op == Oseq){
1085 left = e->left;
1086 e->left = left->right;
1087 left->right = e;
1088 e = left;
1089 }
1090 return e;
1091 }
1092
1093 /*
1094 * reverse the case labels list
1095 */
1096 Node*
caselist(Node * s,Node * nr)1097 caselist(Node *s, Node *nr)
1098 {
1099 Node *r;
1100
1101 r = s->right;
1102 s->right = nr;
1103 if(r == nil)
1104 return s;
1105 return caselist(r, s);
1106 }
1107
1108 /*
1109 * e is a seq of expressions; make into cons's to build a list
1110 */
1111 Node*
etolist(Node * e)1112 etolist(Node *e)
1113 {
1114 Node *left, *n;
1115
1116 if(e == nil)
1117 return nil;
1118 n = mknil(&e->src);
1119 n->src.start = n->src.stop;
1120 if(e->op != Oseq)
1121 return mkbin(Ocons, e, n);
1122 e->right = mkbin(Ocons, e->right, n);
1123 while(e->left->op == Oseq){
1124 e->op = Ocons;
1125 left = e->left;
1126 e->left = left->right;
1127 left->right = e;
1128 e = left;
1129 }
1130 e->op = Ocons;
1131 return e;
1132 }
1133
1134 Node*
dupn(int resrc,Src * src,Node * n)1135 dupn(int resrc, Src *src, Node *n)
1136 {
1137 Node *nn;
1138
1139 nn = allocmem(sizeof *nn);
1140 *nn = *n;
1141 if(resrc)
1142 nn->src = *src;
1143 if(nn->left != nil)
1144 nn->left = dupn(resrc, src, nn->left);
1145 if(nn->right != nil)
1146 nn->right = dupn(resrc, src, nn->right);
1147 return nn;
1148 }
1149
1150 Node*
mkn(int op,Node * left,Node * right)1151 mkn(int op, Node *left, Node *right)
1152 {
1153 Node *n;
1154
1155 n = allocmem(sizeof *n);
1156 *n = znode;
1157 n->op = op;
1158 n->left = left;
1159 n->right = right;
1160 return n;
1161 }
1162
1163 Node*
mkunary(int op,Node * left)1164 mkunary(int op, Node *left)
1165 {
1166 Node *n;
1167
1168 n = mkn(op, left, nil);
1169 n->src = left->src;
1170 return n;
1171 }
1172
1173 Node*
mkbin(int op,Node * left,Node * right)1174 mkbin(int op, Node *left, Node *right)
1175 {
1176 Node *n;
1177
1178 n = mkn(op, left, right);
1179 n->src.start = left->src.start;
1180 n->src.stop = right->src.stop;
1181 return n;
1182 }
1183
1184 Node*
mkdeclname(Src * src,Decl * d)1185 mkdeclname(Src *src, Decl *d)
1186 {
1187 Node *n;
1188
1189 n = mkn(Oname, nil, nil);
1190 n->src = *src;
1191 n->decl = d;
1192 n->ty = d->ty;
1193 d->refs++;
1194 return n;
1195 }
1196
1197 Node*
mknil(Src * src)1198 mknil(Src *src)
1199 {
1200 return mkdeclname(src, nildecl);
1201 }
1202
1203 Node*
mkname(Src * src,Sym * s)1204 mkname(Src *src, Sym *s)
1205 {
1206 Node *n;
1207
1208 n = mkn(Oname, nil, nil);
1209 n->src = *src;
1210 if(s->unbound == nil){
1211 s->unbound = mkdecl(src, Dunbound, nil);
1212 s->unbound->sym = s;
1213 }
1214 n->decl = s->unbound;
1215 return n;
1216 }
1217
1218 Node*
mkconst(Src * src,Long v)1219 mkconst(Src *src, Long v)
1220 {
1221 Node *n;
1222
1223 n = mkn(Oconst, nil, nil);
1224 n->ty = tint;
1225 n->val = v;
1226 n->src = *src;
1227 return n;
1228 }
1229
1230 Node*
mkrconst(Src * src,Real v)1231 mkrconst(Src *src, Real v)
1232 {
1233 Node *n;
1234
1235 n = mkn(Oconst, nil, nil);
1236 n->ty = treal;
1237 n->rval = v;
1238 n->src = *src;
1239 return n;
1240 }
1241
1242 Node*
mksconst(Src * src,Sym * s)1243 mksconst(Src *src, Sym *s)
1244 {
1245 Node *n;
1246
1247 n = mkn(Oconst, nil, nil);
1248 n->ty = tstring;
1249 n->decl = mkdecl(src, Dconst, tstring);
1250 n->decl->sym = s;
1251 n->src = *src;
1252 return n;
1253 }
1254
1255 int
opconv(Fmt * f)1256 opconv(Fmt *f)
1257 {
1258 int op;
1259 char buf[32];
1260
1261 op = va_arg(f->args, int);
1262 if(op < 0 || op > Oend) {
1263 seprint(buf, buf+sizeof(buf), "op %d", op);
1264 return fmtstrcpy(f, buf);
1265 }
1266 return fmtstrcpy(f, opname[op]);
1267 }
1268
1269 int
etconv(Fmt * f)1270 etconv(Fmt *f)
1271 {
1272 Node *n;
1273 char buf[1024];
1274
1275 n = va_arg(f->args, Node*);
1276 if(n->ty == tany || n->ty == tnone || n->ty == terror)
1277 seprint(buf, buf+sizeof(buf), "%V", n);
1278 else
1279 seprint(buf, buf+sizeof(buf), "%V of type %T", n, n->ty);
1280 return fmtstrcpy(f, buf);
1281 }
1282
1283 int
expconv(Fmt * f)1284 expconv(Fmt *f)
1285 {
1286 Node *n;
1287 char buf[4096], *p;
1288
1289 n = va_arg(f->args, Node*);
1290 p = buf;
1291 *p = 0;
1292 if(f->r == 'V')
1293 *p++ = '\'';
1294 p = eprint(p, buf+sizeof(buf)-1, n);
1295 if(f->r == 'V')
1296 *p++ = '\'';
1297 *p = 0;
1298 return fmtstrcpy(f, buf);
1299 }
1300
1301 char*
eprint(char * buf,char * end,Node * n)1302 eprint(char *buf, char *end, Node *n)
1303 {
1304 if(n == nil)
1305 return buf;
1306 if(n->flags & PARENS)
1307 buf = secpy(buf, end, "(");
1308 switch(n->op){
1309 case Obreak:
1310 case Ocont:
1311 buf = secpy(buf, end, opname[n->op]);
1312 if(n->decl != nil){
1313 buf = seprint(buf, end, " %s", n->decl->sym->name);
1314 }
1315 break;
1316 case Oexit:
1317 case Owild:
1318 buf = secpy(buf, end, opname[n->op]);
1319 break;
1320 case Onothing:
1321 break;
1322 case Oadr:
1323 case Oused:
1324 buf = eprint(buf, end, n->left);
1325 break;
1326 case Oseq:
1327 buf = eprintlist(buf, end, n, ", ");
1328 break;
1329 case Oname:
1330 if(n->decl == nil)
1331 buf = secpy(buf, end, "<nil>");
1332 else
1333 buf = seprint(buf, end, "%s", n->decl->sym->name);
1334 break;
1335 case Oconst:
1336 if(n->ty->kind == Tstring){
1337 buf = stringpr(buf, end, n->decl->sym);
1338 break;
1339 }
1340 if(n->decl != nil && n->decl->sym != nil){
1341 buf = seprint(buf, end, "%s", n->decl->sym->name);
1342 break;
1343 }
1344 switch(n->ty->kind){
1345 case Tint:
1346 case Tbyte:
1347 buf = seprint(buf, end, "%ld", (long)n->val);
1348 break;
1349 case Tbig:
1350 buf = seprint(buf, end, "%lld", n->val);
1351 break;
1352 case Treal:
1353 buf = seprint(buf, end, "%g", n->rval);
1354 break;
1355 case Tfix:
1356 buf = seprint(buf, end, "%ld(%g)", (long)n->val, n->ty->val->rval);
1357 break;
1358 default:
1359 buf = secpy(buf, end, opname[n->op]);
1360 break;
1361 }
1362 break;
1363 case Ocast:
1364 buf = seprint(buf, end, "%T ", n->ty);
1365 buf = eprint(buf, end, n->left);
1366 break;
1367 case Otuple:
1368 if(n->ty != nil && n->ty->kind == Tadt)
1369 buf = seprint(buf, end, "%s", n->ty->decl->sym->name);
1370 buf = seprint(buf, end, "(");
1371 buf = eprintlist(buf, end, n->left, ", ");
1372 buf = secpy(buf, end, ")");
1373 break;
1374 case Ochan:
1375 if(n->left){
1376 buf = secpy(buf, end, "chan [");
1377 buf = eprint(buf, end, n->left);
1378 buf = secpy(buf, end, "] of ");
1379 buf = seprint(buf, end, "%T", n->ty->tof);
1380 }else
1381 buf = seprint(buf, end, "chan of %T", n->ty->tof);
1382 break;
1383 case Oarray:
1384 buf = secpy(buf, end, "array [");
1385 if(n->left != nil)
1386 buf = eprint(buf, end, n->left);
1387 buf = secpy(buf, end, "] of ");
1388 if(n->right != nil){
1389 buf = secpy(buf, end, "{");
1390 buf = eprintlist(buf, end, n->right, ", ");
1391 buf = secpy(buf, end, "}");
1392 }else{
1393 buf = seprint(buf, end, "%T", n->ty->tof);
1394 }
1395 break;
1396 case Oelem:
1397 case Olabel:
1398 if(n->left != nil){
1399 buf = eprintlist(buf, end, n->left, " or ");
1400 buf = secpy(buf, end, " =>");
1401 }
1402 buf = eprint(buf, end, n->right);
1403 break;
1404 case Orange:
1405 buf = eprint(buf, end, n->left);
1406 buf = secpy(buf, end, " to ");
1407 buf = eprint(buf, end, n->right);
1408 break;
1409 case Ospawn:
1410 buf = secpy(buf, end, "spawn ");
1411 buf = eprint(buf, end, n->left);
1412 break;
1413 case Oraise:
1414 buf = secpy(buf, end, "raise ");
1415 buf = eprint(buf, end, n->left);
1416 break;
1417 case Ocall:
1418 buf = eprint(buf, end, n->left);
1419 buf = secpy(buf, end, "(");
1420 buf = eprintlist(buf, end, n->right, ", ");
1421 buf = secpy(buf, end, ")");
1422 break;
1423 case Oinc:
1424 case Odec:
1425 buf = eprint(buf, end, n->left);
1426 buf = secpy(buf, end, opname[n->op]);
1427 break;
1428 case Oindex:
1429 case Oindx:
1430 case Oinds:
1431 buf = eprint(buf, end, n->left);
1432 buf = secpy(buf, end, "[");
1433 buf = eprint(buf, end, n->right);
1434 buf = secpy(buf, end, "]");
1435 break;
1436 case Oslice:
1437 buf = eprint(buf, end, n->left);
1438 buf = secpy(buf, end, "[");
1439 buf = eprint(buf, end, n->right->left);
1440 buf = secpy(buf, end, ":");
1441 buf = eprint(buf, end, n->right->right);
1442 buf = secpy(buf, end, "]");
1443 break;
1444 case Oload:
1445 buf = seprint(buf, end, "load %T ", n->ty);
1446 buf = eprint(buf, end, n->left);
1447 break;
1448 case Oref:
1449 case Olen:
1450 case Ohd:
1451 case Otl:
1452 case Otagof:
1453 buf = secpy(buf, end, opname[n->op]);
1454 buf = secpy(buf, end, " ");
1455 buf = eprint(buf, end, n->left);
1456 break;
1457 default:
1458 if(n->right == nil){
1459 buf = secpy(buf, end, opname[n->op]);
1460 buf = eprint(buf, end, n->left);
1461 }else{
1462 buf = eprint(buf, end, n->left);
1463 buf = secpy(buf, end, opname[n->op]);
1464 buf = eprint(buf, end, n->right);
1465 }
1466 break;
1467 }
1468 if(n->flags & PARENS)
1469 buf = secpy(buf, end, ")");
1470 return buf;
1471 }
1472
1473 char*
eprintlist(char * buf,char * end,Node * elist,char * sep)1474 eprintlist(char *buf, char *end, Node *elist, char *sep)
1475 {
1476 if(elist == nil)
1477 return buf;
1478 for(; elist->right != nil; elist = elist->right){
1479 if(elist->op == Onothing)
1480 continue;
1481 if(elist->left->op == Ofnptr)
1482 return buf;
1483 buf = eprint(buf, end, elist->left);
1484 if(elist->right->left->op != Ofnptr)
1485 buf = secpy(buf, end, sep);
1486 }
1487 buf = eprint(buf, end, elist->left);
1488 return buf;
1489 }
1490
1491 int
nodeconv(Fmt * f)1492 nodeconv(Fmt *f)
1493 {
1494 Node *n;
1495 char buf[4096];
1496
1497 n = va_arg(f->args, Node*);
1498 buf[0] = 0;
1499 nprint(buf, buf+sizeof(buf), n, 0);
1500 return fmtstrcpy(f, buf);
1501 }
1502
1503 char*
nprint(char * buf,char * end,Node * n,int indent)1504 nprint(char *buf, char *end, Node *n, int indent)
1505 {
1506 int i;
1507
1508 if(n == nil)
1509 return buf;
1510 buf = seprint(buf, end, "\n");
1511 for(i = 0; i < indent; i++)
1512 if(buf < end-1)
1513 *buf++ = ' ';
1514 switch(n->op){
1515 case Oname:
1516 if(n->decl == nil)
1517 buf = secpy(buf, end, "name <nil>");
1518 else
1519 buf = seprint(buf, end, "name %s", n->decl->sym->name);
1520 break;
1521 case Oconst:
1522 if(n->decl != nil && n->decl->sym != nil)
1523 buf = seprint(buf, end, "const %s", n->decl->sym->name);
1524 else
1525 buf = seprint(buf, end, "%O", n->op);
1526 if(n->ty == tint || n->ty == tbyte || n->ty == tbig)
1527 buf = seprint(buf, end, " (%ld)", (long)n->val);
1528 break;
1529 default:
1530 buf = seprint(buf, end, "%O", n->op);
1531 break;
1532 }
1533 buf = seprint(buf, end, " %T %d %d", n->ty, n->addable, n->temps);
1534 indent += 2;
1535 buf = nprint(buf, end, n->left, indent);
1536 buf = nprint(buf, end, n->right, indent);
1537 return buf;
1538 }
1539