xref: /inferno-os/limbo/nodes.c (revision 1e1b493dfc048d301ef6b41377f0a3665ee7f3fc)
1 #include "limbo.h"
2 
3 static vlong
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
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
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
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
70 fix2real(Long v, Type *f)
71 {
72 	return (double)v * scale(f);
73 }
74 
75 int
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*
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
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
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*
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*
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*
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
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
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*
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*
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*
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
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
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
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
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*
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*
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*
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*
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*
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*
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*
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*
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*
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*
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*
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*
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*
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*
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*
1198 mknil(Src *src)
1199 {
1200 	return mkdeclname(src, nildecl);
1201 }
1202 
1203 Node*
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*
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*
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*
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
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
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
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*
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*
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
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*
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