xref: /inferno-os/utils/c2l/c2l.c (revision 50b0dbb170df61467e42c7ea4deb0b5692d15f4c)
1 #define EXTERN
2 
3 #include "cc.h"
4 
5 /*
6  *	locals, parameters, globals etc of the same name should work ok without having
7  *	to duplicate Syms because the details are on the containing Nodes
8  */
9 
10 #define SZ_CHAR	1
11 #define SZ_SHORT	2
12 #define SZ_INT	4
13 #define SZ_LONG	4
14 #define SZ_FLOAT	4
15 #define SZ_IND	4
16 #define SZ_VLONG	8
17 #define SZ_DOUBLE	8
18 
19 char buf[128], mbuf[128];
20 static Sym *sysop, *bioop, *libcop;
21 static int again;
22 
23 #define	STAR	0x80
24 #define	RET		0x80
25 
26 #define	LARR	(-1729)
27 
28 static void swalk(void);
29 static int isdec(Node*);
30 static int isconst(Node*, vlong);
31 static int cktype(Node*, Node*, int, int);
32 static void addnode(int, Node*);
33 static int argpos(Node*, Node*);
34 static void setdec(Sym*, Type*);
35 static Type* tcp(Type*);
36 static int isadt(Type*);
37 static void aargs(Node*);
38 static int iteq(Type*, Type*);
39 static Node* arg(Node*, int);
40 static void etgen2(Sym*);
41 static Node* ckneg(Node*);
42 static Sym* suename(Type*);
43 static int isnil(Node*);
44 static void sliceasgn(Node*);
45 static Node* lastn(Node*);
46 static char* hasm(void);
47 static void prn(Node*, int);
48 static int isfn(Type*);
49 
50 schar	ewidth[NTYPE] =
51 {
52 	-1,		/* [TXXX] */
53 	SZ_CHAR,	/* [TCHAR] */
54 	SZ_CHAR,	/* [TUCHAR] */
55 	SZ_SHORT,	/* [TSHORT] */
56 	SZ_SHORT,	/* [TUSHORT] */
57 	SZ_INT,		/* [TINT] */
58 	SZ_INT,		/* [TUINT] */
59 	SZ_LONG,	/* [TLONG] */
60 	SZ_LONG,	/* [TULONG] */
61 	SZ_VLONG,	/* [TVLONG] */
62 	SZ_VLONG,	/* [TUVLONG] */
63 	SZ_FLOAT,	/* [TFLOAT] */
64 	SZ_DOUBLE,	/* [TDOUBLE] */
65 	SZ_IND,		/* [TIND] */
66 	0,		/* [TFUNC] */
67 	-1,		/* [TARRAY] */
68 	0,		/* [TVOID] */
69 	-1,		/* [TSTRUCT] */
70 	-1,		/* [TUNION] */
71 	SZ_INT,		/* [TENUM] */
72 };
73 
74 long	ncast[NTYPE] =
75 {
76 	0,				/* [TXXX] */
77 	BCHAR|BUCHAR,			/* [TCHAR] */
78 	BCHAR|BUCHAR,			/* [TUCHAR] */
79 	BSHORT|BUSHORT,			/* [TSHORT] */
80 	BSHORT|BUSHORT,			/* [TUSHORT] */
81 	BINT|BUINT|BLONG|BULONG|BIND,	/* [TINT] */
82 	BINT|BUINT|BLONG|BULONG|BIND,	/* [TUINT] */
83 	BINT|BUINT|BLONG|BULONG|BIND,	/* [TLONG] */
84 	BINT|BUINT|BLONG|BULONG|BIND,	/* [TULONG] */
85 	BVLONG|BUVLONG,			/* [TVLONG] */
86 	BVLONG|BUVLONG,			/* [TUVLONG] */
87 	BFLOAT,				/* [TFLOAT] */
88 	BDOUBLE,			/* [TDOUBLE] */
89 	BLONG|BULONG|BIND,		/* [TIND] */
90 	0,				/* [TFUNC] */
91 	0,				/* [TARRAY] */
92 	0,				/* [TVOID] */
93 	BSTRUCT,			/* [TSTRUCT] */
94 	BUNION,				/* [TUNION] */
95 	0,				/* [TENUM] */
96 };
97 
98 enum{
99 	TCFD = 1,
100 	TCFC = 2,
101 	TCPC = 4,
102 	TCAR = 8,
103 	TCIN = 16,
104 	TCGEN = TCFD|TCFC|TCPC|TCAR,
105 	TCALL = TCFD|TCFC|TCPC|TCAR|TCIN,
106 };
107 
108 enum{
109 	SGLOB,
110 	SPARM,
111 	SAUTO,
112 };
113 
114 typedef struct Scope Scope;
115 
116 struct Scope{
117 	Node *n;
118 	int	k;
119 	Scope *nxt;
120 };
121 
122 static void
123 prtyp(Type *t, char *s, int nl)
124 {
125 	print("%s: ", s);
126 	if(t == T){
127 		print("nil");
128 		if(nl)
129 			print("\n");
130 		return;
131 	}
132 	while(t != T){
133 		print("%d(%d)[%x] ", t->etype, t->mark, (int)t);
134 		if(isadt(t))
135 			break;
136 		t = t->link;
137 	}
138 	if(nl)
139 		print("\n");
140 }
141 
142 static Node*
143 func(Node *n)
144 {
145 	while(n != Z && n->op != OFUNC)
146 		n = n->left;
147 	return n;
148 }
149 
150 static void
151 setmain(Node *n)
152 {
153 	inmain |= n->left->op == ONAME && strcmp(n->left->sym->name, "main") == 0;
154 }
155 
156 static Node*
157 protoname(Node *n)
158 {
159 	do
160 		n = n->left;
161 	while(n != Z && n->op != ONAME && n->op != ODOTDOT);
162 	return n;
163 }
164 
165 static Type*
166 prototype(Node *n, Type *t)
167 {
168 	for( ; n != Z ; n = n->left){
169 		switch(n->op){
170 		case OARRAY:
171 			t = typ(TARRAY, t);
172 			t->width = 0;
173 			break;
174 		case OIND:
175 			t = typ(TIND, t);
176 			break;
177 		case OFUNC:
178 			t = typ(TFUNC, t);
179 			t->down = fnproto(n);
180 			break;
181 		}
182 	}
183 	return t;
184 }
185 
186 static Scope *scopes, *freescopes;
187 
188 static void
189 pushdcl(Node *n, int c)
190 {
191 	Sym *s;
192 
193 	if(passes){
194 		s = n->sym;
195 		push1(s);
196 		if(c != CAUTO || s->class != CSTATIC)
197 			s->class = c;
198 		s->type = n->type;
199 	}
200 }
201 
202 static void
203 pushparams(Node *n)
204 {
205 	if(n == Z)
206 		return;
207 	if(passes){
208 		if(n->op == OLIST){
209 			pushparams(n->left);
210 			pushparams(n->right);
211 		}
212 		else if(n->op == OPROTO){
213 			n = protoname(n);
214 			if(n != Z && n->op == ONAME)
215 				pushdcl(n, CPARAM);
216 		}
217 		else if(n->op == ONAME){
218 			addnode(OPROTO, n);
219 			pushdcl(n, CPARAM);
220 		}
221 		else if(n->op != ODOTDOT)
222 			diag(Z, "bad op in pushparams");
223 	}
224 }
225 
226 static void
227 pushscope(Node *n, int k)
228 {
229 	Scope *s;
230 
231 	if(freescopes != nil){
232 		s = freescopes;
233 		freescopes = freescopes->nxt;
234 	}
235 	else
236 		s = (Scope*)malloc(sizeof(Scope));
237 	s->n = n;
238 	s->k = k;
239 	s->nxt = scopes;
240 	scopes = s;
241 	if(passes && (k == SPARM || k == SAUTO))
242 		markdcl();
243 	if(k == SPARM)
244 		pushparams(n->right);
245 }
246 
247 static void
248 popscope(void)
249 {
250 	int k;
251 	Scope *s;
252 
253 	s = scopes;
254 	k = s->k;
255 	scopes = scopes->nxt;
256 	s->nxt = freescopes;
257 	freescopes = s;
258 	if(passes && (k == SPARM || k == SAUTO))
259 		revertdcl();
260 }
261 
262 static Node*
263 curfn(void)
264 {
265 	Scope *s;
266 
267 	for(s = scopes; s != nil; s = s->nxt)
268 		if(s->k == SPARM)
269 			return s->n;
270 	return Z;
271 }
272 
273 static void
274 marktype(Type *t, int tc)
275 {
276 	t->mark = tc;
277 }
278 
279 static int
280 marked(Type *t)
281 {
282 	return t == T ? 0 :  t->mark;
283 }
284 
285 static Sym*
286 decsym(Node *n)
287 {
288 	if(n == Z)
289 		return S;
290 	if(n->op == OFUNC){
291 		if(n->left->op == ONAME)
292 			return n->left->sym;
293 		return S;
294 	}
295 	if(n->op == ODAS)
296 		return n->left->sym;
297 	return n->sym;
298 }
299 
300 static void
301 trep(Type *t1, Type *t)
302 {
303 	int l;
304 	Sym *s;
305 	Type *t2;
306 
307 	if(t1 != T){
308 		l = t1->lineno;
309 		s = t1->sym;
310 		t2 = t1->down;
311 		*t1 = *t;
312 		t1->down = t2;
313 		t1->sym = s;
314 		t1->lineno = l;
315 	}
316 }
317 
318 static void
319 tind(Node *n)
320 {
321 	if(n == Z)
322 		return;
323 	n = protoname(n);
324 	if(n != Z && n->type != T){
325 		n->type = tcp(n->type->link);
326 		marktype(n->type, TCIN);
327 	}
328 }
329 
330 static void
331 tcon(Node *n, Type *t)
332 {
333 	Type *tt;
334 
335 	if(n->garb)
336 		return;
337 	n->garb = 1;
338 	again = 1;
339 	switch(n->op){
340 		case OCONST:
341 			if(t->mark == TCFD && !isnil(n))
342 				addnode(OFILDES, n);
343 			n->type = t;
344 			break;
345 		case OCAST:
346 			tcon(n->left, t);
347 			*n = *n->left;
348 			n->type = t;
349 			break;
350 		case ONAME:
351 			n->sym->type = t;
352 			n->type = t;
353 			setdec(n->sym, t);
354 			break;
355 		case ODOT:
356 		case ODOTIND:
357 			trep(n->type, t);
358 			n->type = t;
359 			break;
360 		case OARRIND:
361 			tt = n->left->type;
362 			if(tt != T)
363 				tt->link = t;
364 			n->type = t;
365 			break;
366 		case OFUNC:
367 			n->left->type->link = t;
368 			if(n->left->op == ONAME)
369 				n->left->sym->type->link = t;
370 			n->type = t;
371 			break;
372 	}
373 }
374 
375 static Node*
376 retval(Node *n)
377 {
378 	int i;
379 	Type *t;
380 	Node *a, *l, *cf;
381 
382 	cf = curfn();
383 	t = cf->left->type->link;
384 	if(t->mark&(TCPC|TCFC) && (n == Z || !(n->type->mark&(TCPC|TCFC)))){
385 		if(n == Z)
386 			n = new1(ORETURN, Z, Z);
387 		l = n->left;
388 		for(i = 0; ; i++){
389 			a = arg(cf->right, i);
390 			if(a == Z)
391 				break;
392 			a = protoname(a);
393 			if(a == Z || a->op != ONAME)
394 				break;
395 			if(a->type->mark == TCIN){
396 				if(l == Z)
397 					l = ncopy(a);
398 				else
399 					l = new1(OTUPLE, l, ncopy(a));
400 			}
401 		}
402 		n->left = l;
403 		n->type = l->type = t;
404 	}
405 	return n;
406 }
407 
408 static void
409 sube(Node *n)
410 {
411 	Node *l, *r, *nn;
412 	Type *tt;
413 	static Node *gn;
414 	int p;
415 
416 	if(n == Z)
417 		return;
418 	l = n->left;
419 	r = n->right;
420 	switch(n->op){
421 		default:
422 			sube(l);
423 			sube(r);
424 			break;
425 		case OIND:
426 			if(l == Z)
427 				return;
428 			tt = l->type;
429 			sube(l);
430 			if(cktype(l, n, TCIN, 0) && iteq(tt, l->type))
431 				*n = *n->left;
432 			break;
433 		case OARRIND:
434 			tt = l->type;
435 			sube(l);
436 			sube(r);
437 			if(!isconst(r, 0))
438 				break;
439 			if(cktype(l, n, TCIN, 0) && iteq(tt, l->type))
440 				*n = *n->left;
441 			break;
442 		case ONAME:
443 			if(cktype(n, n, TCALL, 0))
444 				setdec(n->sym, n->type);
445 			break;
446 		case OCAST:
447 			sube(l);
448 			if(cktype(l, n, TCALL, 0))
449 				n->type = l->type;
450 			break;
451 		case OPROTO:
452 			sube(l);
453 			sube(r);
454 			nn = protoname(n);
455 			if(nn != Z && cktype(nn, n, TCALL, 0)){
456 				n->type = nn->type;
457 				p = argpos(n, gn->right);
458 				for(tt = gn->left->type->down; tt != T && p >= 0; tt = tt->down){
459 					if(p == 0){
460 						trep(tt, nn->type);
461 						break;
462 					}
463 					--p;
464 				}
465 			}
466 			break;
467 		case OFUNC:
468 			if(n->kind == KEXP)
469 				aargs(n);
470 			if(n->left->op == ONAME)
471 				gn = n;
472 			sube(l);
473 			sube(r);
474 			if(l != Z && cktype(n, n, TCGEN, 0))
475 				l->type->link = n->type;
476 			break;
477 		case OAS:
478 			sube(l);
479 			sube(r);
480 			if(r->op == ORETV){
481 				n->left = new1(OTUPLE, l, r->right);
482 				n->right = r->left;
483 				n->left->type = n->type;
484 				break;
485 			}
486 			if(cktype(r, n, TCGEN, 0)){
487 				tcon(l, r->type);
488 				n->type = r->type;
489 			}
490 			if(cktype(l, n, TCGEN, 1)){
491 				tcon(r, l->type);
492 				n->type = l->type;
493 			}
494 			break;
495 		case OLT:
496 		case OGE:
497 			sube(l);
498 			sube(r);
499 			if(cktype(l, n, TCFD, 0) && isconst(r, 0)){
500 				n->op = n->op == OLT ? OEQ : ONE;
501 				r->op = ONIL;
502 				r->type = l->type;
503 			}
504 			break;
505 		case OGT:
506 		case OLE:
507 			sube(l);
508 			sube(r);
509 			if(cktype(r, n, TCFD, 0) && isconst(l, 0)){
510 				n->op = n->op == OGT ? OEQ : ONE;
511 				l->op = ONIL;
512 				l->type = r->type;
513 			}
514 			break;
515 	}
516 }
517 
518 static void
519 subs(Node *n, int blk, int aut)
520 {
521 	Node *l, *r;
522 
523 	if(n == Z)
524 		return;
525 	if(blk)
526 		pushscope(n, SAUTO);
527 	nearln = n->lineno;
528 	l = n->left;
529 	r = n->right;
530 	switch(n->op){
531 		default:
532 			sube(n);
533 			break;
534 		case ONAME:
535 			if(aut && n->kind != KEXP)
536 				pushdcl(n, CAUTO);
537 			if(cktype(n, n, TCALL, 0))
538 				setdec(n->sym, n->type);
539 			break;
540 		case ODAS:
541 			if(aut)
542 				pushdcl(l, CAUTO);
543 			subs(l, 0, aut);
544 			if(cktype(l, n, TCALL, 0))
545 				tcon(r, l->type);
546 			break;
547 		case OSBREAK:
548 		case ONUL:
549 		case OLABEL:
550 		case OGOTO:
551 		case OCONTINUE:
552 		case OBREAK:
553 		case OSET:
554 		case OUSED:
555 			break;
556 		case OBLK:
557 			subs(l, 1, aut);
558 			break;
559 		case OCASE:
560 			subs(r, 1, aut);
561 			break;
562 		case OLIST:
563 			subs(l, 0, aut);
564 			subs(r, 0, aut);
565 			break;
566 		case ORETURN:
567 			sube(l);
568 			if(l != Z && cktype(l, n, TCGEN, 0)){
569 				n->type = l->type;
570 				tcon(curfn(), l->type);
571 			}
572 			retval(n);
573 			break;
574 		case OSWITCH:
575 		case OWHILE:
576 		case ODWHILE:
577 			sube(l);
578 			subs(r, 1, aut);
579 			break;
580 		case OIF:
581 			sube(l);
582 			subs(r->left, 1, aut);
583 			subs(r->right, 1, aut);
584 			break;
585 		case OFOR:
586 			sube(l->left);
587 			sube(l->right->left);
588 			sube(l->right->right);
589 			subs(r, 1, aut);
590 			break;
591 	}
592 	if(blk)
593 		popscope();
594 }
595 
596 static Node*
597 finddec0(Sym *s, Node *n)
598 {
599 	Node *nn;
600 
601 	if(n == Z)
602 		return ZZ;
603 	switch(n->op){
604 		case OLIST:
605 			nn = finddec0(s, n->left);
606 			if(nn != Z)
607 				return nn;
608 			return finddec0(s, n->right);
609 		case OFUNC:
610 			if(n->op != KEXP){
611 				if(s == decsym(n))
612 					return n;
613 				return finddec0(s, n->right);
614 			}
615 			else
616 				return ZZ;
617 		case OPROTO:
618 		case OIND:
619 		case OARRAY:
620 			return finddec0(s, n->left);
621 		case ODOTDOT:
622 			return ZZ;
623 		case ONOOP:
624 		case OPUSH:
625 		case OPOP:
626 		case OCODE:
627 		case ODECE:
628 		case ODECT:
629 			return finddec0(s, n->right);
630 		case ODECV:
631 		case ODECF:
632 			if(s == decsym(n->left) && !isfn(n->left->type))
633 				return n->left;
634 			return finddec0(s, n->right);
635 	}
636 	if(isdec(n)){
637 		if(s == decsym(n) && !isfn(n->type))
638 			return n;
639 		return Z;
640 	}
641 	return ZZ;
642 }
643 
644 static Node*
645 finddec(Sym *s, int g)
646 {
647 	Node *n;
648 	Scope *sc;
649 
650 	for(sc = scopes; sc != nil; sc = sc->nxt){
651 		if(!g || sc->k == SGLOB){
652 			n = finddec0(s, sc->n);
653 			if(n != Z && n != ZZ)
654 				return n;
655 		}
656 	}
657 	return Z;
658 }
659 
660 static void
661 setdec(Sym *s, Type *t)
662 {
663 	Node *n;
664 
665 	if((n = finddec(s, 0)) != Z){
666 		n->type = t;
667 		if(n->op == ODAS){
668 			n = n->left;
669 			n->type = t;
670 		}
671 		n->sym->type = t;
672 	}
673 }
674 
675 typedef struct Syml Syml;
676 
677 struct Syml{
678 	Sym *sym;
679 	Syml *nxt;
680 };
681 
682 typedef struct Symq Symq;
683 
684 struct Symq{
685 	Syml *f;
686 	Syml *r;
687 };
688 
689 typedef struct Modl Modl;
690 
691 struct Modl{
692 	char *mod;
693 	int	ld;
694 	Modl *nxt;
695 };
696 
697 static void
698 prn(Node *n, int i)
699 {
700 	int j;
701 
702 	for(j = 0; j < i; j++)
703 		print("\t");
704 	if(n == Z){
705 		print("Z\n");
706 		return;
707 	}
708 	print("%s", onames[n->op]);
709 	if(n->blk)
710 		print("	block");
711 	if(n->type == T)
712 		print("	T");
713 	else
714 		print("	%s", tnames[n->type->etype]);
715 	if(n->op == OCONST)
716 		print("	%d", (int)n->vconst);
717 	else if(n->op == OSTRING)
718 		print("	%s", n->cstring);
719 	else if(n->op == ONAME)
720 		print("	%s", n->sym->name);
721 	print("\n");
722 	if(n->op != OLIST)
723 		i++;
724 	prn(n->left, i);
725 	prn(n->right, i);
726 }
727 
728 static int
729 isbigv(vlong v)
730 {
731 	return v > 0xffffffff;
732 }
733 
734 static int
735 islbigv(vlong v)
736 {
737 	return v > 0x7fffffff || v < -0x7fffffff;
738 }
739 
740 static int
741 isuintv(vlong v)
742 {
743 	return !isbigv(v) && (v&0x80000000) != 0;
744 }
745 
746 static int
747 isadt(Type *t)
748 {
749 	return t != T && (t->etype == TSTRUCT || t->etype == TUNION);
750 }
751 
752 static int
753 isreal(Type *t)
754 {
755 	return t != T && (t->etype == TDOUBLE || t->etype == TFLOAT);
756 }
757 
758 static int
759 isbyte(Type *t)
760 {
761 	return t != T && (t->etype == TCHAR || t->etype == TUCHAR);
762 }
763 
764 static int
765 isshort(Type *t)
766 {
767 	return t != T && (t->etype == TSHORT || t->etype == TUSHORT);
768 }
769 
770 static int
771 isint(Type *t)
772 {
773 	return t != T && (t->etype == TINT || t->etype == TUINT);
774 }
775 
776 static int
777 islong(Type *t)
778 {
779 	return t != T && (t->etype == TLONG || t->etype == TULONG);
780 }
781 
782 static int
783 isbig(Type *t)
784 {
785 	return t != T && (t->etype == TVLONG || t->etype == TUVLONG);
786 }
787 
788 static int
789 isinteger(Type *t)
790 {
791 	return isbyte(t) || isshort(t) || isint(t) || islong(t) || isbig(t);
792 }
793 
794 static int
795 isptr(Type *t)
796 {
797 	return t != T && (t->etype == TIND || t->etype == TARRAY || t->etype == TFUNC);
798 }
799 
800 static int
801 isscalar(Type *t)
802 {
803 	return t != T && !isadt(t) && t->etype != TTUPLE;
804 }
805 
806 static int
807 isvoid(Type *t)
808 {
809 	return t == T || t->etype == TVOID;
810 }
811 
812 static int
813 isnum(Type *t)
814 {
815 	return t != T && isscalar(t) && !isptr(t) && !isvoid(t);
816 }
817 
818 static int
819 isarray(Type *t)
820 {
821 	return t != T && (t->etype == TARRAY || (t->etype == TIND && !isadt(t->link)));
822 }
823 
824 static int
825 isstr(Type *t)
826 {
827 	return t != T && (t->etype == TSTRING || isarray(t) && isbyte(t->link));
828 }
829 
830 static int
831 isfn(Type *t)
832 {
833 	return t != T && t->etype == TFUNC;
834 }
835 
836 static int
837 iscastable(Type *t, Type *tt)
838 {
839 	return t != T && (!isptr(t) || isarray(t) && isbyte(t->link) && isstr(tt));
840 }
841 
842 static int
843 isname(Node *n)
844 {
845 	return n->op == ONAME;
846 }
847 
848 static int
849 isstring(Node *n)
850 {
851 	return n->op == OSTRING || n->op == OLSTRING || n->op == ONAME && n->sym->tenum != T && n->sym->tenum->etype == TIND;
852 }
853 
854 static int
855 isnil(Node *n)
856 {
857 	if(!isptr(n->type))
858 		return 0;
859 	while(n->op == OCAST)
860 		n = n->left;
861 	return n->op == OCONST && n->vconst == 0 || n->op == ONIL;
862 }
863 
864 static int
865 isconst(Node *n, vlong v)
866 {
867 	while(n->op == OCAST)
868 		n = n->left;
869 	return n->op == OCONST && n->vconst == v;
870 }
871 
872 static Node*
873 cknil(Node *n)
874 {
875 	if(isconst(n, 0))
876 		n->op = ONIL;
877 	return n;
878 }
879 
880 static int
881 cktype(Node *n, Node *t, int mask, int lev)
882 {
883 	int g, m, m0;
884 
885 	g = t->garb > lev;
886 	m = marked(n->type) & mask;
887 	if(n->op == ONAME){
888 		m0 = marked(n->sym->type) & mask;
889 		if(m && !m0){
890 			n->sym->type = n->type;
891 			if(!g)
892 				again = 1;
893 		}
894 		if(!m && m0){
895 			n->type = n->sym->type;
896 			if(!g)
897 				again = 1;
898 		}
899 		m |= m0;
900 	}
901 	if(m && t->garb < 2)
902 		t->garb++;
903 	return m && !g ? m : 0;
904 }
905 
906 int
907 isconsym(Sym *s)
908 {
909 	switch(s->class){
910 		case CXXX:
911 		case CTYPEDEF:
912 			return 1;
913 		case CEXTERN:
914 		case	CGLOBL:
915 		case CSTATIC:
916 		case CLOCAL:
917 			return s->type != T && s->type->etype == TENUM;
918 	}
919 	return -1;
920 }
921 
922 static void genstart(void);
923 
924 static char*
925 mprolog[] =
926 {
927 	"%%: module",
928 	"{",
929 	"\tPATH: con \"%%%.dis\";",
930 	"",
931 	nil
932 };
933 
934 static char*
935 mepilog[] =
936 {
937 	"};",
938 	nil
939 };
940 
941 static char*
942 bprolog[] =
943 {
944 	"implement %%;",
945 	"",
946 	"include \"draw.m\";",
947 	"",
948 	"%%: module",
949 	"{",
950 	"	init: fn(nil: ref Draw->Context, argl: list of string);",
951 	"};",
952 	"",
953 	nil
954 };
955 
956 static char*
957 bmprolog[] =
958 {
959 	"implement %%;",
960 	"",
961 	"include \"draw.m\";",
962 	"",
963 	nil
964 };
965 
966 static char*
967 bepilog[] =
968 {
969 	nil
970 };
971 
972 static void
973 pgen0(char **txt)
974 {
975 	int sub;
976 	char *b, *s, *t, **p;
977 
978 	p = txt;
979 	for(;;){
980 		s = *p++;
981 		if(s == nil)
982 			break;
983 		sub = 0;
984 		for(t = s; *t != 0; t++){
985 			if(*t == '%' && *(t+1) == '%'){
986 				sub = 1;
987 				break;
988 			}
989 		}
990 		if(sub){
991 			strcpy(buf, s);
992 			b = buf;
993 			for(t = s; *t != 0; t++){
994 				if(*t == '%' && *(t+1) == '%'){
995 					if(*(t+2) == '%'){
996 						outmod(mbuf, 0);
997 						t++;
998 					}
999 					else
1000 						outmod(mbuf, 1);
1001 					strcpy(b, mbuf);
1002 					b += strlen(mbuf);
1003 					t++;
1004 				}
1005 				else
1006 					*b++ = *t;
1007 			}
1008 			*b = 0;
1009 			prline(buf);
1010 		}
1011 		else
1012 			prline(s);
1013 	}
1014 }
1015 
1016 static char*
1017 hasm()
1018 {
1019 	outmod(mbuf, 0);
1020 	strcat(mbuf, ".m");
1021 	if(exists(mbuf))
1022 		return mbuf;
1023 	else if(domod){
1024 		outmod(buf, 0);
1025 		strcat(buf, ".h");
1026 		if(exists(buf))
1027 			return mbuf;
1028 	}
1029 	return nil;
1030 }
1031 
1032 void
1033 pgen(int b)
1034 {
1035 	char **p;
1036 
1037 	if(!dolog())
1038 		return;
1039 	if(b)
1040 		p = hasm() ? bmprolog : bprolog;
1041 	else
1042 		p = mprolog;
1043 	pgen0(p);
1044 	if(b && passes)
1045 		genstart();
1046 	if(!b)
1047 		incind();
1048 }
1049 
1050 void
1051 epgen(int b)
1052 {
1053 	char **p;
1054 
1055 	/* output(0x7fffffff, 1); */	/* INFINITY */
1056 	if(!dolog())
1057 		return;
1058 	if(b){
1059 		if(!passes)
1060 			genstart();
1061 		p = bepilog;
1062 	}
1063 	else
1064 		p = mepilog;
1065 	if(!b)
1066 		decind();
1067 	pgen0(p);
1068 }
1069 
1070 static int lastsec = 0;
1071 
1072 #define ASSOC		1
1073 #define RASSOC	2
1074 #define POSTOP	4
1075 
1076 #define LEFT	1
1077 #define RIGHT	2
1078 #define PRE	4
1079 #define POST	8
1080 
1081 static int space[] = { 0, 0, 2, 0, 4, 5, 0, 0, 0, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0 };
1082 
1083 static struct{
1084 	char *name;
1085 	int	prec;
1086 	int	kind;
1087 } ops[] = {
1088 	"",		0,	0,	/* ONOOP */
1089 	"",		16,	0,	/* OXXX, */
1090 	"+",		12,	ASSOC,	/* OADD, */
1091 	"&",		14,	RASSOC,	/* OADDR, */
1092 	"&",		8,	ASSOC,	/* OAND, */
1093 	"&&",	5,	ASSOC,	/* OANDAND, */
1094 	"",		16,	0,	/* OARRAY, */
1095 	"=",		2,	RASSOC,	/* OAS, */
1096 	"=",		2,	RASSOC,	/* OASI, */
1097 	"+=",		2,	RASSOC,	/* OASADD, */
1098 	"&=",		2,	RASSOC,	/* OASAND, */
1099 	"<<=",	2,	RASSOC,	/* OASASHL, */
1100 	">>=",	2,	RASSOC,	/* OASASHR, */
1101 	"/=",		2,	RASSOC,	/* OASDIV, */
1102 	"<<",		11,	0,	/* OASHL, */
1103 	">>",		11,	0,	/* OASHR, */
1104 	"/=",		2,	RASSOC,	/* OASLDIV, */
1105 	"%=",		2,	RASSOC,	/* OASLMOD, */
1106 	"*=",		2,	RASSOC,	/* OASLMUL, */
1107 	">>=",	2,	RASSOC,	/* OASLSHR, */
1108 	"%=",		2,	RASSOC,	/* OASMOD, */
1109 	"*=",		2,	RASSOC,	/* OASMUL, */
1110 	"|=",		2,	RASSOC,	/* OASOR, */
1111 	"-=",		2,	RASSOC,	/* OASSUB, */
1112 	"^=",		2,	RASSOC,	/* OASXOR, */
1113 	"",		-1,	0,	/* OBIT, */
1114 	"",		-1,	0,	/* OBREAK, */
1115 	"",		-1,	0,	/* OCASE, */
1116 	"",		14,	RASSOC,	/* OCAST, */
1117 	"",		1,	ASSOC,	/* OCOMMA, */
1118 	"",		3,	RASSOC,	/* OCOND, */
1119 	"",		16,	0,	/* OCONST, */
1120 	"",		-1,	0,	/* OCONTINUE, */
1121 	"/",		13,	0,	/* ODIV, */
1122 	".",		15,	0,	/* ODOT, */
1123 	"...",		16,	0,	/* ODOTDOT, */
1124 	"",		-1,	0,	/* ODWHILE, */
1125 	"",		-1,	0,	/* OENUM, */
1126 	"==",		9,	0,	/* OEQ, */
1127 	"",		-1,	0,	/* OFOR, */
1128 	"",		15,	0,	/* OFUNC, */
1129 	">=",		10,	0,	/* OGE, */
1130 	"",		-1,	0,	/* OGOTO, */
1131 	">",		10,	0,	/* OGT, */
1132 	">",		10,	0,	/* OHI, */
1133 	">=",		10,	0,	/* OHS, */
1134 	"",		-1,	0,	/* OIF, */
1135 	"*",		14,	RASSOC,	/* OIND, */
1136 	"",		-1,	0,	/* OINDREG, */
1137 	"",		16,	0,	/* OINIT, */
1138 	"",		-1,	0,	/* OLABEL, */
1139 	"/",		13,	0,	/* OLDIV, */
1140 	"<=",		10,	0,	/* OLE, */
1141 	"",		16,	0,	/* OLIST, */
1142 	"%",		13,	0,	/* OLMOD, */
1143 	"*",		13,	ASSOC,	/* OLMUL, */
1144 	"<",		10,	0,	/* OLO, */
1145 	"<=",		10,	0,	/* OLS, */
1146 	">>",		11,	0,	/* OLSHR, */
1147 	"<",		10,	0,	/* OLT, */
1148 	"%",		13,	0,	/* OMOD, */
1149 	"*",		13,	ASSOC,	/* OMUL, */
1150 	"",		16,	0,	/* ONAME, */
1151 	"!=",		9,	0,	/* ONE, */
1152 	"!",		14,	RASSOC,	/* ONOT, */
1153 	"|",		6,	ASSOC,	/* OOR, */
1154 	"||",		4,	ASSOC,	/* OOROR, */
1155 	"--",		14,	RASSOC|POSTOP,	/* OPOSTDEC, */
1156 	"++",		14,	RASSOC|POSTOP,	/* OPOSTINC, */
1157 	"--",		14,	RASSOC,	/* OPREDEC, */
1158 	"++",		14,	RASSOC,	/* OPREINC, */
1159 	"",		16,	0,	/* OPROTO, */
1160 	"",		-1,	0,	/* OREGISTER, */
1161 	"",		0,	0,	/* ORETURN, */
1162 	"SET",	-1,	0,	/* OSET, */
1163 	"signof",	14,	RASSOC,	/* OSIGN, */
1164 	"sizeof",	14,	RASSOC,	/* OSIZE, */
1165 	"",		16,	0,	/* OSTRING, */
1166 	"",		16,	0,	/* OLSTRING, */
1167 	"",		16,	0,	/* OSTRUCT, */
1168 	"-",		12,	0,	/* OSUB, */
1169 	"",		-1,	0,	/* OSWITCH, */
1170 	"",		16,	0,	/* OUNION, */
1171 	"USED",	-1,	0,	/* OUSED, */
1172 	"",		-1,	0,	/* OWHILE, */
1173 	"^",		7,	ASSOC,	/* OXOR, */
1174 	"-",		14,	RASSOC,	/* ONEG, */
1175 	"~",		14,	RASSOC,	/* OCOM, */
1176 	"",		16,	0,	/* OELEM, */
1177 	"",		-1,	0,	/* OTST, */
1178 	"",		-1,	0,	/* OINDEX, */
1179 	"",		-1,	0,	/* OFAS, */
1180 	"",		-1,	0,	/* OBLK */
1181 	"+",		14,	RASSOC,	/* OPOS */
1182 	"",		-1,	0,	/* ONUL */
1183 	".",		15,	0,	/* ODOTIND */
1184 	"",		15,	0,	/* OARRIND */
1185 	"",		-1,	0,	/* ODAS */
1186 	":=",		2,	RASSOC,	/* OASD */
1187 	"",		16,	0,	/* OIOTA */
1188 	"",		14,	RASSOC,	/* OLEN */
1189 	"",		17,	0,	/* OBRACKET */
1190 	"",		14,	RASSOC,	/* OREF */
1191 	"",		14,	RASSOC,	/* OARRAYOF */
1192 	"",		15,	0,	/* OSLICE */
1193 	"&",		14,	RASSOC,	/* OSADDR, */
1194 	"",		16,	0,	/* ONIL */
1195 	"",		16,	0,	/* OS2AB */
1196 	"",		16,	0,	/* OAB2S */
1197 	"",		16,	0,	/* OFILDES */
1198 	".",		15,	0,	/* OFD */
1199 	"",		16,	0,	/* OTUPLE */
1200 	".",		15,	0,	/* OT0 */
1201 	"",		15,	0,	/* ORETV */
1202 	"+",		12,	ASSOC,	/* OCAT */
1203 	"",		-1,	0,	/* OSBREAK, */
1204 	".",		15,	0,	/* OLDOT */
1205 	"->",		15,	0,	/* OMDOT */
1206 	nil,		-1,	0,	/* OCODE */
1207 	nil,		-1,	0,	/* ODECE */
1208 	nil,		-1,	0,	/* ODECT */
1209 	nil,		-1,	0,	/* ODECV */
1210 	nil,		-1,	0,	/* ODECF */
1211 	nil,		-1,	0,	/* OPUSH */
1212 	nil,		-1,	0,	/* OPOP */
1213 	"",		-1,	0,	/* OEND */
1214 };
1215 
1216 #define COMPLEX	32
1217 
1218 #define NOBR	2
1219 #define NOIN	4
1220 #define YESBR	8
1221 #define NONL	16
1222 #define NOENL	32
1223 
1224 enum{
1225 	LNONE,
1226 	LSTRLEN,
1227 	LSTRCMP,
1228 	LSTRCPY,
1229 	LSTRCAT,
1230 	LSTRNCMP,
1231 	LSTRNCPY,
1232 	LSTRNCAT,
1233 	LSTRDUP,
1234 	LMEMMOVE,
1235 	LMALLOC,
1236 	LFREE,
1237 	LEXIT,
1238 	LCLOSE,
1239 	LATOI,
1240 	LATOL,
1241 	LATOF,
1242 	LPRINT,
1243 	LFPRINT,
1244 	LSPRINT,
1245 	LSELF,
1246 };
1247 
1248 static int tmp;
1249 
1250 static void egen(Node*, int, int);
1251 static Node* buildcases(Node*);
1252 static void tdgen(Node *, int);
1253 static Node* cfind(Node*);
1254 static Node* cgen(Node*, Node*);
1255 static void cgen0(Node*, Node*);
1256 static int lteq(Type*, Type*);
1257 static Type* ntype(Node*);
1258 static int rewe(Node*, Type*, int);
1259 static void rewlc(Node*, int, Type*);
1260 static Node* con(vlong);
1261 static void	clrbrk(Node*);
1262 static int hasbrk(Node*);
1263 static int isgen(char*);
1264 static int simple(Node*);
1265 static void pfmt(char*);
1266 static void lpfmt(Rune*);
1267 static int lline(Node*);
1268 static void args(Node*);
1269 static void addmodn(Sym*);
1270 static void scomplex(Node*);
1271 static void mset(Node*);
1272 
1273 static Node *lastd;
1274 
1275 static int
1276 rev(int op)
1277 {
1278 	switch(op){
1279 		case OLT:	return OGT;
1280 		case OLE:	return OGE;
1281 		case OGT:	return OLT;
1282 		case OGE:	return OLE;
1283 	}
1284 	return op;
1285 }
1286 
1287 void
1288 newsec(int l)
1289 {
1290 	if(l != 1 && lastd != Z){
1291 		tdgen(lastd, 1);
1292 		lastd = Z;
1293 	}
1294 	if(l != 2)
1295 		etgen2(nil);
1296 	if(lastsec && l != lastsec)
1297 		newline();
1298 	lastsec = l;
1299 }
1300 
1301 static Node*
1302 defval(Type *t)
1303 {
1304 	Node *n;
1305 
1306 	if(t == T)
1307 		t = types[TINT];
1308 	n = con(0);
1309 	n->type = types[TINT];
1310 	n->kind = KDEC;
1311 	switch(t->etype){
1312 		case TFLOAT:
1313 		case TDOUBLE:
1314 			n->type = types[TDOUBLE];
1315 			n->fconst = 0.0;
1316 			n->cstring = "0.0";
1317 			return n;
1318 		default:
1319 			break;
1320 		case TIND:
1321 		case TFUNC:
1322 		case TARRAY:
1323 			n->type = typ1(TIND, types[TVOID]);
1324 			return n;
1325 		case TVOID:
1326 		case TSTRUCT:
1327 		case TUNION:
1328 			free(n);
1329 			return Z;
1330 	}
1331 	if(!lteq(n->type, t)){
1332 		n = new1(OCAST, n, Z);
1333 		n->type = t;
1334 	}
1335 	return n;
1336 }
1337 
1338 static int
1339 teq(Type *t1, Type *t2)
1340 {
1341 	if(t1 == t2)
1342 		return 1;
1343 	return sametype(t1, t2);
1344 /*
1345 	if(t1->etype != t2->etype)
1346 		return 0;
1347 	switch(t1->etype){
1348 		case TARRAY:
1349 			if(t1->width != t2->width)
1350 				return 0;
1351 			break;
1352 		case TFUNC:
1353 			if(!teq(t1->down, t2->down))
1354 				return 0;
1355 			break;
1356 		case TSTRUCT:
1357 		case TUNION:
1358 			return t1->link == t2->link;
1359 		case TENUM:
1360 			return 1;
1361 	}
1362 	return teq(t1->link, t2->link);
1363 */
1364 }
1365 
1366 static int
1367 tequiv(Type *t1, Type *t2)
1368 {
1369 	if(!teq(t1, t2))
1370 		return 0;
1371 	if(t1->etype == TSTRUCT || t1->etype == TUNION)
1372 		return suename(t1) == suename(t2);
1373 	return 1;
1374 }
1375 
1376 static int
1377 iteq(Type *t1, Type *t2)
1378 {
1379 	if(t1 == T || t2 == T)
1380 		return 0;
1381 	return t1->etype == TIND && (teq(t1->link, t2) || (t1->link->etype == TVOID && isnum(t2)));
1382 }
1383 
1384 static Type *
1385 ltype(Type *t)
1386 {
1387 	switch(t->etype){
1388 		case TUCHAR:
1389 			return types[TCHAR];
1390 		case TSHORT:
1391 		case TUSHORT:
1392 		case TUINT:
1393 		case TLONG:
1394 		case TULONG:
1395 		case TENUM:
1396 			return types[TINT];
1397 		case TUVLONG:
1398 			return types[TVLONG];
1399 		case TFLOAT:
1400 			return types[TDOUBLE];
1401 		default:
1402 			return t;
1403 	}
1404 }
1405 
1406 static int
1407 lteq(Type *t1, Type *t2)
1408 {
1409 	if(t1 == T || t2 == T)
1410 		return 0;
1411 	if(t1 == t2)
1412 		return 1;
1413 	if(t1->etype == TIND && t2->etype == TIND)
1414 		return lteq(t1->link, t2->link);
1415 	return sametype(ltype(t1), ltype(t2));
1416 }
1417 
1418 static Type*
1419 tcp(Type *t)
1420 {
1421 	Type *nt;
1422 
1423 	if(t == T)
1424 		return T;
1425 	nt = typ1(TXXX, T);
1426 	*nt = *t;
1427 	return nt;
1428 }
1429 
1430 static Type*
1431 tuple(Type *t1, Type *t2)
1432 {
1433 	Type *t, **at, *l;
1434 
1435 	if(t1 == T || t1->etype == TVOID)
1436 		return tcp(t2);
1437 	if(t2 == T || t2->etype == TVOID)
1438 		return tcp(t1);
1439 	if(t2->etype == TTUPLE)
1440 		diag(Z, "bad tuple type");
1441 	t = typ1(TTUPLE, T);
1442 	at = &t->link;
1443 	if(t1->etype == TTUPLE){
1444 		for(l = t1->link; l != T; l = l->down){
1445 			*at = tcp(l);
1446 			at = &(*at)->down;
1447 		}
1448 	}
1449 	else{
1450 		*at = tcp(t1);
1451 		at = &(*at)->down;
1452 	}
1453 	*at = tcp(t2);
1454 	return t;
1455 }
1456 
1457 static Sym*
1458 sue(Type *t)
1459 {
1460 	int h;
1461 	Sym *s;
1462 
1463 	if(t != T)
1464 		for(h=0; h<nelem(hash); h++)
1465 			for(s = hash[h]; s != S; s = s->link)
1466 				if(s->suetag && s->suetag->link == t)
1467 					return s;
1468 	return S;
1469 }
1470 
1471 static void
1472 pranon(int i)
1473 {
1474 	prid("anon_");
1475 	prnum(i+1, KDEC, T);
1476 }
1477 
1478 static int
1479 dotpath(Sym *s, Type *t, int pr)
1480 {
1481 	int i;
1482 	Type *t1;
1483 
1484 	if(t == T)
1485 		return 0;
1486 	for(t1 = t->link; t1 != T; t1 = t1->down){
1487 		if(t1->sym == s){
1488 			if(pr){
1489 				prdelim(".");
1490 				prsym(s, 0);
1491 			}
1492 			return 1;
1493 		}
1494 	}
1495 	i = 0;
1496 	for(t1 = t->link; t1 != T; t1 = t1->down){
1497 		if(t1->sym == S){
1498 			i++;
1499 			if(typesu[t1->etype] && sametype(s->type, t1)){
1500 				if(pr){
1501 					prdelim(".");
1502 					pranon(i-1);
1503 				}
1504 				return 1;
1505 			}
1506 		}
1507 	}
1508 	i = 0;
1509 	for(t1 = t->link; t1 != T; t1 = t1->down){
1510 		if(t1->sym == S){
1511 			i++;
1512 			if(typesu[t1->etype] && dotpath(s, t1, 0)){
1513 				if(pr){
1514 					prdelim(".");
1515 					pranon(i-1);
1516 					dotpath(s, t1, 1);
1517 				}
1518 				return 1;
1519 			}
1520 		}
1521 	}
1522 	return 0;
1523 }
1524 
1525 static Sym*
1526 suename(Type *t)
1527 {
1528 	Sym *s;
1529 
1530 	s = sue(t->link);
1531 	if(s != S)
1532 		return s;
1533 	else if(t->tag != S)
1534 		return t->tag;
1535 	else if(t->sym != S)
1536 		return t->sym;
1537 	return S;
1538 }
1539 
1540 static int
1541 cycle(Type *t, Type *base)
1542 {
1543 	int r;
1544 	Type *l;
1545 
1546 	if(t->vis){
1547 		/* sametype() does structural comparison so have to check names */
1548 		if(t == base || tequiv(t, base))
1549 			return 1;
1550 		return 0;
1551 	}
1552 	r = 0;
1553 	t->vis = 1;
1554 	switch(t->etype){
1555 		case TIND:
1556 		case TARRAY:
1557 			r = cycle(t->link, base);
1558 			break;
1559 		case TSTRUCT:
1560 		case TUNION:
1561 		case TTUPLE:
1562 			for(l = t->link; l != T; l = l->down)
1563 				r |= cycle(l, base);
1564 			break;
1565 	}
1566 	t->vis = 0;
1567 	return r;
1568 }
1569 
1570 static void
1571 addnode(int op, Node *n)
1572 {
1573 	Node *nn;
1574 
1575 	nn = new1(OXXX, Z, Z);
1576 	*nn = *n;
1577 	n->op = op;
1578 	n->left = nn;
1579 	n->right = Z;
1580 	n->type = nn->type;
1581 }
1582 
1583 static void
1584 cast(Node *n, Type *t)
1585 {
1586 	addnode(OCAST, n);
1587 	n->type = t;
1588 }
1589 
1590 static void
1591 intcast(Node *n)
1592 {
1593 	if(isptr(n->type)){
1594 		addnode(ONE, n);
1595 		n->right = con(0);
1596 		n->right->type = n->left->type;
1597 		n->type = types[TINT];
1598 	}
1599 	else
1600 		cast(n, types[TINT]);
1601 }
1602 
1603 static void
1604 strcast(Node *n)
1605 {
1606 	cast(n, stringtype);
1607 }
1608 
1609 static void
1610 bptr(Node *n)
1611 {
1612 	if(n == Z)
1613 		return;
1614 	switch(n->op){
1615 		default:
1616 			if(!lteq(n->type, types[TINT]))
1617 				intcast(n);
1618 			break;
1619 		case ONOT:
1620 			if(!lteq(n->left->type, types[TINT])){
1621 				intcast(n->left);
1622 				if(n->left->op == ONE){
1623 					n->left->op = OEQ;
1624 					*n = *n->left;
1625 				}
1626 			}
1627 			break;
1628 		case OANDAND:
1629 		case OOROR:
1630 			bptr(n->left);
1631 			bptr(n->right);
1632 			break;
1633 		case OCOND:
1634 			bptr(n->right->left);
1635 			bptr(n->right->right);
1636 			break;
1637 	}
1638 }
1639 
1640 static void
1641 bcomplex(Node *n)
1642 {
1643 	if(n == Z)
1644 		return;
1645 	if(!passes)
1646 		complex(n);
1647 	bptr(n);
1648 }
1649 
1650 static void
1651 ecomplex(Node *n)
1652 {
1653 	if(!passes)
1654 		complex(n);
1655 	rewe(n, T, 0);
1656 }
1657 
1658 static void
1659 becomplex(Node *n)
1660 {
1661 	bcomplex(n);
1662 	rewe(n, T, 0);
1663 }
1664 
1665 static void
1666 tgen(Type *t, int dec, int arinit)
1667 {
1668 	Type *l;
1669 
1670 	if(t == T)
1671 		return;
1672 	switch(t->etype){
1673 		case TXXX:
1674 			prid("int");
1675 			break;
1676 		case TCHAR:
1677 		case TUCHAR:
1678 			prid("byte");
1679 			break;
1680 		case TSHORT:
1681 		case TUSHORT:
1682 		case TINT:
1683 		case TUINT:
1684 		case TLONG:
1685 		case TULONG:
1686 		case TENUM:
1687 			prid("int");
1688 			break;
1689 		case TVLONG:
1690 		case TUVLONG:
1691 			prid("big");
1692 			break;
1693 		case TFLOAT:
1694 		case TDOUBLE:
1695 			prid("real");
1696 			break;
1697 		case TIND:
1698 			if(strings == 2 && t->link && t->link->etype == TCHAR){
1699 				prid("string");
1700 				break;
1701 			}
1702 			if(isadt(t->link) || t->link->etype == TFUNC)
1703 				prid("ref ");
1704 			else
1705 				prid("array of ");
1706 			if(t->link && t->link->etype == TVOID){
1707 				prid("byte");
1708 				prcom("was void*", Z);
1709 			}
1710 			else
1711 				tgen(t->link, 1, 0);
1712 			break;
1713 		case TFUNC:
1714 			if(0){
1715 				prid("int");
1716 				prcom("was function", Z);
1717 				break;
1718 			}
1719 			prid("fn");
1720 			prdelim("(");
1721 			for(l = t->down; l != T; l = l->down){
1722 				if(l->etype == TVOID && l->down == T)
1723 					break;
1724 				if(l->etype == TDOT){
1725 					prcom("was ...", Z);
1726 					break;
1727 				}
1728 				if(l->sym != S)
1729 					prsym(l->sym, 0);
1730 				else
1731 					prid("nil");
1732 				prdelim(": ");
1733 				tgen(l, 1, 0);
1734 				if(l->down != T && l->down->etype != TDOT)
1735 					prdelim(", ");
1736 			}
1737 			/* tgen(t->down, dec, 0, 0); */
1738 			prdelim(")");
1739 			if(!isvoid(t->link)){
1740 				prdelim(": ");
1741 				tgen(t->link, dec, 0);
1742 			}
1743 			break;
1744 		case TARRAY:
1745 			prid("array");
1746 			if(t->width == LARR)
1747 				t->width = LARR;
1748 			else if(dec){
1749 				if(t->nwidth != Z)
1750 					prcom("array index was ", t->nwidth);
1751 				else if(t->width != 0){
1752 					sprint(buf, "array index was %ld", t->width/t->link->width);
1753 					prcom(buf, Z);
1754 				}
1755 			}
1756 			else{
1757 				prdelim("[");
1758 				if(t->nwidth != Z)
1759 					egen(t->nwidth, ONOOP, PRE);
1760 				else if(t->width != 0)
1761 					prnum(t->width/t->link->width, KDEC, T);
1762 				prdelim("]");
1763 			}
1764 			prdelim(" of ");
1765 			if(!arinit)
1766 				tgen(t->link, 1, 0);
1767 			break;
1768 		case TVOID:
1769 			/* prid("void"); */
1770 			prid("byte");
1771 			prcom("was void", Z);
1772 			break;
1773 		case TSTRUCT:
1774 		case TUNION:
1775 			if(t->link != T && t->link->etype == TFD){
1776 				prid("Sys->FD");
1777 				usemod(sysop, 0);
1778 			}
1779 			else
1780 				prsym(suename(t), 1);
1781 			break;
1782 		case TTUPLE:
1783 			prdelim("(");
1784 			for(l = t->link; l != T; l = l->down){
1785 				tgen(l, dec, 0);
1786 				if(l->down != T)
1787 					prdelim(", ");
1788 			}
1789 			prdelim(")");
1790 			break;
1791 		case TDOT:
1792 			prdelim("...");
1793 			break;
1794 		case TSTRING:
1795 			prid("string");
1796 			break;
1797 		case TFD:
1798 			prid("fd");
1799 			break;
1800 		default:
1801 			diag(Z, "unknown type");
1802 			break;
1803 	}
1804 }
1805 
1806 static Type*
1807 typn(Type *t, int i)
1808 {
1809 	Type *l;
1810 
1811 	for(l = t->down; l != T && --i >= 0; l = l->down)
1812 		;
1813 	return l;
1814 }
1815 
1816 void
1817 ttgen2(Type *t)
1818 {
1819 	Type *l;
1820 	Sym *s;
1821 	int anon = 0;
1822 
1823 	switch(t->etype){
1824 		case TSTRUCT:
1825 		case TUNION:
1826 			newsec(0);
1827 			output(t->lineno, 1);
1828 			s = suename(t);
1829 			if(isgen(s->name))
1830 				addmodn(s);
1831 			setmod(s);
1832 			prsym(s, 0);
1833 			prdelim(": ");
1834 			prid("adt");
1835 			prdelim("{");
1836 			if(t->etype == TUNION)
1837 				prcom("was union", Z);
1838 			newline();
1839 			incind();
1840 			t->vis = 1;
1841 			for(l = t->link; l != T; l = l->down){
1842 				output(l->lineno, 1);
1843 				if(l->nbits)
1844 					prcom("was bit field", Z);
1845 				if(l->sym != S)
1846 					prsym(l->sym, 0);
1847 				else
1848 					pranon(anon++);
1849 				prdelim(": ");
1850 				if(cycle(l, t))
1851 					prid("cyclic ");
1852 				tgen(l, 1, 0);
1853 				prdelim(";");
1854 				newline();
1855 			}
1856 			t->vis = 0;
1857 			decind();
1858 			prdelim("};");
1859 			newline();
1860 			newline();
1861 			break;
1862 		default:
1863 			break;
1864 	}
1865 }
1866 
1867 static int
1868 canjoin(Node *n, Node *nn)
1869 {
1870 	return teq(n->type, nn->type) && isname(n) && isname(nn) && n->type->etype != TARRAY;
1871 }
1872 
1873 void
1874 vtgen2(Node *n)
1875 {
1876 	int  t, c, comma = 0;
1877 	Node *nn;
1878 	Sym *s;
1879 
1880 	nn = n;
1881 	if(n->op == ODAS)
1882 		nn = n->left;
1883 	if(nn->type == T || nn->sym == S)
1884 		return;
1885 	t = nn->type->etype;
1886 	c = nn->sym->class;
1887 	if(0 && c == CTYPEDEF){
1888 		/* egen(nn, ONOOP, PRE); */
1889 		/* tdgen(n, 1, 0); */
1890 		if(isadt(n->type)){
1891 			s = suename(n->type);
1892 			if(isgen(s->name)){
1893 				s->lname = nn->sym->name;
1894 				ttgen2(n->type);
1895 			}
1896 		}
1897 	}
1898 	if(c != CGLOBL && c != CSTATIC && c != CLOCAL && c != CEXREG)
1899 		return;
1900 	newsec(1);
1901 	if(lastd != Z){
1902 		if(t != TFUNC && canjoin(lastd, n))
1903 			comma = 1;
1904 		else
1905 			tdgen(lastd, 1);
1906 	}
1907 	output(nn->lineno, 1);
1908 	if(t == TFUNC){
1909 		if(ism()){
1910 			setmod(nn->sym);
1911 			egen(nn, ONOOP, PRE);
1912 			tdgen(n, 1);
1913 		}
1914 		lastd = Z;
1915 		return;
1916 	}
1917 	if(comma)
1918 		prdelim(", ");
1919 	if(nn->op != ONAME)
1920 		diag(nn, "internal: not name in vtgen");
1921 	setmod(nn->sym);
1922 	prsym(nn->sym, 0);
1923 	/* egen(nn, ONOOP, PRE); */
1924 	/* tdgen(n, 1, 0); */
1925 	lastd = n;
1926 	if(n->op == ODAS)
1927 		rewe(n->right, T, 1);
1928 }
1929 
1930 static void minseq(Syml*);
1931 
1932 static Node*
1933 con(vlong v)
1934 {
1935 	int neg = 0;
1936 	Node *n;
1937 
1938 	if(v < 0){
1939 		neg = 1;
1940 		v = -v;
1941 	}
1942 	n = new1(OCONST, Z, Z);
1943 	n->vconst = v;
1944 	n->kind = KDEC;
1945 	n->type = types[TINT];
1946 	if(neg)
1947 		n = new1(ONEG, n, Z);
1948 	return n;
1949 }
1950 
1951 /*
1952 static Node*
1953 fcon(double v)
1954 {
1955 	int neg = 0;
1956 	Node *n;
1957 
1958 	if(v < 0){
1959 		neg = 1;
1960 		v = -v;
1961 	}
1962 	n = new1(OCONST, Z, Z);
1963 	n->fconst = v;
1964 	n->kind = KDEC;
1965 	n->type = types[TDOUBLE];
1966 	if(neg)
1967 		n = new1(ONEG, n, Z);
1968 	return n;
1969 }
1970 */
1971 
1972 static Node*
1973 add(vlong v, Node *n)
1974 {
1975 	if(v == 0)
1976 		return n;
1977 	return new1(OADD, con(v), n);
1978 }
1979 
1980 static Node*
1981 addn(Node *n1, Node *n2)
1982 {
1983 	if(n1 == Z || n2 == Z)
1984 		return Z;
1985 	if(isconst(n1, 0))
1986 		return n2;
1987 	if(isconst(n2, 0))
1988 		return n1;
1989 	return new1(OADD, n1, n2);
1990 }
1991 
1992 static Node*
1993 mul(vlong v, Node *n)
1994 {
1995 	if(v == 0)
1996 		return con(0);
1997 	else if(v == 1)
1998 		return n;
1999 	else if(v == -1)
2000 		return new1(ONEG, n, Z);
2001 	return new1(OMUL, con(v), n);
2002 }
2003 
2004 static Node*
2005 mydiv(Node *n, vlong w)
2006 {
2007 	Node *nn;
2008 
2009 	if(w == 0)
2010 		return Z;
2011 	if(w == 1)
2012 		return n;
2013 	else if(w == -1)
2014 		return new1(ONEG, n, Z);
2015 	switch(n->op){
2016 		case OCONST:
2017 			if(n->vconst % w == 0){
2018 				n->vconst /= w;
2019 				if(n->left != Z && mydiv(n->left, w) == Z){
2020 					n->vconst *= w;
2021 					break;
2022 				}
2023 				return n;
2024 			}
2025 			break;
2026 		case OCAST:
2027 			return mydiv(n->left, w);
2028 		case OMUL:
2029 			nn = mydiv(n->right, w);
2030 			if(nn != Z){
2031 				if(isconst(nn, 1))
2032 					*n = *n->left;
2033 				return n;
2034 			}
2035 			nn = mydiv(n->left, w);
2036 			if(nn != Z){
2037 				if(isconst(nn, 1))
2038 					*n = *n->right;
2039 				return n;
2040 			}
2041 			break;
2042 		default:
2043 			break;
2044 	}
2045 	return Z;
2046 }
2047 
2048 static Node*
2049 iota(void)
2050 {
2051 	return new1(OIOTA, Z, Z);
2052 }
2053 
2054 static Node*
2055 symcon(Sym *s)
2056 {
2057 	Node *n;
2058 
2059 	if(s->nconst != Z)
2060 		return s->nconst;
2061 	n = con(s->vconst);
2062 	n->kind = s->kind;
2063 	return n;
2064 }
2065 
2066 #define ARITH	1
2067 #define GEOM	2
2068 
2069 static Syml*
2070 newsyml(Sym *s, Syml **frees)
2071 {
2072 	Syml *sl, *f;
2073 
2074 	if((f = *frees) != nil){
2075 		sl = f;
2076 		*frees = f->nxt;
2077 	}
2078 	else
2079 		sl = (Syml*)malloc(sizeof(Syml));
2080 	sl->sym = s;
2081 	sl->nxt = nil;
2082 	return sl;
2083 }
2084 
2085 static Syml*
2086 etseq(Syml *syml)
2087 {
2088 	int e, pio, io, comma;
2089 	vlong d, dd, v0, v1, v, t, tt;
2090 	Node *expr;
2091 	Sym *s;
2092 	Syml *sl, *lsl;
2093 
2094 	lsl = nil;
2095 	pio = io = ARITH|GEOM;
2096 	e = 0;
2097 	dd = 0;
2098 	d = 0;
2099 	for(sl = syml; sl != nil; sl = sl->nxt){
2100 		s = sl->sym;
2101 		if(isreal(s->tenum) || s->tenum->etype == TIND)
2102 			break;
2103 		if(e == 0)
2104 			v0 = s->vconst;
2105 		if(e == 1){
2106 			v1 = s->vconst;
2107 			d = v1-v0;
2108 		}
2109 		if(e > 0 && (v <= 0 || s->vconst != 2*v))
2110 			io &= ~GEOM;
2111 		if(0 && e > 1 && s->vconst-v != d)
2112 			io &= ~ARITH;
2113 		if(e > 1){
2114 			t = s->vconst-v;
2115 			tt = t-d;
2116 			if(e > 2 && tt != dd)
2117 				io &= ~ARITH;
2118 			else{
2119 				d = t;
2120 				dd = tt;
2121 			}
2122 		}
2123 		if(io == 0)
2124 			break;
2125 		v = s->vconst;
2126 		lsl = sl;
2127 		pio = io;
2128 		e++;
2129 	}
2130 	if(e < 2)
2131 		pio = 0;
2132 	if(pio&GEOM){
2133 		if(e < 3)
2134 			pio = 0;
2135 	}
2136 	else if(pio&ARITH){
2137 		int n;
2138 
2139 		if(d == 0 && dd == 0)
2140 			n = 2;
2141 		else if(dd == 0)
2142 			n = 3;
2143 		else
2144 			n = 4;
2145 		if(e < n || (dd&1) != 0)
2146 			pio = 0;
2147 	}
2148 	if(lsl == nil || pio == 0)
2149 		lsl = syml;
2150 	comma = 0;
2151 	for(sl = syml; sl != nil; sl = sl->nxt){
2152 		s = sl->sym;
2153 		nearln = s->lineno;
2154 		output(s->lineno, 1);
2155 		if(pio){
2156 			if(comma)
2157 				prdelim(", ");
2158 			setmod(s);
2159 			prsym(s, 0);
2160 			comma = 1;
2161 		}
2162 		else{
2163 			setmod(s);
2164 			prsym(s, 0);
2165 			prdelim(": ");
2166 			prid("con ");
2167 			if(isbyte(s->tenum) || isbig(s->tenum) && !islbigv(s->vconst) || !isbig(s->tenum) && isuintv(s->vconst)){
2168 				tgen(s->tenum, 1, 0);
2169 				prdelim(" ");
2170 			}
2171 			if(s->nconst != Z)
2172 				egen(s->nconst, ONOOP, PRE);
2173 			else if(s->kind == KCHR)
2174 				prchar(s->vconst);
2175 			else if(isreal(s->tenum))
2176 				prreal(s->fconst, s->cstring, s->kind);
2177 			else
2178 				prnum(s->vconst, s->kind, s->tenum);
2179 			prdelim(";");
2180 			newline();
2181 		}
2182 		if(sl == lsl)
2183 			break;
2184 	}
2185 	if(pio){
2186 		s = syml->sym;
2187 		prdelim(": ");
2188 		prid("con ");
2189 		if(isbyte(s->tenum) || isbig(s->tenum)){
2190 			tgen(s->tenum, 1, 0);
2191 			prdelim(" ");
2192 		}
2193 		if(pio&GEOM){
2194 			if(v0 == 0 || v0 == 1 || v0 == -1)
2195 				expr = mul(v0, new1(OASHL, con(1), iota()));
2196 			else
2197 				expr = new1(OMUL, symcon(s), new1(OASHL, con(1), iota()));
2198 		}
2199 		else if(d == 0 && dd == 0)
2200 			expr = symcon(s);
2201 		else if(dd == 0)
2202 			expr = add(v0, mul(d, iota()));
2203 		else
2204 			expr = add(v0, new1(OADD, mul(v1-dd/2-v0, iota()), mul(dd/2, new1(OMUL, iota(), iota()))));
2205 		complex(expr);
2206 		expr = ckneg(expr);
2207 		egen(expr, ONOOP, PRE);
2208 		prdelim(";");
2209 		newline();
2210 	}
2211 	return lsl->nxt;
2212 }
2213 
2214 static void
2215 adde(Syml *sl, Symq *q)
2216 {
2217 	if(q->f == nil)
2218 		q->f = sl;
2219 	else
2220 		q->r->nxt = sl;
2221 	q->r = sl;
2222 }
2223 
2224 static void
2225 freeq(Symq *q, Syml **frees)
2226 {
2227 	if(q->f){
2228 		q->r->nxt = *frees;
2229 		*frees = q->f;
2230 		q->f = q->r = nil;
2231 	}
2232 }
2233 
2234 static void
2235 etgen2(Sym *s)
2236 {
2237 	Syml *sl;
2238 	static Syml *frees;
2239 	static Symq symq, symq1;
2240 
2241 	if(s != nil){
2242 		newsec(2);
2243 		sl = newsyml(s, &frees);
2244 		adde(sl, &symq);
2245 		if(isinteger(s->tenum) && isbigv(s->vconst) && !isbig(s->tenum))
2246 			s->tenum = types[TVLONG];
2247 		return;
2248 	}
2249 	/* end of enums */
2250 	if(symq.f && symq.f == symq.r){	/* try to merge with other singletons */
2251 		adde(symq.f, &symq1);
2252 		symq.f = symq.r = nil;
2253 		return;
2254 	}
2255 	if(symq1.f){
2256 		for(sl = symq1.f; sl != nil; sl = etseq(sl))
2257 			;
2258 		freeq(&symq1, &frees);
2259 	}
2260 	if(symq.f){
2261 		for(sl = symq.f; sl != nil; sl = etseq(sl))
2262 			;
2263 		freeq(&symq, &frees);
2264 	}
2265 }
2266 
2267 static void
2268 lgen(Node *n, int br, int first)
2269 {
2270 	if(br)
2271 		prdelim("(");
2272 	if(n == Z){
2273 		if(br)
2274 			prdelim(")");
2275 		return;
2276 	}
2277 	if(n->op == OLIST || n->op == OTUPLE){
2278 		lgen(n->left, 0, first);
2279 		lgen(n->right, 0, 0);
2280 	}
2281 	else if(n->op != ODOTDOT){
2282 		if(!first)
2283 			prdelim(", ");
2284 		egen(n, ONOOP, PRE);
2285 	}
2286 	else
2287 		prcom("was ...", Z);
2288 	if(br)
2289 		prdelim(")");
2290 }
2291 
2292 static void
2293 preced(int op1, int op2, int s, int c)
2294 {
2295 	int p1, p2, k1, k2, br;
2296 	char buf[2];
2297 
2298 	br = 0;
2299 	p1 = ops[op1].prec;
2300 	p2 = ops[op2].prec;
2301 	if(p1 < 0 || p2 < 0)
2302 		diag(Z, "-ve precedence");
2303 	if(p1 > p2)
2304 		br = 1;
2305 	else if(p1 == p2){
2306 		k1 = ops[op1].kind;
2307 		k2 = ops[op2].kind;
2308 		if(op1 == op2){
2309 			if(k1&RASSOC)
2310 				br = s == LEFT;
2311 			else
2312 				br = s == RIGHT && !(k1&ASSOC);
2313 		}
2314 		else{
2315 			if(k1&RASSOC)
2316 				br = s == LEFT;
2317 			else
2318 				br = s == RIGHT && op1 != OADD;
2319 
2320 			if(k1&POSTOP && !(k2&POSTOP))
2321 				br = 1;
2322 
2323 			/* funny case */
2324 			if(op2 == OMDOT && s == LEFT && (op1 == ODOT || op1 == ODOTIND))
2325 				br = 1;
2326 		}
2327 	}
2328 	if(br){
2329 		buf[0] = c;
2330 		buf[1] = '\0';
2331 		prdelim(buf);
2332 	}
2333 }
2334 
2335 static void
2336 egen(Node *n, int op0, int side)
2337 {
2338 	int op, p;
2339 	Type *t;
2340 	Node *nn;
2341 
2342 	if(n == Z){
2343 		if(op0 == OBRACKET)
2344 			prdelim("()");
2345 		return;
2346 	}
2347 	if(n->op == OCONST && n->left != Z){	/* actual node in source */
2348 		n->left->type = n->type;
2349 		n = n->left;
2350 	}
2351 	if((n->op == OSTRING || n->op == OLSTRING) && n->left != Z)	/* actual node in source */
2352 		n = n->left;
2353 	if(n->op == OCAST && (lteq(n->type, n->left->type) || isnil(n) || !iscastable(n->type, n->left->type))){
2354 		if(isnil(n))
2355 			prid("nil");
2356 		else
2357 			egen(n->left, op0, side);
2358 		return;
2359 	}
2360 	if(n->op == ONAME && arrow(n->sym))
2361 		n->op = OMDOT;
2362 	if(n->op != OLIST)
2363 		output(n->lineno, 0);
2364 	op = n->op;
2365 	preced(op0, op, side, '(');
2366 	switch(op){
2367 		case OLIST:
2368 		case OTUPLE:
2369 			lgen(n, 1, 1);
2370 			break;
2371 		case OIOTA:
2372 			prid("iota");
2373 			break;
2374 		case OMDOT:
2375 		case ONAME:
2376 		case OXXX:
2377 			prsym(n->sym, 1);
2378 			break;
2379 		case OCONST:
2380 			if(n->kind == KCHR)
2381 				prchar(n->vconst);
2382 			else if(isreal(n->type))
2383 				prreal(n->fconst, n->cstring, n->kind);
2384 			else if(isnil(n))
2385 				prid("nil");
2386 			else
2387 				prnum(n->vconst, n->kind, n->type);
2388 			if(n->right != Z)
2389 				prcom("was ", n->right);
2390 			break;
2391 		case OSTRING:
2392 			prstr(n->cstring);
2393 			break;
2394 		case OLSTRING:
2395 			prlstr(n->rstring);
2396 			break;
2397 		case OCOND:
2398 			egen(n->left, op, POST);
2399 			prdelim(" ? ");
2400 			egen(n->right->left, op, PRE|POST);
2401 			prdelim(" : ");
2402 			egen(n->right->right, op, PRE);
2403 			prcom("?", Z);
2404 			break;
2405 		case OCOMMA:
2406 			if(op0 != OCOMMA)
2407 				prdelim("(");
2408 			egen(n->left, op, LEFT);
2409 			prdelim(", ");
2410 			egen(n->right, op, RIGHT);
2411 			if(op0 != OCOMMA)
2412 				prdelim(")");
2413 			break;
2414 		case OLDOT:
2415 			egen(n->left, OMOD, LEFT);	/* any precedence 13 operator */
2416 			prdelim(".");
2417 			egen(n->right, op, RIGHT);
2418 			break;
2419 		default:
2420 			p = ops[op].prec;
2421 			egen(n->left, op, LEFT);
2422 			if(space[p])
2423 				prdelim(" ");
2424 			prdelim(ops[op].name);
2425 			if(space[p])
2426 				prdelim(" ");
2427 			egen(n->right, op, RIGHT);
2428 			break;
2429 		case OIND: case OADDR: case OSADDR:
2430 		case OPOS: case ONEG:
2431 		case ONOT: case OCOM:
2432 		case OPREINC: case OPREDEC:
2433 			if(op == OADDR){
2434 				n->op = OSADDR;
2435 				if(!isfn(n->left->type))
2436 					prcom("was ", n);
2437 			}
2438 			else
2439 				prdelim(ops[op].name);
2440 			egen(n->left, op, PRE);
2441 			break;
2442 		case OPOSTINC: case OPOSTDEC:
2443 			egen(n->left, op, POST);
2444 			prdelim(ops[op].name);
2445 			break;
2446 		case ODOT:
2447 			egen(n->left, op, LEFT);
2448 			dotpath(n->sym, n->left->type, 1);
2449 			/* prdelim(ops[op].name); */
2450 			/* prsym(n->sym, 0); */
2451 			break;
2452 		case ODOTIND:
2453 			egen(n->left, op, LEFT);
2454 			if(isadt(n->left->type))
2455 				dotpath(n->sym, n->left->type, 1);	/* type may be demoted arg */
2456 			else
2457 				dotpath(n->sym, n->left->type->link, 1);
2458 			/* prdelim(ops[op].name); */
2459 			/* prsym(n->sym, 0); */
2460 			break;
2461 		case OARRIND:
2462 			egen(n->left, op, LEFT);
2463 			prdelim("[");
2464 			egen(n->right, ONOOP, RIGHT);
2465 			prdelim("]");
2466 			if(n->right->op == OCONST && n->right->vconst < 0)
2467 				prcom("negative array index", Z);
2468 			break;
2469 		case OLEN:
2470 			prid("len ");
2471 			egen(n->right, op, PRE);
2472 			break;
2473 		case OREF:
2474 			prid("ref ");
2475 			tgen(n->type->link, 0, 0);
2476 			break;
2477 		case OARRAYOF:
2478 			prid("array");
2479 			prdelim("[");
2480 			egen(n->left, ONOOP, LEFT);
2481 			prdelim("]");
2482 			prid(" of ");
2483 			tgen(n->type->link, 0, 0);
2484 			break;
2485 		case OSLICE:
2486 			egen(n->left, op, LEFT);
2487 			prdelim("[");
2488 			egen(n->right->left, ONOOP, RIGHT);
2489 			prdelim(": ");
2490 			egen(n->right->right, ONOOP, RIGHT);
2491 			prdelim("]");
2492 			break;
2493 		case OFUNC:
2494 			if(n->kind == KEXP)
2495 				egen(n->left, op, LEFT);
2496 			else
2497 				prsym(n->left->sym, 0);
2498 			lgen(n->right, 1, 1);
2499 			if(n->kind != KEXP && !isvoid(n->left->type->link)){
2500 				prdelim(": ");
2501 				tgen(n->left->type->link, 0, 0);
2502 			}
2503 			break;
2504 		case	ONIL:
2505 			prid("nil");
2506 			break;
2507 		case OCAST:
2508 			if(isnil(n))
2509 				prid("nil");
2510 			else if(iscastable(n->type, n->left->type)){
2511 				tgen(n->type, 0, 0);
2512 				prdelim(" ");
2513 				egen(n->left, op, RIGHT);
2514 			}
2515 			else
2516 				egen(n->left, op0, RIGHT);
2517 			break;
2518 		case OARRAY:
2519 			tgen(n->type, 0, 0);
2520 			egen(n->left, op, LEFT);
2521 			prdelim("[");
2522 			egen(n->right, ONOOP, RIGHT);
2523 			prdelim("]");
2524 			break;
2525 		case OSTRUCT:
2526 		case OUNION:
2527 			tgen(n->type, 0, 0);
2528 			lgen(n->left, 1, 1);
2529 			break;
2530 		case OELEM:
2531 			prdelim(".");
2532 			/* tgen(n->type, 0, 0, 0); */
2533 			prsym(n->sym, 0);
2534 			break;
2535 		case OSIZE:
2536 		case OSIGN:
2537 			prid(ops[op].name);
2538 			if(n->left != Z)
2539 				egen(n->left, OBRACKET, RIGHT);
2540 			else{
2541 				prdelim(" ");
2542 				prid(tnames[n->type->etype]);
2543 				if(typesu[n->type->etype] && n->type->tag){
2544 					prdelim(" ");
2545 					prid(n->type->tag->name);
2546 				}
2547 			}
2548 			break;
2549 		case OPROTO:
2550 			nn = n;
2551 			t = n->type;
2552 			n = protoname(n);
2553 			if(n != Z)
2554 				t = n->type;
2555 			else
2556 				t = prototype(nn->left, t);
2557 			if(!isvoid(t) || n != Z){
2558 				if(n == Z)
2559 					prid("nil");
2560 				else if(n->op == ODOTDOT){
2561 					prcom("was ...", Z);
2562 					break;
2563 				}
2564 				else
2565 					prsym(n->sym, 0);
2566 				/* egen(n, ONOOP, PRE); */
2567 				prdelim(": ");
2568 				tgen(t, 1, 0);
2569 			}
2570 			break;
2571 		case ODOTDOT:
2572 			prid("...");
2573 			break;
2574 		case OINIT:
2575 			egen(n->left, ONOOP, PRE);
2576 			break;
2577 		case OS2AB:
2578 			prid("libc0->s2ab");
2579 			prdelim("(");
2580 			egen(n->left, ONOOP, PRE);
2581 			prdelim(")");
2582 			usemod(libcop, 1);
2583 			break;
2584 		case OAB2S:
2585 			prid("libc0->ab2s");
2586 			prdelim("(");
2587 			egen(n->left, ONOOP, PRE);
2588 			prdelim(")");
2589 			usemod(libcop, 1);
2590 			break;
2591 		case OFILDES:
2592 			prid("sys->fildes");
2593 			prdelim("(");
2594 			egen(n->left, ONOOP, PRE);
2595 			prdelim(")");
2596 			usemod(sysop, 1);
2597 			break;
2598 		case OFD:
2599 			egen(n->left, op, LEFT);
2600 			prdelim(ops[op].name);
2601 			prid("fd");
2602 			break;
2603 		case OT0:
2604 			egen(n->left, op, LEFT);
2605 			prdelim(ops[op].name);
2606 			prid("t0");
2607 			break;
2608 		case ORETV:
2609 			n->op = OAS;
2610 			nn = n->left;
2611 			p = isvoid(n->type) || n->type->etype != TTUPLE || n->type->mark == TCPC;
2612 			if(p)
2613 				n->left = n->right;
2614 			else
2615 				n->left = new1(OTUPLE, new1(ONIL, Z, Z), n->right);
2616 			n->right = nn;
2617 			n->left->type = n->type;
2618 			if(!p && op0 != ONOOP)
2619 				addnode(OT0, n);
2620 			egen(n, op0, side);
2621 			break;
2622 		case OCAT:
2623 			egen(n->left, op, LEFT);
2624 			prdelim(" + ");
2625 			egen(n->right, op, RIGHT);
2626 			break;
2627 	}
2628 	preced(op0, op, side, ')');
2629 }
2630 
2631 static int
2632 isexpr(Node *n, Type *t)
2633 {
2634 	if(n == Z)
2635 		return 0;
2636 	if(n->op == OLIST || n->op == OINIT || n->op == OSTRUCT)
2637 		return 0;
2638 	if(teq(t, n->type))
2639 		return 1;
2640 	return 0;
2641 }
2642 
2643 static Node *
2644 nxtval(Node *n, Node **nn)
2645 {
2646 	if(n == Z){
2647 		*nn = Z;
2648 		return Z;
2649 	}
2650 	if(n->op == OLIST){
2651 		*nn = n->right;
2652 		return n->left;
2653 	}
2654 	*nn = Z;
2655 	return n;
2656 }
2657 
2658 static Node*
2659 eagen(Node *n, Type *t, int ar, int *nz, int depth)
2660 {
2661 	int i, w, nw, down;
2662 	Type *t1;
2663 	Node *nn, *tn;
2664 
2665 	if(n != Z){
2666 		if(n->type == T && t == T){
2667 			egen(n, ONOOP, PRE);
2668 			if(ar){
2669 				prdelim(",");
2670 				newline();
2671 			}
2672 			return Z;
2673 		}
2674 		if(ar && n->op == OLIST && n->left->op == OARRAY){
2675 			egen(n->left->left, ONOOP, PRE);
2676 			prdelim(" => ");
2677 			n = n->right;
2678 		}
2679 		if(n->op == OLIST && n->left->op == OELEM){
2680 			prcom("cannot do ", n->left);
2681 			n = n->right;
2682 		}
2683 		if(n->op == OUSED || n->op == ODOTDOT)
2684 			n = n->left;
2685 		if(t == T)
2686 			t = n->type;
2687 	}
2688 	switch(t->etype){
2689 		case TSTRUCT:
2690 		case TUNION:
2691 			if(isexpr(n, t))
2692 				goto Default;
2693 			down = 0;
2694 			tn = nxtval(n, &nn);
2695 			if(tn != Z && (tn->op == OINIT || tn->op == OSTRUCT)){
2696 				down = 1;
2697 				n = tn->left;
2698 			}
2699 			if(depth > 0){
2700 				tgen(t, 0, 0);
2701 				prdelim(" ");
2702 			}
2703 			prdelim("(");
2704 			for(t1 = t->link; t1 != T; t1 = t1->down){
2705 				if(n == Z)
2706 					n = defval(t1);
2707 				n = eagen(n, t1, 0, nil, depth+1);
2708 				if(t1->down != T){
2709 					prdelim(",");
2710 					if(ar)
2711 						prdelim("\t");
2712 					else
2713 						prdelim(" ");
2714 				}
2715 			}
2716 			prdelim(")");
2717 			if(down)
2718 				n = nn;
2719 			break;
2720 		case TARRAY:
2721 			if(isexpr(n, t))
2722 				goto Default;
2723 			if(depth > 0){
2724 				tgen(t, 0, 1);
2725 				prdelim(" ");
2726 			}
2727 			prdelim("{");
2728 			newline();
2729 			incind();
2730 			w = t->width/t->link->width;
2731 			nw = 0;
2732 			for(i = 0; i < w; i++){
2733 				down = 0;
2734 				tn = nxtval(n, &nn);
2735 				if(tn != Z && (tn->op == OINIT || tn->op == OSTRUCT)){
2736 					down = 1;
2737 					n = tn->left;
2738 				}
2739 				n = eagen(n, t->link, 1, &nw, depth+1);
2740 				if(down)
2741 					n = nn;
2742 			}
2743 			if(nw > 0){
2744 				if(nw > 1)
2745 					prdelim("* => ");
2746 				egen(defval(t->link), ONOOP, PRE);
2747 				newline();
2748 			}
2749 			decind();
2750 			prdelim("}");
2751 			break;
2752 		default:
2753 Default:
2754 			if(n == Z){
2755 				if(ar)
2756 					(*nz)++;
2757 				else
2758 					egen(defval(t), ONOOP, PRE);
2759 				return Z;
2760 			}
2761 			n = nxtval(n, &nn);
2762 			if(ar && isnil(n) && iscastable(t, types[TINT])){
2763 				tgen(t, 0, 0);
2764 				prdelim(" ");
2765 			}
2766 			egen(n, ONOOP, PRE);
2767 			n = nn;
2768 			break;
2769 	}
2770 	if(ar){
2771 		prdelim(",");
2772 		newline();
2773 	}
2774 	return n;
2775 }
2776 
2777 /* better is
2778  *	array of byte "abcde\0"
2779  * but limbo compiler does not accept this as a constant expression
2780  */
2781 static void
2782 stob(Node *n)
2783 {
2784 	int m;
2785 	char *s = nil, buf[UTFmax];
2786 	Rune *u = nil;
2787 
2788 	while(n->op == ONAME)
2789 		n = n->sym->nconst;
2790 	if(n->op == OSTRING)
2791 		s = n->cstring;
2792 	else
2793 		u = n->rstring;
2794 	prdelim("{ ");
2795 	if(s){
2796 		while(*s){
2797 			prid("byte ");
2798 			prchar(*s++);
2799 			prdelim(", ");
2800 		}
2801 	}
2802 	else{
2803 		while(*u){
2804 			m = runetochar(buf, u++);
2805 			s = buf;
2806 			while(--m >= 0){
2807 				prid("byte ");
2808 				prchar(*s++);
2809 				prdelim(", ");
2810 			}
2811 		}
2812 	}
2813 	prid("byte ");
2814 	prchar('\0');
2815 	prdelim(" }");
2816 }
2817 
2818 static Type *arrayofchar;
2819 
2820 static void
2821 sdgen(Node *n, int glob)
2822 {
2823 	int sop = 0;
2824 
2825 	prdelim(" := ");
2826 	if(glob && n->right->op == OS2AB && isstring(n->right->left)){
2827 		if(arrayofchar == T){
2828 			arrayofchar = typ1(TARRAY, types[TCHAR]);
2829 			arrayofchar->width = 0;
2830 		}
2831 		n->type = n->right->type = arrayofchar;
2832 		sop = 1;
2833 	}
2834 	else
2835 		n->type = n->right->type = T;
2836 	tgen(n->type, 0, 1);
2837 	if(sop)
2838 		stob(n->right->left);
2839 	else
2840 		eagen(n->right, n->type, 0, nil, 0);
2841 	prdelim(";");
2842 	newline();
2843 }
2844 
2845 static void
2846 tdgen(Node *n, int glob)
2847 {
2848 	int ar, arinit;
2849 
2850 	if(ism()){
2851 		prdelim(": ");
2852 		tgen(n->type, 1, 0);
2853 		if(n->op == ODAS)
2854 			prcom("initial value was ", n->right);
2855 		prdelim(";");
2856 		newline();
2857 		return;
2858 	}
2859 	if(n->op == ODAS && (isstring(n->right) || n->right->op == OS2AB)){
2860 		sdgen(n, glob);
2861 		return;
2862 	}
2863 	ar = n->type->etype == TARRAY && n->type->width != LARR;
2864 	arinit = ar && n->op == ODAS;
2865 	if(ar)
2866 		prdelim(" := ");
2867 	else
2868 		prdelim(": ");
2869 	tgen(n->type, 0, arinit);
2870 	if(n->op == ODAS){
2871 		if(!arinit)
2872 			prdelim(" = ");
2873 		eagen(n->right, n->type, 0, nil, 0);
2874 	}
2875 	prdelim(";");
2876 	newline();
2877 }
2878 
2879 static int
2880 isdec(Node *n)
2881 {
2882 	return isname(n) && n->kind != KEXP || n->op == ODAS;
2883 }
2884 
2885 static void
2886 sgen(Node *n, int blk, Node **ln)
2887 {
2888 	int comma = 0;
2889 	Node *nn;
2890 
2891 	if(n == Z)
2892 		return;
2893 	if(blk){
2894 		pushscope(n, SAUTO);
2895 		if(n->op == OLIST && !(blk&NOBR) || (blk&YESBR)){
2896 			prdelim("{");
2897 			newline();
2898 		}
2899 		else if(!(blk&NONL))
2900 			newline();
2901 		if(!(blk&NOIN))
2902 			incind();
2903 	}
2904 	if((nn = *ln) != Z && isdec(nn)){
2905 		if(isdec(n)){
2906 			if(canjoin(nn, n))
2907 				comma = 1;
2908 			else
2909 				tdgen(nn, 0);
2910 		}
2911 		else if(n->op != OLIST){
2912 			tdgen(nn, 0);
2913 			newline();
2914 		}
2915 	}
2916 	if(n->op != OLIST){
2917 		*ln = n;
2918 		output(n->lineno, 1);
2919 	}
2920 	switch(n->op){
2921 		default:
2922 			egen(n, ONOOP, PRE);
2923 			prdelim(";");
2924 			newline();
2925 			break;
2926 		case ODAS:
2927 			pushdcl(n->left, CAUTO);
2928 			egen(n->left, ONOOP, PRE);
2929 			break;
2930 		case ONAME:
2931 			if(n->kind == KEXP){
2932 				egen(n, ONOOP, PRE);
2933 				prdelim(";");
2934 				newline();
2935 			}
2936 			else{
2937 				pushdcl(n, CAUTO);
2938 				if(comma)
2939 					prdelim(", ");
2940 				if(n->op != ONAME)
2941 					diag(n, "internal: not name in sgen");
2942 				prsym(n->sym, 0);
2943 				/* egen(n, ONOOP, PRE); */
2944 /*
2945 				prdelim(": ");
2946 				tgen(n->type, 0, 0, 0);
2947 				prdelim(";");
2948 				newline();
2949 */
2950 			}
2951 			break;
2952 		case OSBREAK:
2953 			break;
2954 		case ONUL:
2955 			prdelim(";");
2956 			newline();
2957 			break;
2958 		case OBLK:
2959 			sgen(n->left, 1|YESBR, ln);
2960 			break;
2961 		case OLIST:
2962 			sgen(n->left, 0, ln);
2963 			sgen(n->right, 0, ln);
2964 			break;
2965 		case ORETURN:
2966 			prkeywd("return");
2967 			if(n->left != Z)
2968 				prdelim(" ");
2969 			egen(n->left, ONOOP, PRE);
2970 			prdelim(";");
2971 			newline();
2972 			break;
2973 		case OLABEL:
2974 			prcom("was label ", n->left);
2975 			/* i = zeroind(); */
2976 			/* egen(n->left, ONOOP, PRE); */
2977 			/* prdelim(":"); */
2978 			newline();
2979 			/* restoreind(i); */
2980 			break;
2981 		case OGOTO:
2982 			prcom("was goto ", n->left);
2983 			/* prkeywd("goto "); */
2984 			/* egen(n->left, ONOOP, PRE); */
2985 			prdelim(";");
2986 			newline();
2987 			break;
2988 		case OCASE:
2989 			for(nn = n->left; nn != Z; nn = nn->right){
2990 				if(nn != n->left)
2991 					prkeywd(" or ");
2992 				if(nn->left != Z)
2993 					egen(nn->left, ONOOP, PRE);
2994 				else
2995 					prkeywd("*");
2996 			}
2997 			prdelim(" =>");
2998 			clrbrk(n->right);
2999 			sgen(n->right, 1|NOBR, ln);
3000 			if(n->kind != KLAST && !hasbrk(n->right)){
3001 				prcom("fall through", Z);
3002 				newline();
3003 			}
3004 			break;
3005 		case OSWITCH:
3006 			prkeywd("case");
3007 			egen(n->left, OBRACKET, PRE);
3008 			sgen(n->right, 1|NOIN|YESBR, ln);
3009 			break;
3010 		case OWHILE:
3011 			prkeywd("while");
3012 			egen(n->left, OBRACKET, PRE);
3013 			sgen(n->right, 1, ln);
3014 			break;
3015 		case ODWHILE:
3016 			prkeywd("do");
3017 			sgen(n->right, 1|NOENL, ln);
3018 			prkeywd("while");
3019 			egen(n->left, OBRACKET, PRE);
3020 			prdelim(";");
3021 			newline();
3022 			break;
3023 		case OFOR:
3024 			prkeywd("for");
3025 			prdelim("(");
3026 			egen(n->left->right->left, ONOOP, PRE);
3027 			prdelim(";");
3028 			if(n->left->left != Z)
3029 				prdelim(" ");
3030 			egen(n->left->left, ONOOP, PRE);
3031 			prdelim(";");
3032 			if(n->left->right->right != Z)
3033 				prdelim(" ");
3034 			egen(n->left->right->right, ONOOP, PRE);
3035 			prdelim(")");
3036 			sgen(n->right, 1, ln);
3037 			break;
3038 		case OCONTINUE:
3039 			prkeywd("continue");
3040 			prdelim(";");
3041 			newline();
3042 			break;
3043 		case OBREAK:
3044 			prkeywd("break");
3045 			prdelim(";");
3046 			newline();
3047 			break;
3048 		case OIF:
3049 			prkeywd("if");
3050 			egen(n->left, OBRACKET, PRE);
3051 			if(n->right->left->op == OIF && n->right->left->right->right == Z && n->right->right != Z)		/* avoid dangling else */
3052 				sgen(n->right->left, 1|YESBR, ln);
3053 			else
3054 				sgen(n->right->left, 1, ln);
3055 			if(n->right->right != Z){
3056 				prdelim("else");
3057 				if(n->right->right->op == OIF){	/* merge else and if */
3058 					prdelim(" ");
3059 					sgen(n->right->right, 1|NONL|NOIN, ln);
3060 				}
3061 				else
3062 					sgen(n->right->right, 1, ln);
3063 			}
3064 			break;
3065 		case OSET:
3066 		case OUSED:
3067 			prkeywd(ops[n->op].name);
3068 			lgen(n->left, 1, 1);
3069 			prdelim(";");
3070 			newline();
3071 			break;
3072 	}
3073 	if(blk){
3074 		if(!(blk&NOIN))
3075 			decind();
3076 		if(n->op == OLIST&& !(blk&NOBR) || (blk&YESBR)){
3077 			prdelim("}");
3078 			if(!(blk&NOENL))
3079 				newline();
3080 		}
3081 		popscope();
3082 	}
3083 }
3084 
3085 static void rew(Node*, int);
3086 
3087 static void
3088 rewc0(Node *n, Node *r)
3089 {
3090 	Node *nn;
3091 
3092 	if((nn = cfind(n)) != Z){
3093 		cgen0(nn, n);
3094 		if(r->op == ORETURN){
3095 			n->right->left = new1(ORETURN, n->right->left, Z);
3096 			n->right->right = new1(ORETURN, n->right->right, Z);
3097 			n->right->left->type = n->right->left->left->type;
3098 			n->right->right->type = n->right->right->left->type;
3099 			*r = *n;
3100 		}
3101 	}
3102 }
3103 
3104 static void
3105 rewc1(Node *n)
3106 {
3107 	Node *c, *nc;
3108 
3109 	if(n == Z || n->op != OCOND || side(n) || !simple(n))
3110 		return;
3111 	c = n->left;
3112 	nc = new1(ONOT, ncopy(c), Z);
3113 	n->op = OOROR;
3114 	n->left = new1(OANDAND, c, n->right->left);
3115 	n->right = new1(OANDAND, nc, n->right->right);
3116 }
3117 
3118 static void
3119 rewc(Node *n, Node *r)
3120 {
3121 	Node *nn, *rr, *i;
3122 
3123 	if((nn = cfind(n)) != Z){
3124 		i = cgen(nn, n);
3125 		rr = new1(OXXX, Z, Z);
3126 		if(n == r && nn == n)
3127 			*rr = *nn;
3128 		else
3129 			*rr = *r;
3130 		r->op = OLIST;
3131 		r->left = i;
3132 		r->right = rr;
3133 	}
3134 }
3135 
3136 static int
3137 rewe(Node *n, Type *t, int lev)
3138 {
3139 	int op, k, k1, k2;
3140 	int v;
3141 	Node *nn;
3142 
3143 	if(n == Z)
3144 		return -1;
3145 	switch(n->op){
3146 		case OCONST:
3147 			break;
3148 		case ONAME:
3149 			if(strings || !isstring(n))
3150 				break;
3151 		case OSTRING:
3152 		case OLSTRING:
3153 			if(!strings)
3154 				addnode(OS2AB, n);
3155 			break;
3156 		case OCOND:
3157 			bptr(n->left);
3158 			rewe(n->left, T, 1);
3159 			rewe(n->right, T, 1);
3160 			break;
3161 		case OIND:
3162 			if(isfn(n->type)){
3163 				*n = *n->left;
3164 				rewe(n, T, 1);
3165 				break;
3166 			}
3167 			if(!isadt(n->type)){
3168 				n->op = OARRIND;
3169 				n->right = con(0);
3170 				rewe(n, T, 1);
3171 				break;
3172 			}
3173 			rewe(n->left, T, 1);
3174 			break;
3175 		case OADDR:
3176 			if(n->left->op == OARRIND){
3177 				n->right = n->left;
3178 				n->left = n->right->left;
3179 				n->right->left = n->right->right;
3180 				n->right->right = Z;
3181 				n->right->op = OLIST;
3182 				n->op = OSLICE;
3183 				rewe(n, T, 1);
3184 				break;
3185 			}
3186 			rewe(n->left, T, 1);
3187 			break;
3188 		case OSLICE:
3189 			rewe(n->left, T, 1);
3190 			rewe(n->right, T, 1);
3191 			if(n->left->op == OSLICE){
3192 				n->right->left = addn(n->left->right->left, n->right->left);
3193 				n->right->right = addn(n->left->right->left, n->right->right);
3194 				n->left = n->left->left;
3195 				rewe(n, T, 1);
3196 				break;
3197 			}
3198 			break;
3199 		case OCOMMA:
3200 			rewe(n->left, T, 1);
3201 			rewe(n->right, T, 1);
3202 			if(n->left->op == OAS && n->right->op == OAS){
3203 				n->op = OAS;
3204 				n->left->op = n->right->op = OLIST;
3205 				nn = n->left->right;
3206 				n->left->right = n->right->left;
3207 				n->right->left = nn;
3208 				rewe(n, T, 1);
3209 				break;
3210 			}
3211 			break;
3212 		case OFUNC:
3213 			if(n->left->op == ONAME){
3214 				if((k = n->left->sym->kind) != LNONE){
3215 					rewlc(n, k, t);
3216 					rewe(n->left, T, 1);
3217 					rewe(n->right, T, 1);
3218 					args(n);
3219 					return k;
3220 				}
3221 			}
3222 			else
3223 				rewe(n->left, T, 1);
3224 			rewe(n->right, T, 1);
3225 			args(n);
3226 			break;
3227 		case OCAST:
3228 			rewe(n->left, n->type, 1);
3229 			break;
3230 		case OAS:
3231 		case OASI:
3232 		case OASD:
3233 			rewe(n->left, T, 1);
3234 			rewe(n->right, n->type, 1);
3235 			break;
3236 		case ONOT:
3237 		case OANDAND:
3238 		case OOROR:
3239 			bptr(n);
3240 			rewe(n->left, T, 1);
3241 			rewe(n->right, T, 1);
3242 			break;
3243 		case OPREINC:
3244 		case OPOSTINC:
3245 		case OASADD:
3246 			if(n->op != OPOSTINC || lev == 0){
3247 				sliceasgn(n);
3248 				if(n->op == OAS){
3249 					rewe(n, T, 1);
3250 					break;
3251 				}
3252 			}
3253 			rewe(n->left, T, 1);
3254 			rewe(n->right, T, 1);
3255 			break;
3256 		case OEQ:
3257 		case ONE:
3258 		case OLT:
3259 		case OLE:
3260 		case OGT:
3261 		case OGE:
3262 			k1 = rewe(n->left, T, 1);
3263 			k2 = rewe(n->right, T, 1);
3264 			if(k1 == LSTRCMP && n->right->op == OCONST){
3265 				op = -1;
3266 				v = n->right->vconst;
3267 				switch(v){
3268 					case -1:
3269 						if(n->op == OEQ)
3270 							op = OLT;
3271 						else if(n->op == ONE)
3272 							op = OGE;
3273 						break;
3274 					case 0:
3275 						op = n->op;
3276 						break;
3277 					case 1:
3278 						if(n->op == OEQ)
3279 							op = OGT;
3280 						else if(n->op == ONE)
3281 							op = OLE;
3282 						break;
3283 				}
3284 				if(op != -1){
3285 					*n = *n->left;
3286 					n->op = op;
3287 				}
3288 			}
3289 			if(k2 == LSTRCMP && n->left->op == OCONST){
3290 				op = -1;
3291 				v = n->left->vconst;
3292 				switch(v){
3293 					case -1:
3294 						if(n->op == OEQ)
3295 							op = OLT;
3296 						else if(n->op == ONE)
3297 							op = OGE;
3298 						break;
3299 					case 0:
3300 						op = rev(n->op);
3301 						break;
3302 					case 1:
3303 						if(n->op == OEQ)
3304 							op = OGT;
3305 						else if(n->op == ONE)
3306 							op = OLE;
3307 						break;
3308 				}
3309 				if(op != -1){
3310 					*n = *n->right;
3311 					n->op = op;
3312 				}
3313 			}
3314 			break;
3315 		default:
3316 			rewe(n->left, T, 1);
3317 			rewe(n->right, T, 1);
3318 			break;
3319 	}
3320 	return -1;
3321 }
3322 
3323 /*
3324 static void
3325 rewf(Node *n)
3326 {
3327 	if(n == Z)
3328 		return;
3329 	switch(n->op){
3330 		case OFUNC:
3331 			if(n->left->op == ONAME)
3332 				fdargs(n);
3333 			break;
3334 		default:
3335 			rewf(n->left);
3336 			rewf(n->right);
3337 			break;
3338 	}
3339 }
3340 */
3341 
3342 static void
3343 rew(Node *n, int blk)
3344 {
3345 	int i;
3346 	Node *a, *nn;
3347 
3348 	if(n == Z)
3349 		return;
3350 	if(blk)
3351 		pushscope(n, SAUTO);
3352 	nearln = n->lineno;
3353 	if(n->blk){
3354 		n->blk = 0;
3355 		addnode(OBLK, n);
3356 	}
3357 	switch(n->op){
3358 		default:
3359 			if(simple(n))
3360 				rewc0(n, n);
3361 			else
3362 				rewc(n, n);
3363 			if(n->op == OLIST || n->op == OIF){
3364 				rew(n, 0);
3365 				break;
3366 			}
3367 			ecomplex(n);
3368 			break;
3369 		case ODAS:
3370 			pushdcl(n->left, CAUTO);
3371 			rewe(n->right, T, 1);
3372 			break;
3373 		case OSBREAK:
3374 		case ONUL:
3375 			break;
3376 		case ONAME:
3377 			if(n->kind == KEXP)
3378 				ecomplex(n);
3379 			else
3380 				pushdcl(n, CAUTO);
3381 			break;
3382 		case OBLK:
3383 			rew(n->left, 1);
3384 			break;
3385 		case OLIST:
3386 			rew(n->left, 0);
3387 			rew(n->right, 0);
3388 			break;
3389 		case ORETURN:
3390 			if(simple(n->left))
3391 				rewc0(n->left, n);
3392 			else
3393 				rewc(n->left, n);
3394 			if(n->op != ORETURN){
3395 				rew(n, 0);
3396 				break;
3397 			}
3398 			ecomplex(n);
3399 			break;
3400 		case OLABEL:
3401 		case OGOTO:
3402 			break;
3403 		case OCASE:
3404 			for(nn = n->left; nn != Z; nn = nn->right)
3405 				if(nn->left != Z)
3406 					ecomplex(nn->left);
3407 			rew(n->right, 1);
3408 			break;
3409 		case OSWITCH:
3410 			rewc(n->left, n);
3411 			if(n->op == OLIST){
3412 				rew(n, 0);
3413 				break;
3414 			}
3415 			ecomplex(n->left);
3416 			if(!lteq(n->left->type, types[TINT]))
3417 				intcast(n->left);
3418 			n->right = buildcases(n->right);
3419 			rew(n->right, 1);
3420 			break;
3421 		case OWHILE:
3422 		case ODWHILE:
3423 			rewc1(n->left);
3424 			becomplex(n->left);
3425 			rew(n->right, 1);
3426 			break;
3427 		case OFOR:
3428 			rewc1(n->left->left);
3429 			rewc(n->left->right->left, n);
3430 			if(n->op == OLIST){
3431 				rew(n, 0);
3432 				break;
3433 			}
3434 			becomplex(n->left->left);
3435 			ecomplex(n->left->right->left);
3436 			ecomplex(n->left->right->right);
3437 			rew(n->right, 1);
3438 			break;
3439 		case OCONTINUE:
3440 			break;
3441 		case OBREAK:
3442 			break;
3443 		case OIF:
3444 			rewc1(n->left);
3445 			rewc(n->left, n);
3446 			if(n->op == OLIST){
3447 				rew(n, 0);
3448 				break;
3449 			}
3450 			becomplex(n->left);
3451 			rew(n->right->left, 1);
3452 			rew(n->right->right, 1);
3453 			break;
3454 		case OSET:
3455 			if(n->left == Z){
3456 				n->op = ONUL;
3457 				n->left = n->right = Z;
3458 				break;
3459 			}
3460 			if(n->left->op != OLIST){
3461 				n->op = OAS;
3462 				n->right = defval(n->left->type);
3463 				rew(n, 0);
3464 				break;
3465 			}
3466 			i = 0;
3467 			nn = Z;
3468 			for(;;){
3469 				a = arg(n->left, i);
3470 				if(a == Z)
3471 					break;
3472 				a = new1(OAS, a, defval(a->type));
3473 				if(i == 0)
3474 					nn = a;
3475 				else
3476 					nn = new1(OLIST, nn, a);
3477 				i++;
3478 			}
3479 			*n = *nn;
3480 			rew(n, 0);
3481 			break;
3482 		case OUSED:
3483 			if(n->left == Z){
3484 				n->op = ONUL;
3485 				n->left = n->right = Z;
3486 				break;
3487 			}
3488 			i = 0;
3489 			nn = Z;
3490 			for(;;){
3491 				a = arg(n->left, i);
3492 				if(a == Z)
3493 					break;
3494 				if(i == 0)
3495 					nn = a;
3496 				else
3497 					nn = new1(OOROR, nn, a);
3498 				i++;
3499 			}
3500 			n->op = OIF;
3501 			n->left = nn;
3502 			n->right = new1(OLIST, Z, Z);
3503 			n->right->left = new1(ONUL, Z, Z);
3504 			rew(n, 0);
3505 			break;
3506 	}
3507 	if(blk)
3508 		popscope();
3509 }
3510 
3511 void
3512 codgen2(Node *n, Node *nn, int lastlno, int rw)
3513 {
3514 	Node *ln = Z;
3515 
3516 	newsec(0);
3517 	output(nn->lineno, 1);
3518 	tmp = 0;
3519 	/* t = types[TVOID]; */
3520 	nn = func(nn);
3521 	pushscope(nn, SPARM);
3522 	if(rw)
3523 		rew(n, 1);
3524 	egen(nn, ONOOP, PRE);
3525 	newline();
3526 	prdelim("{");
3527 	newline();
3528 	incind();
3529 	/* rewf(n); */
3530 	pushscope(n, SAUTO);
3531 	sgen(n, 0, &ln);
3532 	if(ln != Z && isdec(ln))
3533 		tdgen(ln, 0);
3534 	popscope();
3535 	popscope();
3536 	if(n != Z)
3537 		output(lline(n), 1);
3538 	output(lastlno, 1);
3539 	decind();
3540 	prdelim("}");
3541 	newline();
3542 	newline();
3543 	setmain(nn);
3544 }
3545 
3546 void
3547 rewall(Node *n, Node *nn, int lastlno)
3548 {
3549 	USED(lastlno);
3550 	tmp = 0;
3551 	nn = func(nn);
3552 	pushscope(nn, SPARM);
3553 	rew(n, 1);
3554 	popscope();
3555 	setmain(nn);
3556 }
3557 
3558 void
3559 suball(Node *n, Node *nn)
3560 {
3561 	Node *rn;
3562 
3563 	nn = func(nn);
3564 	pushscope(nn, SPARM);
3565 	subs(nn, 0, 0);
3566 	subs(n, 1, 1);
3567 	nn = lastn(n);
3568 	if(nn != Z && nn->op != ORETURN){
3569 		rn = retval(Z);
3570 		if(rn != Z){
3571 			addnode(OLIST, nn);
3572 			nn->right = rn;
3573 		}
3574 	}
3575 	popscope();
3576 }
3577 
3578 void
3579 ginit(void)
3580 {
3581 	thechar = 'o';
3582 	thestring = "386";
3583 	tfield = types[TLONG];
3584 }
3585 
3586 long
3587 align(long i, Type *t, int op)
3588 {
3589 	long o;
3590 	Type *v;
3591 	int w;
3592 
3593 	o = i;
3594 	w = 1;
3595 	switch(op) {
3596 	default:
3597 		diag(Z, "unknown align opcode %d", op);
3598 		break;
3599 
3600 	case Asu2:	/* padding at end of a struct */
3601 		w = SZ_LONG;
3602 		break;
3603 
3604 	case Ael1:	/* initial allign of struct element */
3605 		for(v=t; v->etype==TARRAY; v=v->link)
3606 			;
3607 		w = ewidth[v->etype];
3608 		if(w <= 0 || w >= SZ_LONG)
3609 			w = SZ_LONG;
3610 		break;
3611 
3612 	case Ael2:	/* width of a struct element */
3613 		o += t->width;
3614 		break;
3615 
3616 	case Aarg0:	/* initial passbyptr argument in arg list */
3617 		if(typesuv[t->etype]) {
3618 			o = align(o, types[TIND], Aarg1);
3619 			o = align(o, types[TIND], Aarg2);
3620 		}
3621 		break;
3622 
3623 	case Aarg1:	/* initial allign of parameter */
3624 		w = ewidth[t->etype];
3625 		if(w <= 0 || w >= SZ_LONG) {
3626 			w = SZ_LONG;
3627 			break;
3628 		}
3629 		w = 1;		/* little endian no adjustment */
3630 		break;
3631 
3632 	case Aarg2:	/* width of a parameter */
3633 		o += t->width;
3634 		w = SZ_LONG;
3635 		break;
3636 
3637 	case Aaut3:	/* total allign of automatic */
3638 		o = align(o, t, Ael2);
3639 		o = align(o, t, Ael1);
3640 		w = SZ_LONG;	/* because of a pun in cc/dcl.c:contig() */
3641 		break;
3642 	}
3643 	o = round(o, w);
3644 	if(0)
3645 		print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
3646 	return o;
3647 }
3648 
3649 long
3650 maxround(long max, long v)
3651 {
3652 	v = round(v, SZ_LONG);
3653 	if(v > max)
3654 		return v;
3655 	return max;
3656 }
3657 
3658 static int
3659 nlen(Node *n)
3660 {
3661 	if(n == Z)
3662 		return 0;
3663 	if(n->op == OLIST)
3664 		return nlen(n->left)+nlen(n->right);
3665 	return 1;
3666 }
3667 
3668 static void
3669 flatten(Node *n, Node **a, int *i)
3670 {
3671 	if(n == Z)
3672 		return;
3673 	if(n->op == OLIST){
3674 		flatten(n->left, a, i);
3675 		flatten(n->right, a, i);
3676 		free(n);
3677 		return;
3678 	}
3679 	a[(*i)++] = n;
3680 }
3681 
3682 static Node*
3683 addcase(Node *n, Node **e, Node **s, int k)
3684 {
3685 	Node *nn;
3686 
3687 	if(*e != Z){
3688 		nn = new1(OCASE, *e, *s);
3689 		nn->right->blk = 0;
3690 		nn->kind = k;
3691 	}
3692 	else
3693 		nn = *s;
3694 	*e = *s = Z;
3695 	if(n == Z)
3696 		return nn;
3697 	return new1(OLIST, n, nn);
3698 }
3699 
3700 /* collect case code together */
3701 static Node*
3702 buildcases(Node *n)
3703 {
3704 	int i, m, m0, c;
3705 	Node *e, *s, *nn, **a, **ep;
3706 
3707 	m = nlen(n);
3708 	a = (Node **)malloc(m*sizeof(Node*));
3709 	m0 = 0;
3710 	flatten(n, a, &m0);
3711 	if(m != m0)
3712 		diag(Z, "internal: bad buildcases()");
3713 	c = 1;
3714 	e = s = nn = Z;
3715 	ep = &e;
3716 	for(i = 0; i < m; i++){
3717 		n = a[i];
3718 		if(n->op == OCASE){
3719 			if(!c){
3720 				nn = addcase(nn, &e, &s, KNIL);
3721 				ep = &e;
3722 			}
3723 			*ep = new1(OLIST, n->left, Z);
3724 			if(n->left == Z)
3725 				(*ep)->lineno = n->lineno;
3726 			ep = &(*ep)->right;
3727 			c = 1;
3728 		}
3729 		else{
3730 			if(s == Z)
3731 				s = n;
3732 			else
3733 				s = new1(OLIST, s, n);
3734 			c = 0;
3735 		}
3736 	}
3737 	nn = addcase(nn, &e, &s, KLAST);
3738 	free(a);
3739 	return nn;
3740 }
3741 
3742 static Sym *
3743 tmpgen(Type *t)
3744 {
3745 	Sym *s;
3746 
3747 	sprint(buf, "tmp_%d", ++tmp);
3748 	s = slookup(buf);
3749 	s->type = t;
3750 	s->class = CAUTO;
3751 	if(t->etype == TENUM)
3752 		s->type = types[TINT];
3753 	return s;
3754 }
3755 
3756 static Node*
3757 cfind(Node *n)
3758 {
3759 	Node *nn;
3760 
3761 	if(n == Z)
3762 		return Z;
3763 	if(n->op == OCOND)
3764 		return n;
3765 	nn = cfind(n->left);
3766 	if(nn != Z)
3767 		return nn;
3768 	return cfind(n->right);
3769 }
3770 
3771 Node*
3772 ncopy(Node *n)
3773 {
3774 	Node *nn;
3775 
3776 	if(n == Z)
3777 		return Z;
3778 	nn = new1(n->op, Z, Z);
3779 	*nn = *n;
3780 	nn->left = ncopy(n->left);
3781 	nn->right = ncopy(n->right);
3782 	return nn;
3783 }
3784 
3785 static int
3786 complexity(Node *n, int *cond)
3787 {
3788 	int c;
3789 
3790 	if(n == Z)
3791 		return 0;
3792 	c = complexity(n->left, cond)+1+complexity(n->right, cond);
3793 	if(n->op == OCOND)
3794 		(*cond)++;
3795 	return c;
3796 }
3797 
3798 static int
3799 simple(Node *n)
3800 {
3801 	int c;
3802 
3803 	c = 0;
3804 	return complexity(n, &c) < COMPLEX && c <= 1;
3805 }
3806 
3807 static Type*
3808 intype(Node *n)
3809 {
3810 	Type *t;
3811 
3812 	t = ntype(n);
3813 	if(t == T)
3814 		return T;
3815 	return t->link;
3816 }
3817 
3818 static Type*
3819 ntype(Node *n)
3820 {
3821 	Type *t;
3822 
3823 	if(n == Z)
3824 		return T;
3825 	t = n->type;
3826 	if(t != T){
3827 		if(t->etype == TENUM)
3828 			return n->sym->tenum;
3829 		return t;
3830 	}
3831 	switch(n->op){
3832 		case OEQ:
3833 		case ONE:
3834 		case OLT:
3835 		case OGE:
3836 		case OGT:
3837 		case OLE:
3838 		case ONOT:
3839 		case OANDAND:
3840 		case OOROR:
3841 		case OIOTA:
3842 			return types[TINT];
3843 		case OCOMMA:
3844 			return ntype(n->right);
3845 		case OCOND:
3846 			return maxtype(ntype(n->right->left), ntype(n->right->right));
3847 		case OFUNC:
3848 			return intype(n->left);
3849 		case ODOT:
3850 			tcomd(n, ntype(n->left));
3851 			t = n->type;
3852 			n->type = T;
3853 			return t;
3854 		case ODOTIND:
3855 			tcomd(n, intype(n->left));
3856 			t = n->type;
3857 			n->type = T;
3858 			return t;
3859 		case OARRIND:
3860 			return intype(n->left);
3861 		case OADDR:
3862 			return typ1(TIND, ntype(n->left));
3863 		case OIND:
3864 			return intype(n->left);
3865 		case OSTRUCT:
3866 			return T;
3867 	}
3868 	return maxtype(ntype(n->left), ntype(n->right));
3869 }
3870 
3871 static Type*
3872 gettype(Node *n1, Node *n2)
3873 {
3874 	Type *t;
3875 
3876 	t = maxtype(n1->type, n2->type);
3877 	if(t != T)
3878 		return t;
3879 	return maxtype(ntype(n1), ntype(n2));
3880 }
3881 
3882 static void
3883 cgen0(Node *n, Node *e)
3884 {
3885 	Node *c, *nn, *ed, *ee;
3886 
3887 	if(n == e){
3888 		n->op = OIF;
3889 		return;
3890 	}
3891 	c = n->left;
3892 	ed = new1(OXXX, Z, Z);
3893 	*ed = *e;
3894 	ee = ncopy(e);
3895 	nn = cfind(ee);
3896 	*n = *n->right->left;
3897 	*nn = *nn->right->right;
3898 	e->op = OIF;
3899 	e->left = c;
3900 	e->right = new1(OLIST, ed, ee);
3901 }
3902 
3903 static Node*
3904 cgen(Node *n, Node *e)
3905 {
3906 	Type *t;
3907 	Node *tn, *i;
3908 
3909 	USED(e);
3910 	tn = new1(ONAME, Z, Z);
3911 	t = gettype(n->right->left, n->right->right);
3912 	tn->sym = tmpgen(t);
3913 	tn->type = tn->sym->type;
3914 /*
3915 	if(n == e){
3916 		n->op = OIF;
3917 		n->right->left = new1(OASD, tn, n->right->left);
3918 		n->right->right = new1(OAS, tn, n->right->right);
3919 		return n;
3920 	}
3921 */
3922 	i = new1(OIF, n->left, new1(OLIST, new1(OASD, tn, n->right->left), new1(OAS, tn, n->right->right)));
3923 	*n = *tn;
3924 	return i;
3925 }
3926 
3927 static struct{
3928 	char *name;
3929 	int	args;
3930 	int	fd;
3931 	char *lname;
3932 } sysops[] = {
3933 	"create",	1,	RET,	nil,
3934 	"dirstat",	1,	0,	"stat",
3935 	"dirfstat",	0,	1,	"fstat",
3936 	"dirwstat",	1,	0,	"wstat",
3937 	"dirfwstat",	0,	1,	"fwstat",
3938 	"dirread",	0,	1,	nil,
3939 	"dup",	0,	0,	nil,
3940 	"fprint",	2|STAR,	1,	nil,
3941 	"fprintf",	2|STAR,	1,	"fprint",
3942 	"open",	1,	RET,	nil,
3943 	"print",	1|STAR,	0,	nil,
3944 	"printf",	1|STAR,	0,	"print",
3945 	"read",	0,	1,	nil,
3946 	"remove",	1,	0,	nil,
3947 	"seek",	0,	1,	nil,
3948 	"sleep",	0,	0,	nil,
3949 	"sprint",	1|STAR,	0,	nil,
3950 	"sprintf",	1|STAR,	0,	"sprint",
3951 	"write",	0,	1,	nil,
3952 	0
3953 };
3954 
3955 /* dummy entry for module */
3956 #define BIOTMP	"__bio__"
3957 
3958 static struct{
3959 	char	*name;
3960 	char	*lname;
3961 } bioops[] = {
3962 	"Bflush",	"flush",
3963 	"Bgetc",	"getc",
3964 	"Bprint",	"puts",
3965 	"Bputc",	"putc",
3966 	"Bread",	"read",
3967 	"Bseek",	"seek",
3968 	"Bungetc",	"ungetc",
3969 	"Bwrite",	"write",
3970 	BIOTMP,	nil,
3971 	0
3972 };
3973 
3974 char *libcops[] = {
3975 	"isalnum",
3976 	"isalpha",
3977 	"isascii",
3978 	"iscntrl",
3979 	"isdigit",
3980 	"isgraph",
3981 	"islower",
3982 	"isprint",
3983 	"ispunct",
3984 	"isspace",
3985 	"isupper",
3986 	"isxdigit",
3987 	"strchr",
3988 	"strrchr",
3989 	"toascii",
3990 	"tolower",
3991 	"toupper",
3992 	"abs",
3993 	"min",
3994 	"max",
3995 	0,
3996 };
3997 
3998 static struct{
3999 	char *name;
4000 	int	type;
4001 	int	string;
4002 } xops[] = {
4003 	"strlen",	LSTRLEN,	1,
4004 	"strcmp",	LSTRCMP,	1,
4005 	"strcpy",	LSTRCPY,	1,
4006 	"strcat",	LSTRCAT,	1,
4007 	"strncmp",	LSTRNCMP,	1,
4008 	"strncpy",	LSTRNCPY,	1,
4009 	"strncat",	LSTRNCAT,	1,
4010 	"strdup",	LSTRDUP,	1,
4011 	"memcpy",	LMEMMOVE,	0,
4012 	"memmove",	LMEMMOVE,	0,
4013 	"malloc",	LMALLOC,	0,
4014 	"free",	LFREE,	0,
4015 	"exit",	LEXIT,	0,
4016 	"exits",	LEXIT,	0,
4017 	"close",	LCLOSE,	0,
4018 	"atoi",	LATOI,	0,
4019 	"atol",	LATOI,	0,
4020 	"atoll",	LATOL,	0,
4021 	"atof",	LATOF,	0,
4022 	"atod",	LATOF,	0,
4023 	"print",	LPRINT,	0,
4024 	"printf",	LPRINT,	0,
4025 	"fprint",	LFPRINT,	0,
4026 	"fprintf",	LFPRINT,	0,
4027 	"sprint",	LSPRINT,	0,
4028 	"sprintf",	LSPRINT,	0,
4029 	0
4030 };
4031 
4032 char *mathsops[] = {
4033 	"sin",
4034 	"cos",
4035 	"tan",
4036 	"sinh",
4037 	"cosh",
4038 	"tanh",
4039 	"asin",
4040 	"acos",
4041 	"atan",
4042 	"asinh",
4043 	"acosh",
4044 	"atanh",
4045 	"atan2",
4046 	"sqrt",
4047 	"cbrt",
4048 	"pow",
4049 	"pow10",
4050 	"exp",
4051 	"log",
4052 	"log10",
4053 	0
4054 };
4055 
4056 Node *glob, *globe;
4057 
4058 void
4059 sysinit(void)
4060 {
4061 	int i;
4062 	Sym *s;
4063 
4064 	glob = globe = new1(ONOOP, Z, Z);
4065 	for(i = 0; sysops[i].name; i++){
4066 		s = slookup(sysops[i].name);
4067 		s->class = CEXTERN;
4068 		s->args = sysops[i].args;
4069 		s->fd = sysops[i].fd;
4070 		s->mod = "sys";
4071 		s->lname = sysops[i].lname;
4072 		s->limbo = 1;
4073 		sysop = s;
4074 	}
4075 	for(i = 0; bioops[i].name; i++){
4076 		s = slookup(bioops[i].name);
4077 		s->class = CEXTERN;
4078 		if(strcmp(bioops[i].name, BIOTMP) == 0){
4079 			s->mod = "bufio";
4080 			bioop = s;
4081 		}
4082 		s->lname = bioops[i].lname;
4083 		s->kind = LSELF;
4084 		s->limbo = 1;
4085 	}
4086 	for(i = 0; mathsops[i]; i++){
4087 		s = slookup(mathsops[i]);
4088 		s->class = CEXTERN;
4089 		s->mod = "math";
4090 		s->limbo = 1;
4091 	}
4092 	for(i = 0; libcops[i]; i++){
4093 		s = slookup(libcops[i]);
4094 		s->class = CEXTERN;
4095 		s->mod = strings ? "libc" : "libc0";
4096 		s->limbo = 1;
4097 		libcop = s;
4098 	}
4099 	for(i = 0; xops[i].name; i++){
4100 		s = slookup(xops[i].name);
4101 		s->class = CEXTERN;
4102 		if(strings || !xops[i].string)
4103 			s->kind = xops[i].type;
4104 		else
4105 			s->mod = "libc0";
4106 		if(s->kind == LEXIT)
4107 			s->lname = "exit";
4108 		s->limbo = 1;
4109 	}
4110 	usemod(sysop, 1);
4111 	if(!strings)
4112 		usemod(libcop, 1);
4113 }
4114 
4115 void
4116 clbegin(void)
4117 {
4118 	pushscope(glob, SGLOB);
4119 }
4120 
4121 void
4122 clend(void)
4123 {
4124 	if(passes)
4125 		swalk();
4126 	popscope();
4127 }
4128 
4129 static Modl *mods;
4130 
4131 void
4132 usemod(Sym *s, int ld)
4133 {
4134 	Modl *ml;
4135 
4136 	for(ml = mods; ml != nil; ml = ml->nxt)
4137 		if(strcmp(ml->mod, s->mod) == 0){
4138 			ml->ld |= ld;
4139 			return;
4140 		}
4141 	ml = (Modl *)malloc(sizeof(Modl));
4142 	ml->mod = s->mod;
4143 	ml->ld = ld;
4144 	ml->nxt = mods;
4145 	mods = ml;
4146 }
4147 
4148 static void
4149 ginc(Modl *ml)
4150 {
4151 	int c;
4152 	char *s;
4153 
4154 	if(ml == nil)
4155 		return;
4156 	if(ml->nxt != nil)
4157 		ginc(ml->nxt);
4158 	s = ml->mod;
4159 	c = toupper(s[0]);
4160 	sprint(buf, "include \"%s.m\";", s);
4161 	prline(buf);
4162 	if(ml->ld){
4163 		sprint(buf, "	%s: %c%s;", s, c, s+1);
4164 		prline(buf);
4165 	}
4166 }
4167 
4168 static void
4169 gload(Modl *ml)
4170 {
4171 	int c;
4172 	char *s;
4173 
4174 	if(ml == nil)
4175 		return;
4176 	if(ml->nxt != nil)
4177 		gload(ml->nxt);
4178 	if(ml->ld){
4179 		s = ml->mod;
4180 		c = toupper(s[0]);
4181 		sprint(buf, "	%s = load %c%s %c%s->PATH;", s, c, s+1, c, s+1);
4182 		prline(buf);
4183 	}
4184 }
4185 
4186 static void
4187 callmain(void)
4188 {
4189 	if(inmain){
4190 		if(strings)
4191 			prline("	main(len argl, argl);");
4192 		else
4193 			prline("	main(len argl, libc0->ls2aab(argl));");
4194 	}
4195 }
4196 
4197 static void
4198 genstart(void)
4199 {
4200 	char *s;
4201 
4202 	if(!strings && inmain)
4203 		usemod(libcop, 1);
4204 	ginc(mods);
4205 	s = hasm();
4206 	if(s){
4207 		sprint(buf, "include \"%s\";", s);
4208 		prline(buf);
4209 	}
4210 	prline("");
4211 	prline("init(nil: ref Draw->Context, argl: list of string)");
4212 	prline("{");
4213 	gload(mods);
4214 	callmain();
4215 	prline("}");
4216 	prline("");
4217 }
4218 
4219 static int
4220 argpos0(Node *nn, Node *n, int *p)
4221 {
4222 	int pp;
4223 
4224 	if(n == Z)
4225 		return -1;
4226 	if(n->op == OLIST){
4227 		pp = argpos0(nn, n->left, p);
4228 		if(pp >= 0)
4229 			return pp;
4230 		return argpos0(nn, n->right, p);
4231 	}
4232 	if(n == nn)
4233 		return *p;
4234 	(*p)++;
4235 	return -1;
4236 }
4237 
4238 static int
4239 argpos(Node *nn, Node *n)
4240 {
4241 	int p = 0;
4242 
4243 	p = argpos0(nn, n, &p);
4244 	if(p < 0)
4245 		diag(Z, "-ve argpos");
4246 	return p;
4247 }
4248 
4249 static Node*
4250 arg0(Node *n, int a, int *i)
4251 {
4252 	Node *nn;
4253 
4254 	if(n == Z)
4255 		return Z;
4256 	if(n->op == OLIST){
4257 		nn = arg0(n->left, a, i);
4258 		if(nn != Z)
4259 			return nn;
4260 		return arg0(n->right, a, i);
4261 	}
4262 	if(a == (*i)++)
4263 		return n;
4264 	return Z;
4265 }
4266 
4267 static Node*
4268 arg(Node *n, int a)
4269 {
4270 	int i = 0;
4271 
4272 	return arg0(n, a, &i);
4273 }
4274 
4275 static Node*
4276 list(Node *l, Node *r)
4277 {
4278 	if(r == Z)
4279 		return l;
4280 	if(l == Z)
4281 		return r;
4282 	return new1(OLIST, l, r);
4283 }
4284 
4285 static Node*
4286 droparg(Node *n, int a, int *i)
4287 {
4288 	if(n == Z)
4289 		return Z;
4290 	if(n->op == OLIST)
4291 		return list(droparg(n->left, a, i), droparg(n->right, a, i));
4292 	if(a == (*i)++)
4293 		return Z;
4294 	return n;
4295 }
4296 
4297 static void
4298 sargs(Node *n)
4299 {
4300 	int s, f, i, j;
4301 	Node *a;
4302 
4303 	if(strings || (f = n->left->sym->args) == 0)
4304 		return;
4305 	s = 0;
4306 	for(i = 1, j = 0; i < STAR || s; i *= 2, j++){
4307 		if(f&i || s){
4308 			a = arg(n->right, j);
4309 			if(a == Z)
4310 				break;
4311 			if(s && !isstr(a->type))
4312 				continue;
4313 			if(f&STAR)
4314 				s++;
4315 			if(a->op == OS2AB){
4316 				*a = *a->left;
4317 				continue;
4318 			}
4319 			addnode(OAB2S, a);
4320 		}
4321 	}
4322 }
4323 
4324 static void
4325 fdargs(Node *n)
4326 {
4327 	int f, i, j;
4328 	Node *a;
4329 
4330 	if((f = n->left->sym->fd) == 0)
4331 		return;
4332 	marktype(pfdtype, TCFD);
4333 	if(f&RET)
4334 		tcon(n, pfdtype);
4335 	for(i = 1, j = 0; i < RET; i *= 2, j++){
4336 		if(f&i){
4337 			a = arg(n->right, j);
4338 			if(a == Z)
4339 				break;
4340 			tcon(a, pfdtype);
4341 		}
4342 	}
4343 }
4344 
4345 static void
4346 aargs(Node *n)
4347 {
4348 	int i;
4349 	Node *a, *nn, *fn;
4350 	Type *t, *t0, *ft, *at, *st;
4351 
4352 	if(!doaddr)
4353 		return;
4354 	if(n->op != OFUNC || n->left->op != ONAME)
4355 		return;
4356 	/* ft = n->left->type; */
4357 	ft = n->left->sym->type;
4358 	t = t0 = ft->link;
4359 	nn = Z;
4360 	for(i = 0; ; i++){
4361 		a = arg(n->right, i);
4362 		if(a == Z)
4363 			break;
4364 		at = typn(ft, i);
4365 		if(at != T && at->etype != TDOT && (a->op == OADDR || iteq(a->type, at) || iteq(at, a->type))){
4366 			if(iteq(at, a->type))
4367 				st = at->link;
4368 			else
4369 				st = a->type->link;
4370 			if(doalladdr || isscalar(st)){
4371 				if(a->op == OADDR)
4372 					*a = *a->left;
4373 				else if(iteq(a->type, at))
4374 					a->type = at;
4375 				if(t->mark == 0){
4376 					t = tuple(t, a->type);
4377 					trep(at, at->link);
4378 					fn = finddec(n->left->sym, 1);
4379 					if(fn != Z && fn->op == OFUNC)
4380 						tind(arg(fn->right, i));
4381 				}
4382 				if(nn == Z)
4383 					nn = cknil(ncopy(a));
4384 				else{
4385 					nn = new1(OTUPLE, nn, cknil(ncopy(a)));
4386 					nn->type = t;
4387 				}
4388 			}
4389 		}
4390 	}
4391 	if(nn != Z){
4392 		if(isvoid(t0) || t->mark == TCPC)
4393 			marktype(t, TCPC);
4394 		else
4395 			marktype(t, TCFC);
4396 		tcon(n, t);
4397 		addnode(ORETV, n);
4398 		n->right = nn;
4399 	}
4400 }
4401 
4402 static void
4403 args(Node *n)
4404 {
4405 	if(n->op != OFUNC || n->left->op != ONAME)
4406 		return;
4407 	sargs(n);
4408 	if(passes){
4409 		fdargs(n);
4410 		aargs(n);
4411 	}
4412 }
4413 
4414 static Node*
4415 indir(Node *n)
4416 {
4417 	if(n->op == OADDR)
4418 		return n->left;
4419 	return new1(OIND, n, Z);
4420 }
4421 
4422 static void
4423 rewlc(Node *n, int k, Type *t)
4424 {
4425 	int i;
4426 	Type *tt;
4427 	Node *a0, *a1, *a2, *nn;
4428 
4429 	if(t == T)
4430 		t = n->type;
4431 	a0 = arg(n->right, 0);
4432 	a1 = arg(n->right, 1);
4433 	switch(k){
4434 		case LSTRLEN:
4435 			n->op = OLEN;
4436 			break;
4437 		case LSTRCMP:
4438 			n->op = ONE;
4439 			n->left = a0;
4440 			n->right = a1;
4441 			break;
4442 		case LSTRCPY:
4443 			n->op = OAS;
4444 			n->left = a0;
4445 			n->right = a1;
4446 			n->type = n->left->type;
4447 			break;
4448 		case LSTRCAT:
4449 			n->op = OASADD;
4450 			n->left = a0;
4451 			n->right = a1;
4452 			n->type = n->left->type;
4453 			break;
4454 		case LSTRDUP:
4455 			*n = *a0;
4456 			break;
4457 		case LMEMMOVE:
4458 			if(!teq(a0->type, a1->type))
4459 				break;
4460 			if(a0->type->etype == TIND){
4461 				tt = a0->type->link;
4462 				a2 = arg(n->right, 2);
4463 				if(isadt(tt) && isconst(a2, tt->width)){
4464 					n->op = OAS;
4465 					n->left = indir(a0);
4466 					n->right = indir(a1);
4467 					n->type = n->left->type = n->right->type = tt;
4468 					break;
4469 				}
4470 				if(mydiv(a2, tt->width) != Z){
4471 					n->op = OAS;
4472 					n->left = new1(OSLICE, a0, new1(OLIST, con(0), Z));
4473 					n->right = new1(OSLICE, a1, new1(OLIST, con(0), a2));
4474 					n->type = n->left->type = n->right->type = a0->type;
4475 				}
4476 			}
4477 			break;
4478 		case LMALLOC:
4479 			if(t->etype == TIND){
4480 				tt = t->link;
4481 				if(isadt(tt) && isconst(a0, tt->width)){
4482 					n->op = OREF;
4483 					n->left = Z;
4484 					n->right = Z;
4485 					n->type = t;
4486 					break;
4487 				}
4488 				if(mydiv(a0, tt->width) != Z){
4489 					n->op = OARRAYOF;
4490 					n->left = a0;
4491 					n->right = Z;
4492 					n->type = t;
4493 					if(isadt(tt)){
4494 						n->type = typ1(TARRAY, tt);
4495 						n->type->width = LARR;	/* limbo array without bounds */
4496 						marktype(n->type, TCAR);
4497 					}
4498 				}
4499 			}
4500 			break;
4501 		case LFREE:
4502 			n->op = OAS;
4503 			n->left = a0;
4504 			n->right = con(0);
4505 			n->type = n->left->type;
4506 			n->right->type = n->type;
4507 			break;
4508 		case LEXIT:
4509 			i = n->kind;
4510 			*n = *n->left;
4511 			n->kind = i;
4512 			break;
4513 		case LCLOSE:
4514 			n->op = OAS;
4515 			n->left = a0;
4516 			n->right = con(0);
4517 			n->left->type = typ1(TIND, n->left->type);
4518 			n->type = n->left->type;
4519 			n->right->type = n->type;
4520 			break;
4521 		case LATOI:
4522 			if(!strings)
4523 				strcast(a0);
4524 			n->op = OCAST;
4525 			n->left = a0;
4526 			n->right = Z;
4527 			n->type = types[TINT];
4528 			break;
4529 		case LATOL:
4530 			if(!strings)
4531 				strcast(a0);
4532 			n->op = OCAST;
4533 			n->left = a0;
4534 			n->right = Z;
4535 			n->type = types[TVLONG];
4536 			break;
4537 		case LATOF:
4538 			if(!strings)
4539 				strcast(a0);
4540 			n->op = OCAST;
4541 			n->left = a0;
4542 			n->right = Z;
4543 			n->type = types[TDOUBLE];
4544 			break;
4545 		case LPRINT:
4546 			if(a0->op == OSTRING)
4547 				pfmt(a0->cstring);
4548 			else if(a0->op == OLSTRING)
4549 				lpfmt(a0->rstring);
4550 			break;
4551 		case LFPRINT:
4552 			if(a1->op == OSTRING)
4553 				pfmt(a1->cstring);
4554 			else if(a1->op == OLSTRING)
4555 				lpfmt(a1->rstring);
4556 			break;
4557 		case LSPRINT:
4558 			if(n->right->kind != KDROP){
4559 				if(a1->op == OSTRING)
4560 					pfmt(a1->cstring);
4561 				else if(a1->op == OLSTRING)
4562 					lpfmt(a1->rstring);
4563 				nn = new1(OXXX, Z, Z);
4564 				*nn = *n;
4565 				i = 0;
4566 				nn->right = droparg(nn->right, 0, &i);
4567 				nn->right->kind = KDROP;
4568 				n->op = OAS;
4569 				n->left = a0;
4570 				n->right = nn;
4571 				n->type = nn->type;
4572 			}
4573 			break;
4574 		case LSELF:
4575 			if(n->right != Z && n->right->kind != KDROP){
4576 				i = 0;
4577 				n->right = droparg(n->right, 0, &i);
4578 				if(n->right != Z)
4579 					n->right->kind = KDROP;
4580 				addnode(OLDOT, n->left);
4581 				n->left->right = n->left->left;
4582 				n->left->left = a0;
4583 				usemod(bioop, 1);
4584 			}
4585 			break;
4586 	}
4587 }
4588 
4589 void
4590 expgen(Node *n)
4591 {
4592 	egen(n, ONOOP, PRE);
4593 }
4594 
4595 static void
4596 clrbrk(Node *n)
4597 {
4598 	if(n == Z)
4599 		return;
4600 	switch(n->op){
4601 		case OLIST:
4602 			clrbrk(n->right);
4603 			break;
4604 		case OBREAK:
4605 			n->op = OSBREAK;
4606 			n->left = n->right = Z;
4607 			break;
4608 	}
4609 }
4610 
4611 static int
4612 hasbrk(Node *n)
4613 {
4614 	if(n == Z)
4615 		return 0;
4616 	switch(n->op){
4617 		case OLIST:
4618 		case OWHILE:
4619 		case ODWHILE:
4620 		case OFOR:
4621 			return hasbrk(n->right);
4622 		case OIF:
4623 			if(n->right->right == Z)
4624 				return 0;
4625 			return hasbrk(n->right->left) && hasbrk(n->right->right);
4626 		case ORETURN:
4627 		case OGOTO:
4628 		case OCONTINUE:
4629 		case OBREAK:
4630 		case OSBREAK:
4631 			return 1;
4632 		default:
4633 			return 0;
4634 	}
4635 }
4636 
4637 static int
4638 isgen(char *s)
4639 {
4640 	char *s1, *s2;
4641 
4642 	s1 = strchr(s, '_');
4643 	s2 = strrchr(s, '_');
4644 	if(s1 == nil || s2-s1 != 4)
4645 		return 0;
4646 	return s1[1] == 'a' && s1[2] == 'd' && s1[3] == 't';
4647 }
4648 
4649 static void
4650 addmodn(Sym *s)
4651 {
4652 	char buf[128], *ns;
4653 
4654 	if(s->name[0] == '_'){
4655 		outmod(buf, -1);
4656 		ns = malloc(strlen(buf)+strlen(s->name)+1);
4657 		strcpy(ns, buf);
4658 		strcat(ns, s->name);
4659 		s->name = ns;
4660 	}
4661 }
4662 
4663 static void
4664 pfmt(char *s)
4665 {
4666 	char *t = s;
4667 
4668 	while(*s != '\0'){
4669 		if(*s == '%'){
4670 			*t++ = *s++;
4671 			if(*s == 'l'){
4672 				s++;
4673 				if(*s == 'l')
4674 					*t++ = 'b';
4675 				else
4676 					*t++ = *s;
4677 				s++;
4678 			}
4679 			else if(*s == 'p'){
4680 				*t++ = 'x';
4681 				s++;
4682 			}
4683 			else
4684 				*t++ = *s++;
4685 		}
4686 		else
4687 			*t++ = *s++;
4688 	}
4689 	*t = '\0';
4690 }
4691 
4692 static void
4693 lpfmt(Rune *s)
4694 {
4695 	 Rune*t = s;
4696 
4697 	while(*s != '\0'){
4698 		if(*s == '%'){
4699 			*t++ = *s++;
4700 			if(*s == 'l'){
4701 				s++;
4702 				if(*s == 'l')
4703 					*t++ = 'b';
4704 				else
4705 					*t++ = *s;
4706 				s++;
4707 			}
4708 			else if(*s == 'p'){
4709 				*t++ = 'x';
4710 				s++;
4711 			}
4712 			else
4713 				*t++ = *s++;
4714 		}
4715 		else
4716 			*t++ = *s++;
4717 	}
4718 	*t = '\0';
4719 }
4720 
4721 int
4722 line(Node *n)
4723 {
4724 	if(n == Z)
4725 		return 0;
4726 	if(n->op == OLIST)
4727 		return line(n->left);
4728 	return n->lineno;
4729 }
4730 
4731 static int
4732 lline(Node *n)
4733 {
4734 	if(n == Z)
4735 		return 0;
4736 	if(n->op == OLIST)
4737 		return lline(n->right);
4738 	return n->lineno+1;
4739 }
4740 
4741 static Node*
4742 lastn(Node *n)
4743 {
4744 	while(n != Z && n->op == OLIST)
4745 		n = n->right;
4746 	return n;
4747 }
4748 
4749 static Node*
4750 newnode(int op, Node *l)
4751 {
4752 	Node *n;
4753 
4754 	n = new1(op, l, Z);
4755 	globe->right = n;
4756 	globe = n;
4757 	return n;
4758 }
4759 
4760 void
4761 codgen1(Node *n, Node *nn, int lastlno)
4762 {
4763 	Node *nnn;
4764 
4765 	scomplex(n);
4766 	nnn = newnode(OCODE, new1(OLIST, n, nn));
4767 	nnn->lineno = lastlno;
4768 	mset(n);
4769 	mset(nn);
4770 	nn = func(nn);
4771 	newnode(ODECF, nn);
4772 	setmain(nn);
4773 }
4774 
4775 void
4776 vtgen1(Node *n)
4777 {
4778 	int c;
4779 	Node *nn = n;
4780 
4781 	if(n->op == ODAS)
4782 		nn = n->left;
4783 	if(nn->type == T || nn->sym == S)
4784 		return;
4785 	c = nn->sym->class;
4786 	if(c == CGLOBL || c == CSTATIC || c == CLOCAL || c == CEXREG){
4787 		newnode(ODECV, n);
4788 		if(nn->type->etype != TFUNC || ism())
4789 			setmod(nn->sym);
4790 	}
4791 	mset(n);
4792 }
4793 
4794 void
4795 etgen1(Sym *s)
4796 {
4797 	Node *n;
4798 
4799 	n = newnode(ODECE, Z);
4800 	n->sym = s;
4801 	if(s != S)
4802 		setmod(s);
4803 }
4804 
4805 void
4806 ttgen1(Type *t)
4807 {
4808 	Node *n;
4809 
4810 	n = newnode(ODECT, Z);
4811 	n->type = t;
4812 	if(isadt(t))
4813 		setmod(suename(t));
4814 }
4815 
4816 void
4817 outpush1(char *s)
4818 {
4819 	Node *n;
4820 	char *t;
4821 
4822 	n = newnode(OPUSH, Z);
4823 	if(s == nil)
4824 		t = nil;
4825 	else{
4826 		t = malloc(strlen(s)+1);
4827 		strcpy(t, s);
4828 	}
4829 	n->cstring = t;
4830 	outpush0(s, n);
4831 }
4832 
4833 void
4834 outpop1(int lno)
4835 {
4836 	Node *n;
4837 
4838 	n = newnode(OPOP, Z);
4839 	n->lineno = lno;
4840 	outpop0(lno);
4841 }
4842 
4843 void
4844 codgen(Node *n, Node *nn, int lastlno)
4845 {
4846 	if(passes)
4847 		codgen1(n, nn, lastlno);
4848 	else
4849 		codgen2(n, nn, lastlno, 1);
4850 }
4851 
4852 void
4853 vtgen(Node *n)
4854 {
4855 	if(passes)
4856 		vtgen1(n);
4857 	else
4858 		vtgen2(n);
4859 }
4860 
4861 void
4862 etgen(Sym *s)
4863 {
4864 	if(passes)
4865 		etgen1(s);
4866 	else
4867 		etgen2(s);
4868 }
4869 
4870 void
4871 ttgen(Type *t)
4872 {
4873 	if(passes)
4874 		ttgen1(t);
4875 	else
4876 		ttgen2(t);
4877 }
4878 
4879 void
4880 outpush(char *s)
4881 {
4882 	if(passes)
4883 		outpush1(s);
4884 	else
4885 		outpush2(s, Z);
4886 }
4887 
4888 void
4889 outpop(int lno)
4890 {
4891 	if(passes)
4892 		outpop1(lno);
4893 	else
4894 		outpop2(lno);
4895 }
4896 
4897 static void
4898 swalk(void)
4899 {
4900 	Node *n, *l;
4901 
4902 	for(n = glob; n != Z; n = n->right){
4903 		l = n->left;
4904 		switch(n->op){
4905 			case OCODE:
4906 				rewall(l->left, l->right, n->lineno);
4907 				break;
4908 			default:
4909 				break;
4910 		}
4911 	}
4912 	while(again){
4913 		again = 0;
4914 		for(n = glob; n != Z; n = n->right){
4915 			l = n->left;
4916 			switch(n->op){
4917 				case OCODE:
4918 					suball(l->left, l->right);
4919 					break;
4920 				case ODECV:
4921 					subs(l, 0, 0);
4922 					break;
4923 				case ODECE:
4924 				case ODECT:
4925 				case ODECF:
4926 					break;
4927 				default:
4928 					break;
4929 			}
4930 		}
4931 	}
4932 	for(n = glob; n != Z; n = n->right){
4933 		l = n->left;
4934 		switch(n->op){
4935 			case ONOOP:
4936 				break;
4937 			case OPUSH:
4938 				outpush2(n->cstring, n);
4939 				break;
4940 			case OPOP:
4941 				outpop2(n->lineno);
4942 				break;
4943 			case OCODE:
4944 				codgen2(l->left, l->right, n->lineno, 0);
4945 				break;
4946 			case ODECV:
4947 				vtgen2(l);
4948 				break;
4949 			case ODECE:
4950 				etgen2(n->sym);
4951 				break;
4952 			case ODECT:
4953 				ttgen2(n->type);
4954 				break;
4955 			case ODECF:
4956 				break;
4957 		}
4958 	}
4959 }
4960 
4961 static void
4962 scomplex(Node *n)
4963 {
4964 	if(n == Z)
4965 		return;
4966 	switch(n->op){
4967 		default:
4968 			complex(n);
4969 			break;
4970 		case ODAS:
4971 		case OSBREAK:
4972 		case ONUL:
4973 		case OLABEL:
4974 		case OGOTO:
4975 		case OCONTINUE:
4976 		case OBREAK:
4977 			break;
4978 		case ONAME:
4979 			if(n->kind == KEXP)
4980 				complex(n);
4981 			break;
4982 		case OBLK:
4983 		case OSET:
4984 		case OUSED:
4985 			scomplex(n->left);
4986 			break;
4987 		case OLIST:
4988 			scomplex(n->left);
4989 			scomplex(n->right);
4990 			break;
4991 		case ORETURN:
4992 			complex(n);
4993 			break;
4994 		case OCASE:
4995 			complex(n->left);
4996 			break;
4997 		case OSWITCH:
4998 		case OWHILE:
4999 		case ODWHILE:
5000 			complex(n->left);
5001 			scomplex(n->right);
5002 			break;
5003 		case OFOR:
5004 			complex(n->left->left);
5005 			complex(n->left->right->left);
5006 			complex(n->left->right->right);
5007 			scomplex(n->right);
5008 			break;
5009 		case OIF:
5010 			complex(n->left);
5011 			scomplex(n->right->left);
5012 			scomplex(n->right->right);
5013 			break;
5014 	}
5015 }
5016 
5017 static void
5018 mtset(Type *t)
5019 {
5020 	if(t == T)
5021 		return;
5022 	switch(t->etype){
5023 		case TIND:
5024 		case TARRAY:
5025 			mtset(t->link);
5026 			break;
5027 		case TSTRUCT:
5028 		case TUNION:
5029 			prsym0(suename(t));
5030 			/*
5031 			for(l = t->link; l != T; l = l->down)
5032 				mtset(l);
5033 			*/
5034 			break;
5035 	}
5036 }
5037 
5038 static void
5039 mset(Node *n)
5040 {
5041 	if(n == Z)
5042 		return;
5043 	n->garb = 0;
5044 	if(n->op == ONAME)
5045 		prsym0(n->sym);
5046 	mtset(n->type);
5047 	mset(n->left);
5048 	mset(n->right);
5049 }
5050 
5051 static int
5052 sign(Node *n)
5053 {
5054 	int s;
5055 
5056 	if(n == Z)
5057 		return 1;
5058 	switch(n->op){
5059 		case OCONST:
5060 			sign(n->left);
5061 			if(n->vconst < 0){
5062 				n->vconst = -n->vconst;
5063 				return -1;
5064 			}
5065 			break;
5066 		case OPOS:
5067 			s = sign(n->left);
5068 			*n = *n->left;
5069 			return s;
5070 		case ONEG:
5071 			s = sign(n->left);
5072 			*n = *n->left;
5073 			return -s;
5074 		case OADD:
5075 			if(sign(n->right) < 0)
5076 				n->op = OSUB;
5077 			break;
5078 		case OSUB:
5079 			if(sign(n->right) < 0)
5080 				n->op = OADD;
5081 			break;
5082 		case OMUL:
5083 		case ODIV:
5084 			return sign(n->left)*sign(n->right);
5085 		default:
5086 			break;
5087 	}
5088 	return 1;
5089 }
5090 
5091 static Node*
5092 ckneg(Node *n)
5093 {
5094 	if(sign(n) < 0)
5095 		return new1(ONEG, n, Z);
5096 	return n;
5097 }
5098 
5099 static void
5100 sliceasgn(Node *n)
5101 {
5102 	Type *t;
5103 	Node *nn;
5104 
5105 	if(side(n->left) || (n->right != Z && side(n->right)))
5106 		return;
5107 	t = n->type;
5108 	if(isarray(t) && (!strings || t->link->etype != TCHAR)){
5109 		if(n->op == OASADD)
5110 			nn = n->right;
5111 		else
5112 			nn = con(1);
5113 		n->op = OAS;
5114 		n->right = new1(OSLICE, ncopy(n->left), new1(OLIST, nn, Z));
5115 	}
5116 }
5117