|
|
1.1 root 1: #include "alloc.h"
2: #include <libc.h>
3:
4: char *
5: emalloc(unsigned long n)
6: {
7: char *p;
8: p=malloc((unsigned)n);
9: if(p==0){
10: warn("out of memory; exiting");
11: exits("out of memory");
12: }
13: return p;
14: }
15: char *
16: erealloc(char *p, unsigned long n)
17: {
18: p=realloc(p, (unsigned)n);
19: if(p==0){
20: warn("out of memory; exiting");
21: exits("out of memory");
22: }
23: return p;
24: }
25: #include "alloc.h"
26: #include "word.h"
27: #include "store.h"
28: #include "comm.h"
29: #include <libc.h>
30:
31: /*
32: * Push constants
33: */
34:
35: ipushconst(Proc *proc)
36: {
37: *proc->sp++=(SWord)*++proc->pc;
38: return 1;
39: }
40:
41: ipush_2(Proc *proc)
42: {
43: *proc->sp++=-2;
44: return 1;
45: }
46:
47: ipush_1(Proc *proc)
48: {
49: *proc->sp++=-1;
50: return 1;
51: }
52:
53: ipush0(Proc *proc)
54: {
55: *proc->sp++=0;
56: return 1;
57: }
58:
59: ipush1(Proc *proc)
60: {
61: *proc->sp++=1;
62: return 1;
63: }
64:
65: ipush2(Proc *proc)
66: {
67: *proc->sp++=2;
68: return 1;
69: }
70:
71: ipush3(Proc *proc)
72: {
73: *proc->sp++=3;
74: return 1;
75: }
76:
77: ipush4(Proc *proc)
78: {
79: *proc->sp++=4;
80: return 1;
81: }
82:
83: ipush5(Proc *proc)
84: {
85: *proc->sp++=5;
86: return 1;
87: }
88:
89: ipush6(Proc *proc)
90: {
91: *proc->sp++=6;
92: return 1;
93: }
94:
95: ipush7(Proc *proc)
96: {
97: *proc->sp++=7;
98: return 1;
99: }
100:
101: ipush8(Proc *proc)
102: {
103: *proc->sp++=8;
104: return 1;
105: }
106:
107: ipush9(Proc *proc)
108: {
109: *proc->sp++=9;
110: return 1;
111: }
112:
113: ipush10(Proc *proc)
114: {
115: *proc->sp++=10;
116: return 1;
117: }
118:
119: /*
120: * Binary operators
121: */
122: ige(Proc *proc)
123: {
124: --proc->sp;
125: proc->sp[-1]=proc->sp[-1]>=proc->sp[0];
126: return 1;
127: }
128:
129: ile(Proc *proc)
130: {
131: --proc->sp;
132: proc->sp[-1]=proc->sp[-1]<=proc->sp[0];
133: return 1;
134: }
135:
136: ine(Proc *proc)
137: {
138: --proc->sp;
139: proc->sp[-1]=proc->sp[-1]!=proc->sp[0];
140: return 1;
141: }
142:
143: ieq(Proc *proc)
144: {
145: --proc->sp;
146: proc->sp[-1]=proc->sp[-1]==proc->sp[0];
147: return 1;
148: }
149:
150: igt(Proc *proc)
151: {
152: --proc->sp;
153: proc->sp[-1]=proc->sp[-1]>proc->sp[0];
154: return 1;
155: }
156:
157: ilt(Proc *proc)
158: {
159: --proc->sp;
160: proc->sp[-1]=proc->sp[-1]<proc->sp[0];
161: return 1;
162: }
163:
164: iadd(Proc *proc)
165: {
166: --proc->sp;
167: proc->sp[-1]+=proc->sp[0];
168: return 1;
169: }
170:
171: isub(Proc *proc)
172: {
173: --proc->sp;
174: proc->sp[-1]-=proc->sp[0];
175: return 1;
176: }
177:
178: imul(Proc *proc)
179: {
180: long l0, l1, l;
181: --proc->sp;
182: l0=proc->sp[-1];
183: l1=proc->sp[0];
184: l=l0*l1;
185: if(l1 && l/l1 != l0)
186: rerror("product overflow");
187: proc->sp[-1]=l;
188: return 1;
189: }
190:
191: idiv(Proc *proc)
192: {
193: --proc->sp;
194: if(proc->sp[0]==0)
195: rerror("zero divide");
196: proc->sp[-1]/=proc->sp[0];
197: return 1;
198: }
199:
200: imod(Proc *proc)
201: {
202: --proc->sp;
203: if(proc->sp[0]==0)
204: rerror("zero modulo");
205: proc->sp[-1]%=proc->sp[0];
206: return 1;
207: }
208:
209: iand(Proc *proc)
210: {
211: --proc->sp;
212: proc->sp[-1]&=proc->sp[0];
213: return 1;
214: }
215:
216: ior(Proc *proc)
217: {
218: --proc->sp;
219: proc->sp[-1]|=proc->sp[0];
220: return 1;
221: }
222:
223: ixor(Proc *proc)
224: {
225: --proc->sp;
226: proc->sp[-1]^=proc->sp[0];
227: return 1;
228: }
229:
230: ilsh(Proc *proc)
231: {
232: --proc->sp;
233: proc->sp[-1]<<=proc->sp[0];
234: return 1;
235: }
236:
237: irsh(Proc *proc)
238: {
239: --proc->sp;
240: proc->sp[-1]>>=proc->sp[0];
241: return 1;
242: }
243:
244: imax(Proc *proc)
245: {
246: SWord l;
247: l=*--proc->sp;
248: if(l>proc->sp[-1])
249: proc->sp[-1]=l;
250: return 1;
251: }
252:
253: /*
254: * Unary operators
255: */
256:
257: ineg(Proc *proc)
258: {
259: proc->sp[-1]=-proc->sp[-1];
260: return 1;
261: }
262:
263: inot(Proc *proc)
264: {
265: proc->sp[-1]=~proc->sp[-1];
266: return 1;
267: }
268:
269: ilnot(Proc *proc)
270: {
271: proc->sp[-1]=!proc->sp[-1];
272: return 1;
273: }
274:
275: iref(Proc *proc)
276: {
277: Store *s=(Store *)*--proc->sp;
278: *proc->sp++=s->ref-1;
279: decref(&s);
280: return 1;
281: }
282:
283: ilen(Proc *proc)
284: {
285: Store *s=(Store *)*--proc->sp;
286: *proc->sp++=s->len;
287: decref(&s);
288: return 1;
289: }
290:
291: /*
292: * String comparison: put value of strcmp() on stack
293: */
294:
295: istrcmp(Proc *proc)
296: {
297: int cmp;
298: Store *s1, *s2;
299: s1=(Store *)proc->sp[-2];
300: s2=(Store *)proc->sp[-1];
301: cmp=strcmp((char *)s1->data, (char *)s2->data);
302: decref(&s1);
303: decref(&s2);
304: proc->sp--;
305: proc->sp[-1]=cmp;
306: return 1;
307: }
308:
309: /*
310: * Print
311: */
312:
313: iprintint(Proc *proc)
314: {
315: pprint(proc, "%ld", *--proc->sp);
316: return 1;
317: }
318:
319: iprintnewline(Proc *proc)
320: {
321: pprint(proc, "\n");
322: return 1;
323: }
324:
325: iprintblank(Proc *proc)
326: {
327: pprint(proc, " ");
328: return 1;
329: }
330:
331: iprintunit(Proc *proc)
332: {
333: pprint(proc, "(unit)");
334: return 1;
335: }
336:
337: iprintchar(Proc *proc)
338: {
339: pprint(proc, "%c", *--proc->sp);
340: return 1;
341: }
342:
343: pprint(proc, fmt, a, b, c, d, e)
344: Proc *proc;
345: char *fmt;
346: {
347: char buf[1024];
348: long n;
349: n=sprint(buf, fmt, a, b, c, d, e);
350: if(proc->prbuf==0){
351: proc->prbuf=emalloc(64+n);
352: proc->maxprbuf=64+n;
353: proc->nprbuf=0;
354: }
355: if(n+proc->nprbuf+1>proc->maxprbuf){
356: proc->prbuf=erealloc(proc->prbuf, proc->maxprbuf+64+n);
357: proc->maxprbuf+=64+n;
358: }
359: strcpy(proc->prbuf+proc->nprbuf, buf);
360: proc->nprbuf+=n;
361: }
362: /*
363: * Stack management
364: */
365:
366: ipop(Proc *proc)
367: {
368: --proc->sp;
369: return 1;
370: }
371:
372: ipopptr(Proc *proc)
373: {
374: decref((Store **)(proc->sp-1));
375: --proc->sp;
376: return 1;
377: }
378:
379: idup(Proc *proc)
380: {
381: proc->sp++;
382: proc->sp[-1]=proc->sp[-2];
383: return 1;
384: }
385:
386: idupptr(Proc *proc)
387: {
388: proc->sp++;
389: proc->sp[-1]=proc->sp[-2];
390: ((Store *)(proc->sp[-1]))->ref++;
391: return 1;
392: }
393: #include "node.h"
394: #include "symbol.h"
395: #include "alloc.h"
396: #include "word.h"
397: #include "store.h"
398: #include "comm.h"
399: #include "inst.h"
400: #include <libc.h>
401:
402: #define FNS
403: #include "lib.h"
404: #undef FNS
405:
406: #define C 0x40000000
407: #define I 0x20000000
408: #define F 0x10000000
409: #define M(x) ((x)&~(C|I|F))
410:
411: long call0[]={ /* plain function, 0 arguments */
412: I+Ipushfp, C+0, F, I+Iret, C+0*WS, I+Idone, 0
413: };
414: long call1[]={ /* plain function, 1 argument */
415: I+Ipushfp, C+0, F, I+Iret, C+1*WS, I+Idone, 0
416: };
417: long call2[]={ /* plain function, 2 arguments */
418: I+Ipushfp, C+0, F, I+Iret, C+2*WS, I+Idone, 0
419: };
420: long call3[]={ /* plain function, 3 arguments */
421: I+Ipushfp, C+0, F, I+Iret, C+3*WS, I+Idone, 0
422: };
423: long call4[]={ /* plain function, 4 arguments */
424: I+Ipushfp, C+0, F, I+Iret, C+4*WS, I+Idone, 0
425: };
426: long call5[]={ /* plain function, 5 arguments */
427: I+Ipushfp, C+0, F, I+Iret, C+5*WS, I+Idone, 0
428: };
429: long call2_0[]={/* two-step function, 0 arguments */
430: I+Ipushfp, C+0, F+0, F+1, I+Iret, C+0*WS, I+Idone, 0
431: };
432:
433: struct{
434: char *name;
435: int (*fn[3])();
436: int nargs;
437: long *template;
438: }bltin[]={
439: #include "lib.h"
440: 0, {0, 0, 0}, 0, 0,
441: };
442:
443: bltinlookup(char *s)
444: {
445: int i;
446: for(i=0; bltin[i].name; i++)
447: if(strcmp(s, bltin[i].name)==0)
448: return i;
449: error("%s not a builtin", s);
450: return -1;
451: }
452:
453: long
454: bltinval(char *name, Node *t)
455: {
456: int i, nargs, len;
457: long *template, *p;
458: Store *s;
459: SWord *d;
460: if(t->o.t!=TProg)
461: error("builtin %s not a function", name);
462: i=bltinlookup(name);
463: nargs=bltin[i].nargs;
464: if(nargs!=length(t->l)) /* necessary but not sufficient */
465: error("wrong #args to builtin %s: %d (should be %d)", name, length(t->l), nargs);
466: template=bltin[i].template;
467: p=template;
468: for(len=0; *p; p++)
469: len++;
470: s=(Store *)emalloc(SHSZ+len*LWS);
471: s->ref=1;
472: s->type=Sprog;
473: s->sbits=0;
474: s->len=len;
475: d=s->data;
476: for(p=template; *p; p++)
477: if(*p&C)
478: *d++=(SWord)M(*p);
479: else if(*p&I)
480: *d++=(SWord)insttab[M(*p)].fp;
481: else if(*p&F)
482: *d++=(SWord)bltin[i].fn[M(*p)];
483: return (long)s;
484: }
485:
486: Store *
487: mk(type, len)
488: {
489: Store *s;
490: if(type==Sstruct)
491: len++;
492: s=(Store *)emalloc(SHSZ+len*LWS);
493: s->ref=1;
494: s->type=type;
495: if(type==Sstruct){
496: s->sbits=1;
497: s->data[0]=0;
498: }else
499: s->sbits=0;
500: s->len=len;
501: return s;
502: }
503: #include "node.h"
504: #include "symbol.h"
505: #include "alloc.h"
506: #include "ydefs.h"
507: #include "word.h"
508: #include "store.h"
509: #include "comm.h"
510: #include "inst.h"
511: #include "errjmp.h"
512: #include <libc.h>
513:
514: long resultloc;
515: long returnloc;
516: Node *formals;
517: long autooffset;
518: extern int bflag;
519: extern int cflag;
520: extern int nscope;
521: extern Node arychartype;
522:
523: compile(n) /* called from parser only */
524: Node *n;
525: {
526: extern long autooffset;
527: Errjmp x;
528: n=constants(n);
529: if(cflag){
530: fileline();
531: fprint(2, "constants:\n");
532: dump(n, 0);
533: }
534: errsave(x);
535: if(errmark()){
536: autooffset=0;
537: freenode(n);
538: errrest(x);
539: errjmp();
540: }
541: istart();
542: gen(n, 0);
543: freenode(n);
544: errrest(x);
545: }
546:
547: gen(Node *n, int retain)
548: {
549: int i;
550: if(n==0)
551: return;
552: switch(n->t){
553: case NArrayref:
554: arygen(n->l, n->r, 0, 0L);
555: if(!retain)
556: popgen(n->l->o.s->val->type->r);
557: return;
558: case NBecome:
559: if(n->l->t==NCall && !bflag){
560: callgen(n->l, Ibecome);
561: return;
562: }
563: gen(n->l, 1);
564: n=n->r;
565: if(n->o.t==TID)
566: n=typeoftid(n);
567: switch(n->o.t){
568: case TInt:
569: case TChar:
570: emit(Istoreauto);
571: emitconst(-LWS*(3+length(formals)));
572: break;
573: case TArray:
574: case TChan:
575: case TProg:
576: case TStruct:
577: emit(Istoreptrauto);
578: emitconst(-LWS*(3+length(formals)));
579: break;
580: case TUnit:
581: break;
582: default:
583: panic("can't compile %t become", n->o.t);
584: }
585: scopedecrefgen();
586: trlrgen();
587: return;
588: case NBegin:
589: callgen(n->l, Ibegin);
590: return;
591: case NCall:
592: callgen(n, Icall);
593: if(!retain)
594: popgen(etypeoft(n->l)->r);
595: return;
596: case NDecl:
597: case NDeclsc:
598: declare(n, 0, 0, 1);
599: return;
600: case NExpr:
601: switch(n->o.i){
602: case GE:
603: i=Ige;
604: Binop:
605: gen(n->l, 1);
606: gen(n->r, 1);
607: if(eqtype(etypeof(n->l), &arychartype)){
608: emit(Istrcmp);
609: constgen(0L);
610: }
611: emit(i);
612: Popit:
613: if(!retain)
614: emit(Ipop);
615: return;
616: case LE:
617: i=Ile;
618: goto Binop;
619: case NE:
620: i=Ine;
621: goto Binop;
622: case EQ:
623: i=Ieq;
624: goto Binop;
625: case '>':
626: i=Igt;
627: goto Binop;
628: case '<':
629: i=Ilt;
630: goto Binop;
631: case '+':
632: i=Iadd;
633: goto Binop;
634: case '-':
635: i=Isub;
636: goto Binop;
637: case '*':
638: i=Imul;
639: goto Binop;
640: case '/':
641: i=Idiv;
642: goto Binop;
643: case '%':
644: i=Imod;
645: goto Binop;
646: case '&':
647: i=Iand;
648: goto Binop;
649: case '|':
650: i=Ior;
651: goto Binop;
652: case '^':
653: i=Ixor;
654: goto Binop;
655: case LSH:
656: i=Ilsh;
657: goto Binop;
658: case RSH:
659: i=Irsh;
660: goto Binop;
661: case ANDAND:
662: condgen(n->l, n->r, Ijmptrue, Ijmpfalse, 0L, 1L, retain);
663: return;
664: case OROR:
665: condgen(n->l, n->r, Ijmpfalse, Ijmptrue, 1L, 0L, retain);
666: return;
667: case PRINT:
668: gen(n->l, 1);
669: printgen(n->l);
670: emit(Isprint);
671: if(!retain)
672: emit(Iprint);
673: return;
674: case SND:
675: gen(n->l, 1);
676: constgen((long)Cissnd);
677: emit(Icommset1);
678: emit(Icommcln1);
679: gen(n->r, 1);
680: if(isptrtype(etypeoft(n->l)->r))
681: emit(Isndptr);
682: else
683: emit(Isnd);
684: if(!retain)
685: popgen(etypeof(n));
686: return;
687: case RCV:
688: gen(n->l, 1);
689: constgen(0L); /* not Cissnd */
690: emit(Icommset1);
691: emit(Icommcln1);
692: return;
693: case '=':
694: gen(n->r, 1);
695: if(retain)
696: dupgen(etypeof(n->r), 1);
697: lgen(n->l);
698: return;
699: case LEN:
700: gen(n->l, 1);
701: emit(Ilen);
702: goto Popit;
703: case REF:
704: if(isptrtype(etypeof(n->l))){
705: gen(n->l, 1);
706: emit(Iref);
707: }else
708: constgen(1L);
709: goto Popit;
710: case DEF:
711: if(retain && n->l->t==NID && isinttype(etypeof(n->l))){
712: constgen(1L);
713: return;
714: }
715: /*
716: * don't really need to call lgen1, which will uniquify our
717: * array for us, but it does no harm, and it's easy.
718: */
719: lgen1(n->l, Idefauto, Idef, Idefary);
720: goto Popit;
721: case UMINUS:
722: gen(n->l, 1);
723: emit(Ineg);
724: goto Popit;
725: case '~':
726: gen(n->l, 1);
727: emit(Inot);
728: goto Popit;
729: case '!':
730: gen(n->l, 1);
731: emit(Ilnot);
732: goto Popit;
733: case INC:
734: lgen1(n->l, Iincauto, Iinc, Iincary);
735: goto Popit;
736: case DEC:
737: lgen1(n->l, Idecauto, Idec, Idecary);
738: goto Popit;
739: default:
740: panic("can't compile %e expression", n->o.i);
741: }
742:
743: case NExprlist:
744: /*
745: * This is an arg or element list; first is pushed last
746: */
747: gen(n->r, 1);
748: gen(n->l, 1);
749: return;
750: case NID:
751: if(!retain)
752: return;
753: switch(typeof(n)->o.t){
754: case TInt:
755: case TChar:
756: if(n->o.s->val->isauto){
757: emit(Ipushauto);
758: emitconst(n->o.s->val->store.off);
759: }else{
760: emit(Ipush);
761: emitconst((long)&n->o.s->val->store.l);
762: }
763: return;
764: case TProg:
765: case TArray:
766: case TChan:
767: case TStruct:
768: if(n->o.s->val->isauto){
769: emit(Ipushptrauto);
770: emitconst(n->o.s->val->store.off);
771: }else{
772: emit(Ipushptr);
773: emitconst((long)&n->o.s->val->store.l);
774: }
775: return;
776: case TUnit:
777: if(retain)
778: constgen(0L);
779: return;
780: case TType:
781: lerror(n, "attempt to evaluate type variable %m", n);
782: default:
783: panic("can't compile type %t", n->o.s->val->type->o.t);
784: }
785: case NIf:
786: ifgen(n);
787: return;
788: case NList:
789: gen(n->l, 0);
790: gen(n->r, 0);
791: return;
792: case NLoop:
793: loopgen(n);
794: return;
795: case NMk:
796: mkgen(n->l, n->r);
797: return;
798: case NNum:
799: if(retain)
800: constgen(n->o.l);
801: return;
802: case NProg:
803: if(retain)
804: proggen(n->l, n->r);
805: return;
806: case NResult:
807: gen(n->l, 1);
808: emit(Ijmp);
809: emitconst((long)(resultloc-here()-1)*WS);
810: return;
811: case NScope:
812: pushscope();
813: if(nscope==1){
814: int nauto;
815: autooffset=0;
816: emit(Ipushfp);
817: nauto=here();
818: emitconst(0L);
819: gen(n->l, 0);
820: patch((int)nauto, autooffset);
821: }else
822: gen(n->l, 0);
823: scopedecrefgen();
824: popscope();
825: return;
826: case NSelect:
827: selgen(n->l);
828: return;
829: case NSmash:{
830: Value *vl, *vr;
831: vl=n->l->o.s->val;
832: vr=n->r->o.s->val;
833: if(vr->type->o.t==TType){
834: freenode(vl->type);
835: vl->type=dupnode(vr->type);
836: return;
837: }
838: gen(n->r, 1);
839: /*
840: * Free old values; tricky: push as int, pop as ptr
841: */
842: if(isptrtype(vl->type)){
843: if(vl->isauto){
844: emit(Ipushauto);
845: emitconst(vl->store.off);
846: }else{
847: emit(Ipush);
848: emitconst((long)&vl->store.l);
849: }
850: emit(Ipopptr);
851: }
852: if(vl->isauto){
853: emit(Istoreauto);
854: emitconst(vl->store.l);
855: return;
856: }
857: emit(Istore);
858: emitconst((long)&vl->store.l);
859: return;
860: }
861: case NString:
862: if(retain){
863: Store *s;
864: s=(Store *)emalloc(SHSZ+strlen(n->o.c)+1);
865: strcpy((char *)(s->data), n->o.c);
866: s->ref=1;
867: s->len=strlen(n->o.c);
868: s->type=Sarychar;
869: emit(Ipushdata);
870: emitconst((long)s);
871: }
872: return;
873: case NStructref:
874: arygen(n->l, n->r, 1, n->o.l);
875: return;
876: case NSwitch:
877: switchgen(n->l, n->r);
878: return;
879: case NUnit:
880: if(retain)
881: constgen(0L);
882: return;
883: case NVal:
884: valgen(n->l);
885: if(!retain)
886: popgen(n->o.n);
887: return;
888: }
889: panic("can't compile node %n", n->t);
890: return;
891: }
892:
893: arygen(Node *a, Node *i, int isstr, long off)
894: {
895: int ptr, ischar;
896: if(isstr){
897: ptr=isptrtype(i);
898: constgen(off);
899: ischar=0;
900: }else{
901: Node *t=etypeoft(a)->r;
902: ptr=isptrtype(t);
903: gen(i, 1);
904: ischar=t->o.t==TChar;
905: }
906: if(a->t!=NID){
907: gen(a, 1);
908: emit(ptr? Ipusharyptrexpr :
909: (ischar? Ipusharycharexpr :Ipusharyexpr));
910: }else if(a->o.s->val->isauto){
911: emit(ptr? Ipusharyptrauto :
912: (ischar? Ipusharycharauto :Ipusharyauto));
913: emitconst(a->o.s->val->store.off);
914: }else{
915: emit(ptr? Ipusharyptr :
916: (ischar? Ipusharychar :Ipushary));
917: emitconst((long)&a->o.s->val->store.l);
918: }
919: }
920:
921: lgen(Node *n)
922: {
923: switch(n->t){
924: case NID:
925: switch(typeof(n)->o.t){
926: case TChar:
927: if(n->o.s->val->isauto){
928: emit(Istorecharauto);
929: emitconst(n->o.s->val->store.off);
930: return;
931: }
932: emit(Istorechar);
933: emitconst((long)&n->o.s->val->store.l);
934: return;
935: case TInt:
936: case TUnit:
937: if(n->o.s->val->isauto){
938: emit(Istoreauto);
939: emitconst(n->o.s->val->store.off);
940: return;
941: }
942: emit(Istore);
943: emitconst((long)&n->o.s->val->store.l);
944: return;
945: case TArray:
946: case TChan:
947: case TProg:
948: case TStruct:
949: if(n->o.s->val->isauto){
950: emit(Istoreptrauto);
951: emitconst(n->o.s->val->store.off);
952: return;
953: }
954: emit(Istoreptr);
955: emitconst((long)&n->o.s->val->store.l);
956: return;
957:
958: default:
959: panic("lgen: ID type %t", n->o.s->val->type->o.t);
960: return;
961: }
962: case NArrayref:
963: gen(n->r, 1);
964: goto Genref;
965: case NStructref:
966: constgen(n->o.l);
967: Genref:
968: lgen1(n->l, Ipushuniqauto, Ipushuniq, Ipushuniqary);
969: emit(Istoreary);
970: return;
971: default:
972: panic("lgen: lvalue node %n", n->t);
973: }
974: }
975:
976: /*
977: * n is a compound object about to be assigned into
978: */
979: lgen1(Node *n, int Iauto, int Ivar, int Iary)
980: {
981: switch(n->t){
982: case NID:
983: if(n->o.s->val->isauto){
984: emit(Iauto);
985: emitconst(n->o.s->val->store.off);
986: return;
987: }
988: emit(Ivar);
989: emitconst((long)&n->o.s->val->store.l);
990: return;
991: case NArrayref:
992: gen(n->r, 1);
993: goto Genref;
994: case NStructref:
995: constgen(n->o.l);
996: Genref:
997: lgen1(n->l, Ipushuniqauto, Ipushuniq, Ipushuniqary);
998: emit(Iary);
999: return;
1000: default:
1001: panic("lgen1: lvalue node %n", n->t);
1002: }
1003: }
1004:
1005: ifgen(Node *n)
1006: {
1007: int loc1, loc2;
1008: gen(n->o.n, 1);
1009: emit(Ijmpfalse);
1010: loc1=here();
1011: emit(0);
1012: gen(n->l, 0);
1013: if(n->r==0){
1014: patch(loc1, (long)(here()-loc1-1)*WS);
1015: return;
1016: }
1017: emit(Ijmp);
1018: loc2=here();
1019: emit(0);
1020: patch(loc1, (long)(here()-loc1-1)*WS);
1021: gen(n->r, 0);
1022: patch(loc2, (long)(here()-loc2-1)*WS);
1023: return;
1024: }
1025:
1026: valgen(Node *n)
1027: {
1028: int loc1, loc2;
1029: int orl;
1030: emit(Ijmp);
1031: loc1=here();
1032: emitconst(0L);
1033: orl=resultloc;
1034: resultloc=here();
1035: emit(Ijmp);
1036: loc2=here();
1037: emitconst(0L);
1038: patch(loc1, (long)(here()-loc1-1)*WS);
1039: gen(n, 1);
1040: emit(Ivalnoresult);
1041: patch(loc2, (long)(here()-loc2-1)*WS);
1042: resultloc=orl;
1043: }
1044:
1045: loopgen(Node *n)
1046: {
1047: int loc0, loc1, loc2;
1048: if(n->o.i){ /* enter loop at top, so jump to body */
1049: emit(Ijmp);
1050: loc0=here();
1051: emit(0);
1052: }
1053: gen(n->r->l, 0); /* left expr */
1054: if(n->r->r){ /* jump to condition */
1055: emit(Ijmp);
1056: loc1=here();
1057: emit(0);
1058: }
1059: if(n->o.i)
1060: patch(loc0, (here()-loc0-1)*LWS);
1061: loc2=here();
1062: gen(n->l, 0); /* body */
1063: gen(n->r->o.n, 0); /* right expr */
1064: if(n->r->r){
1065: patch(loc1, (here()-loc1-1)*LWS);
1066: gen(n->r->r, 1);
1067: emit(Ijmptrue);
1068: }else
1069: emit(Ijmp);
1070: emitconst((loc2-here()-1)*LWS);
1071: }
1072:
1073: condgen(Node *l, Node *r, Inst i1, Inst i2, long t1, long t2, int retain)
1074: {
1075: int loc1, loc2, loc3;
1076: gen(l, 1);
1077: emit(i1);
1078: loc1=here();
1079: emit(0);
1080: loc2=here();
1081: if(retain)
1082: constgen(t1);
1083: emit(Ijmp);
1084: loc3=here();
1085: emit(0);
1086: patch(loc1, (long)(here()-loc1-1)*WS);
1087: gen(r, 1);
1088: emit(i2);
1089: emitconst((long)(loc2-here()-1)*WS);
1090: if(retain)
1091: constgen(t2);
1092: patch(loc3, (long)(here()-loc3-1)*WS);
1093: }
1094:
1095: callgen(Node *n, int callinst)
1096: {
1097: Node *pt;
1098: pt=etypeof(n->l);
1099: /*
1100: * Space for result
1101: */
1102: constgen(0L);
1103: /*
1104: * Args
1105: */
1106: gen(n->r, 1);
1107: /*
1108: * Call
1109: */
1110: emit(Ipushconst);
1111: if(n->l->t==NID)
1112: emitconst((long)n->l->o.s->name);
1113: else{
1114: char buf[128];
1115: char *p;
1116: sprint(buf, "prog(){call on line %d}", n->line);
1117: p=emalloc((unsigned long)strlen(buf)+1);
1118: strcpy(p, buf);
1119: emitconst((long)p);
1120: }
1121: gen(n->l, 1);
1122: switch(callinst){
1123: case Icall:
1124: emit(Icall);
1125: return;
1126: case Ibegin:
1127: constgen(LWS*(1+1+length(pt->l))); /* result+procname+args */
1128: emit(Ibegin);
1129: return;
1130: case Ibecome:
1131: constgen(LWS*(1+1+length(pt->l))); /* result+procname+args */
1132: scopedecrefgen();
1133: fdecrefgen(formals, -3L*WS);
1134: emit(Ibecome);
1135: if(formals)
1136: emitconst(length(formals)*LWS);
1137: else
1138: emitconst(0L);
1139: return;
1140: }
1141: panic("callgen");
1142: }
1143:
1144: selgen(Node *n)
1145: {
1146: int tbl, i;
1147: long l;
1148: int ends[200];
1149: selchangen(n);
1150: l=length(n);
1151: constgen(l);
1152: emit(Icommset);
1153: emit(Icommcln);
1154: if(l>(sizeof ends/sizeof ends[0]))
1155: panic("selgen table too small");
1156: tbl=here();
1157: emitspace(l);
1158: i=0;
1159: seltblgen(n, tbl, ends, &i);
1160: for(i=0; i<l; i++)
1161: patch(ends[i], (long)(here()-ends[i]-1)*WS);
1162: }
1163:
1164: selchangen(Node *n)
1165: {
1166: long flags;
1167: if(n->t==NList){
1168: selchangen(n->l);
1169: selchangen(n->r);
1170: return;
1171: }
1172: if(n->t!=NCase)
1173: panic("selchangen");
1174: n=n->l->l;
1175: if(n->o.t=='=')
1176: n=n->r; /* n is now RCV or SND */
1177: flags=0;
1178: if(n->o.t==SND)
1179: flags|=Cissnd;
1180: n=n->l; /* n is now channel */
1181: if(n->t==NArraycom){
1182: flags|=Cisary;
1183: n=n->l;
1184: }else if(etypeoft(n)->o.t==TArray)
1185: flags|=Cisary;
1186: gen(n, 1);
1187: constgen(flags);
1188: }
1189:
1190: seltblgen(Node *n, int tbl, int *ends, int *ip)
1191: {
1192: Node *c, *s, *l, *t;
1193: if(n->t==NList){
1194: /* chans are eval'ed from the top, so table is backwards */
1195: seltblgen(n->r, tbl, ends, ip);
1196: seltblgen(n->l, tbl, ends, ip);
1197: return;
1198: }
1199: if(n->t!=NCase)
1200: panic("seltblgen");
1201: if(n->l->t==NList)
1202: error("sorry, empty cases not implemented");
1203: patch(tbl+*ip, (long)(here()-tbl)*WS);
1204: c=n->l->l; /* communication */
1205: s=n->r; /* statement */
1206: l=0;
1207: if(c->o.t=='='){
1208: l=c->l; /* lvalue */
1209: c=c->r;
1210: }
1211: if(c->o.t==SND){
1212: gen(c->r, 1);
1213: if(isptrtype(etypeoft(c->l)->r))
1214: emit(Isndptr);
1215: else
1216: emit(Isnd);
1217: }
1218: c=c->l; /* channel expression */
1219: /*
1220: * The value is still on the stack; save it or toss it
1221: */
1222: if(l)
1223: lgen(l);
1224: else if(c->t==NArraycom){
1225: t=etypeoft(c->l)->r;
1226: if(t->o.t==TID)
1227: t=typeoftid(t);
1228: popgen(t->r);
1229: }else
1230: popgen(etypeoft(c)->r);
1231: if(c->t==NArraycom){ /* save array index */
1232: if(c->r)
1233: lgen(c->r);
1234: else
1235: emit(Ipop);
1236: }
1237: gen(s, 0);
1238: emit(Ijmp);
1239: ends[*ip]=here();
1240: (*ip)++;
1241: emitconst(0L);
1242: }
1243:
1244: switchgen(Node *s, Node *e)
1245: {
1246: int isptr, out;
1247: isptr=isptrtype(etypeof(e));
1248: gen(e, 1);
1249: emit(Ijmp);
1250: emitconst(2*LWS);
1251: emit(Ijmp); /* each case jumps to here to get out */
1252: out=here();
1253: emitconst(0L);
1254: switchgen1(s, isptr, out-1);
1255: /* pop leftover value if no case matched */
1256: if(isptr)
1257: emit(Ipopptr);
1258: else
1259: emit(Ipop);
1260: patch(out, (here()-out-1)*LWS);
1261: }
1262:
1263: switchgen1(Node *s, int isptr, int out)
1264: {
1265: Node *e;
1266: int loc;
1267: if(s->t==NList){
1268: switchgen1(s->l, isptr, out);
1269: switchgen1(s->r, isptr, out);
1270: return;
1271: }
1272: if(s->t!=NCase)
1273: panic("switchgen1");
1274: if(s->r==0)
1275: error("sorry; can't fold cases together yet");
1276: if(s->l->t==NDefault)
1277: loc=-1;
1278: else{
1279: e=s->l->l;
1280: if(isptr){ /* string */
1281: emit(Idupptr);
1282: gen(e, 1);
1283: emit(Istrcmp);
1284: constgen(0L);
1285: }else{
1286: emit(Idup);
1287: gen(e, 1);
1288: }
1289: emit(Ieq);
1290: emit(Ijmpfalse);
1291: loc=here();
1292: emitconst(0L);
1293: }
1294: if(isptr)
1295: emit(Ipopptr);
1296: else
1297: emit(Ipop);
1298: gen(s->r, 0);
1299: emit(Ijmp);
1300: emitconst((out-here()-1)*LWS);
1301: if(loc!=-1)
1302: patch(loc, (here()-loc-1)*LWS);
1303: }
1304:
1305: popgen(Node *t)
1306: {
1307: if(isptrtype(t))
1308: emit(Ipopptr);
1309: else if(isinttype(t) || t->o.t==TUnit)
1310: emit(Ipop);
1311: else
1312: panic("popgen %t\n", t->o.t);
1313: }
1314:
1315: genfreeauto(Symbol *s)
1316: {
1317: if(!s->val->isauto)
1318: panic("genfreeauto");
1319: if(isptrtype(s->val->type)){
1320: emit(Idecrefauto);
1321: emitconst(s->val->store.off);
1322: }
1323: }
1324:
1325: printgen(Node *n)
1326: {
1327: Node *t;
1328: if(n==0)
1329: return;
1330: if(n->t==NExprlist){
1331: printgen(n->l);
1332: printgen(n->r);
1333: return;
1334: }
1335: t=etypeoft(n);
1336: switch(t->o.t){
1337: case TArray:
1338: case TChan:
1339: case TProg:
1340: case TStruct:
1341: emit(Iprintary);
1342: break;
1343: case TChar:
1344: emit(Iprintchar);
1345: break;
1346: case TInt:
1347: emit(Iprintint);
1348: break;
1349: case TUnit:
1350: emit(Iprintunit);
1351: break;
1352: default:
1353: panic("printgen: bad type %t", t->o.t);
1354: }
1355: }
1356:
1357: proggen(Node *t, Node *n)
1358: {
1359: int or;
1360: Node *of;
1361: Errjmp s;
1362: Store *p;
1363: long len, loc;
1364: long nauto, oao;
1365: extern int (*prog[])();
1366: oao=autooffset;
1367: or=returnloc;
1368: of=formals;
1369: autooffset=0;
1370: returnloc=0;
1371: formals=t->l;
1372: errsave(s);
1373: if(errmark()){
1374: returnloc=or;
1375: formals=of;
1376: autooffset=oao;
1377: errrest(s);
1378: errjmp();
1379: }
1380: loc=here();
1381: pushscope();
1382: dclformals(t->l);
1383: autooffset=0;
1384: emit(Ipushfp);
1385: nauto=here();
1386: emitconst(0L);
1387: gen(n, 0);
1388: trlrgen();
1389: patch((int)nauto, autooffset);
1390: popscope();
1391: errrest(s);
1392: autooffset=oao;
1393: returnloc=or;
1394: formals=of;
1395: len=here()-loc+1;
1396: p=(Store *)emalloc(SHSZ+len*LWS);
1397: memcpy((char *)(p->data), (char *)(prog+loc), len*LWS);
1398: p->ref=1;
1399: p->len=len;
1400: p->type=Sprog;
1401: setprog(loc);
1402: emit(Ipushdata);
1403: emitconst((long)p);
1404: }
1405:
1406: trlrgen()
1407: {
1408: if(returnloc){
1409: emit(Ijmp);
1410: emitconst((long)(returnloc-here()-1)*WS);
1411: return;
1412: }
1413: returnloc=here();
1414: fdecrefgen(formals, -3L*WS);
1415: emit(Iret);
1416: if(formals)
1417: emitconst(length(formals)*LWS);
1418: else
1419: emitconst(0L);
1420: }
1421:
1422: fdecrefgen(Node *types, long offset)
1423: {
1424: if(types==0)
1425: return 0;
1426: if(types->t==NList){
1427: offset=fdecrefgen(types->l, offset);
1428: return fdecrefgen(types->r, offset);
1429: }
1430: if(types->t!=NFormal)
1431: panic("fdecrefgen");
1432: types=types->r;
1433: if(isptrtype(types)){
1434: emit(Idecrefauto);
1435: emitconst(offset);
1436: }
1437: return offset-WS;
1438: }
1439:
1440: dupgen(Node *t, int n)
1441: {
1442: while(n--)
1443: emit(isptrtype(t)? Idupptr : Idup);
1444: }
1445:
1446: mkgen(Node *t, Node *v)
1447: {
1448: switch(t->o.t){
1449: case TChar:
1450: case TInt:
1451: case TUnit:
1452: if(v)
1453: gen(v, 1);
1454: else
1455: constgen(0L);
1456: return;
1457: case TID:
1458: mkgen(typeoftid(t), v);
1459: return;
1460: case TChan:
1461: if(v)
1462: gen(v, 1);
1463: else{
1464: constgen((long)(sizeof(Chan)-sizeof(Store)));
1465: mallocgen(t);
1466: }
1467: return;
1468: case TArray:
1469: if(v==0){
1470: gen(t->l, 1);
1471: mallocgen(t);
1472: return;
1473: }
1474: gen(v, 1);
1475: if(v->t!=NExprlist && eqtype(t, etypeof(v)))
1476: return;
1477: if(v->t==NString)
1478: constgen((long)strlen(v->o.c));
1479: else
1480: constgen((long)length(v));
1481: emit(Idup);
1482: if(t->l)
1483: gen(t->l, 1);
1484: else
1485: constgen(0L);
1486: emit(Imax);
1487: mallocgen(t);
1488: if(t->r->o.t==TChar){
1489: if(v->t==NString)
1490: emit(Imemcpychar);
1491: else
1492: emit(Imemcpycharint);
1493: }else
1494: emit(Imemcpy);
1495: return;
1496: case TProg:
1497: if(v==0){
1498: v=new(NProg, dupnode(t), (Node *)0, (Node *)0);
1499: gen(v, 1);
1500: freenode(v);
1501: return;
1502: }
1503: gen(v, 1);
1504: return;
1505: case TStruct:
1506: if(v==0){
1507: mallocgen(t);
1508: return;
1509: }
1510: gen(v, 1);
1511: if(v->t!=NExprlist && eqtype(t, etypeof(v)))
1512: return;
1513: constgen((long)length(v));
1514: mallocgen(t);
1515: emit(Imemcpystruct);
1516: return;
1517: default:
1518: panic("mkgen: bad type %t", t->o.t);
1519: }
1520: }
1521:
1522: mallocgen(Node *t)
1523: {
1524: switch(t->o.t){
1525: case TArray:
1526: t=t->r;
1527: if(t->o.t==TID)
1528: t=typeoftid(t);
1529: if(isptrtype(t)){
1530: constgen((long)Saryptr);
1531: emit(Imalloc);
1532: }else if(t->o.t==TInt || t->o.t==TUnit){
1533: constgen((long)Saryint);
1534: emit(Imalloc);
1535: }else if(t->o.t==TChar)
1536: emit(Imallocarychar);
1537: else
1538: panic("mallocgen array of %t", t->o.t);
1539: return;
1540: case TStruct:{
1541: int pos=0;
1542: long bits=0;
1543: t=t->l;
1544: elembitsgen(t, &pos, &bits);
1545: if(pos)
1546: constgen(bits);
1547: constgen((long)length(t));
1548: emit(Imallocstruct);
1549: return;
1550: }
1551: case TChan:
1552: constgen((long)Schan);
1553: emit(Imalloc);
1554: return;
1555: }
1556: panic("mallocgen of %t", t->o.t);
1557: }
1558:
1559: elembitsgen(Node *t, int *pos, long *bits)
1560: {
1561: int i;
1562: if(t->t==NList){
1563: elembitsgen(t->l, pos, bits);
1564: elembitsgen(t->r, pos, bits);
1565: return;
1566: }
1567: if(t->t!=NElem)
1568: panic("elembitsgen %n", t->t);
1569: for(i=length(t); --i>=0; ){
1570: if(*pos==BPW){
1571: constgen(*bits);
1572: *pos=0;
1573: *bits=0;
1574: }
1575: if(isptrtype(t->r))
1576: *bits|=1L<<*pos;
1577: (*pos)++;
1578: }
1579: }
1580:
1581: constgen(long l)
1582: {
1583: if(l<-2 || l>10){
1584: emit(Ipushconst);
1585: emitconst(l);
1586: return;
1587: };
1588: switch((int)l){
1589: case -2:
1590: emit(Ipush_2);
1591: break;
1592: case -1:
1593: emit(Ipush_1);
1594: break;
1595: case 0:
1596: emit(Ipush0);
1597: break;
1598: case 1:
1599: emit(Ipush1);
1600: break;
1601: case 2:
1602: emit(Ipush2);
1603: break;
1604: case 3:
1605: emit(Ipush3);
1606: break;
1607: case 4:
1608: emit(Ipush4);
1609: break;
1610: case 5:
1611: emit(Ipush5);
1612: break;
1613: case 6:
1614: emit(Ipush6);
1615: break;
1616: case 7:
1617: emit(Ipush7);
1618: break;
1619: case 8:
1620: emit(Ipush8);
1621: break;
1622: case 9:
1623: emit(Ipush9);
1624: break;
1625: case 10:
1626: emit(Ipush10);
1627: break;
1628: default:
1629: panic("constgen");
1630: }
1631: }
1632:
1633: printable(Node *n)
1634: {
1635: if(n==0)
1636: return 0;
1637: switch(n->t){
1638: case NExpr:
1639: return n->o.t!='=';
1640: case NArrayref:
1641: case NCall:
1642: case NID:
1643: case NMk:
1644: case NNum:
1645: case NProg:
1646: case NString:
1647: case NStructref:
1648: case NUnit:
1649: case NVal:
1650: return 1;
1651: }
1652: return 0;
1653: }
1654: #include "alloc.h"
1655: #include "node.h"
1656: #include "symbol.h"
1657: #include "ydefs.h"
1658: #include "word.h"
1659: #include "store.h"
1660: #include <libc.h>
1661:
1662: Node *doconst();
1663: extern int Cflag;
1664:
1665: Node *
1666: constants(Node *n)
1667: {
1668: if(n==0)
1669: return 0;
1670: if(Cflag)
1671: return n;
1672: switch(n->t){
1673: case NArrayref:
1674: if(isconst(n))
1675: return doconst(n);
1676: break;
1677: case NArraycom:
1678: break;
1679: case NBecome:
1680: break;
1681: case NBegin:
1682: break;
1683: case NCall:
1684: break;
1685: case NCase:
1686: break;
1687: case NDecl:
1688: n->r=constants(n->r);
1689: n->o.n=constants(n->o.n);
1690: declare(n, 0, 0, 0);
1691: return n;
1692: case NDeclsc:
1693: break;
1694: case NDefault:
1695: return n;
1696: case NElem:
1697: n->r=constants(n->r);
1698: return n;
1699: case NExpr:
1700: switch(n->o.i){
1701: case GE:
1702: case LE:
1703: case NE:
1704: case EQ:
1705: case '>':
1706: case '<':
1707: case '+':
1708: case '-':
1709: case '*':
1710: case '/':
1711: case '%':
1712: case '&':
1713: case '|':
1714: case '^':
1715: case ANDAND:
1716: case OROR:
1717: case LSH:
1718: case RSH:
1719: if(isconst(n->l) && isconst(n->r))
1720: return doconst(n);
1721: break;
1722: case DEF:
1723: case REF:
1724: case LEN:
1725: case UMINUS:
1726: case '~':
1727: case '!':
1728: if(isconst(n->l))
1729: return doconst(n);
1730: break;
1731: case PRINT:
1732: case RCV:
1733: case SND:
1734: case INC:
1735: case DEC:
1736: break;
1737: case '=':
1738: break;
1739: default:
1740: fprint(2, "can't const expression %e\n", n->o.i);
1741: return n;
1742: }
1743: break;
1744: case NExprlist:
1745: break;
1746: case NFormal:
1747: n->r=constants(n->r);
1748: return n;
1749: case NLabel:
1750: break;
1751: case NID:
1752: if(isconst(n))
1753: return doconst(n);
1754: break;
1755: case NIf:
1756: n->l=constants(n->l);
1757: n->r=constants(n->r);
1758: n->o.n=constants(n->o.n);
1759: if(isconst(n->o.n)){
1760: Node *m;
1761: gen(n->o.n, 1);
1762: execute();
1763: if(topofstack()){
1764: m=n->l;
1765: n->l=0;
1766: }else{
1767: m=n->r;
1768: n->r=0;
1769: }
1770: freenode(n);
1771: return m;
1772: }
1773: return n;
1774: case NList:
1775: break;
1776: case NLoop:
1777: break;
1778: case NLoopexpr:
1779: n->o.n=constants(n->o.n);
1780: break;
1781: case NMk:
1782: break;
1783: case NNum:
1784: return n;
1785: case NProg:
1786: pushscope();
1787: dclformals(n->l->l);
1788: n->r=constants(n->r);
1789: popscope();
1790: return n;
1791: case NResult:
1792: break;
1793: case NScope:
1794: pushscope();
1795: n->l=constants(n->l);
1796: popscope();
1797: return n;
1798: case NSelect:
1799: break;
1800: case NSmash:
1801: return n;
1802: case NString:
1803: return n;
1804: case NSwitch:
1805: break;
1806: case NStructref:
1807: if(isconst(n))
1808: return (n);
1809: break;
1810: case NType:
1811: break;
1812: case NUnit:
1813: break;
1814: case NVal:
1815: if(isconst(n->l))
1816: return doconst(n);
1817: break;
1818: default:
1819: fprint(2, "can't const node %n\n", n->t);
1820: return n;
1821: }
1822: n->l=constants(n->l);
1823: n->r=constants(n->r);
1824: return n;
1825: }
1826:
1827: isconst(Node *n)
1828: {
1829: if(n==0)
1830: return 1;
1831: switch(n->t){
1832: case NArrayref:
1833: return isconst(n->l) && isconst(n->r);
1834: case NCall:
1835: return 0;
1836: case NExpr:
1837: switch(n->o.i){
1838: case GE:
1839: case LE:
1840: case NE:
1841: case EQ:
1842: case '>':
1843: case '<':
1844: case '+':
1845: case '-':
1846: case '*':
1847: case '/':
1848: case '%':
1849: case '&':
1850: case '|':
1851: case '^':
1852: case ANDAND:
1853: case OROR:
1854: case LSH:
1855: case RSH:
1856: return isconst(n->l) && isconst(n->r);
1857: case DEF:
1858: case LEN:
1859: case UMINUS:
1860: case '~':
1861: case '!':
1862: return isconst(n->l);
1863: case REF:
1864: case '=':
1865: case RCV:
1866: case SND:
1867: case INC:
1868: case DEC:
1869: return 0;
1870: }
1871: fprint(2, "can't isconst expression %e", n->o.i);
1872: return 0;
1873: case NID:
1874: return n->o.s->val->scope==0 && (n->o.s->val->stclass&SCconst);
1875: case NIf:
1876: return isconst(n->o.n) && isconst(n->l) && isconst(n->r);
1877: case NList:
1878: return 0;
1879: case NLoop:
1880: return 0;
1881: case NNum:
1882: return 1;
1883: case NResult:
1884: return isconst(n->l);
1885: case NScope:
1886: return isconst(n->l);
1887: case NString:
1888: return 1;
1889: case NStructref:
1890: return isconst(n->l);
1891: case NVal:
1892: return isconst(n->l);
1893: case NUnit:
1894: return 1;
1895: }
1896: fprint(2, "can't isconst node %n\n", n->t);
1897: return 0;
1898: }
1899:
1900: Node *
1901: doconst(Node *n)
1902: {
1903: Node *t;
1904: if(n->t==NNum || n->t==NString || n->t==NUnit)
1905: return n; /* already const */
1906: t=etypeoft(n);
1907: switch(t->o.t){
1908: case TChar:
1909: case TInt:
1910: gen(n, 1);
1911: freenode(n);
1912: execute();
1913: return new(NNum, (Node *)0, (Node *)0, (Node *)topofstack());
1914: case TUnit:
1915: return new(NUnit, (Node *)0, (Node *)0, (Node *)0);
1916: case TArray:
1917: if(t->r->o.t==TChar){
1918: Store *s;
1919: char *c;
1920: gen(n, 1);
1921: freenode(n);
1922: execute();
1923: s=(Store *)topofstack();
1924: c=emalloc(s->len+1);
1925: strncpy(c, (char *)s->data, (int)s->len);
1926: return newc(NString, (Node *)0, (Node *)0, c);
1927: }
1928: return n;
1929: }
1930: return n;
1931: }
1932: #include "alloc.h"
1933: #include "word.h"
1934: #include "store.h"
1935: #include "comm.h"
1936: #include <libc.h>
1937:
1938: extern int pflag;
1939:
1940: /*
1941: * Jumps
1942: */
1943:
1944: ijmp(Proc *proc)
1945: {
1946: SWord l;
1947: l=(SWord)*++proc->pc;
1948: proc->pc+=l/WS;
1949: return 1;
1950: }
1951:
1952: ijmpfalse(Proc *proc)
1953: {
1954: SWord l;
1955: l=(SWord)*++proc->pc;
1956: if(*--proc->sp==0)
1957: proc->pc+=l/WS;
1958: return 1;
1959: }
1960:
1961: ijmptrue(Proc *proc)
1962: {
1963: SWord l;
1964: l=(SWord)*++proc->pc;
1965: if(*--proc->sp!=0)
1966: proc->pc+=l/WS;
1967: return 1;
1968: }
1969:
1970: ivalnoresult(Proc *proc)
1971: {
1972: rerror("val produces no result");
1973: return 0;
1974: }
1975:
1976: /*
1977: * Progs
1978: *
1979: * Layout of a stack frame
1980: *
1981: * sp:
1982: * automatics
1983: * fp: old fp
1984: * old pc
1985: * symbol
1986: * arg1
1987: * arg2
1988: * ...
1989: * result
1990: */
1991:
1992: iret(Proc *proc)
1993: {
1994: SWord nargs;
1995: nargs=(SWord)(proc->pc[1]);
1996: proc->sp=(SWord *)proc->fp+1;
1997: proc->fp=(SWord *)*--proc->sp;
1998: proc->pc=(int (**)())*--proc->sp;
1999: proc->sp-=(sizeof(char *)+nargs)/WS;
2000: if(proc->pc==0){
2001: if(pflag)
2002: fprint(2, "%d halts\n", proc->procnum);
2003: halt(proc);
2004: return 0;
2005: }
2006: return 1;
2007: }
2008:
2009: ibecome(Proc *proc)
2010: {
2011: int nargs;
2012: int (**newpc)();
2013: SWord oldfp, oldpc, *oldresultaddr, *newresultaddr;
2014: Store *s;
2015: nargs=*--proc->sp/LWS;
2016: nargs+=2; /* includes result and sym; add pc, fp */
2017: s=(Store *)*--proc->sp;
2018: if(--(s->ref)==0)
2019: rpanic("ibecome ref==0");
2020: newpc=((int (**)())s->data);
2021: oldfp=proc->fp[0];
2022: oldpc=proc->fp[-1];
2023: *proc->sp++=oldpc;
2024: *proc->sp++=oldfp;
2025: oldresultaddr=proc->fp-3-(long)(*++proc->pc)/LWS;
2026: newresultaddr=proc->sp-nargs;
2027: memcpy((char *)oldresultaddr, (char *)newresultaddr, LWS*nargs);
2028: /* args in place. do the call by hand, jmp to pushfp */
2029: proc->sp=oldresultaddr+(nargs-2);
2030: *proc->sp++=oldpc;
2031: proc->fp=(SWord *)oldfp;
2032: proc->pc=newpc-1;
2033: return 1;
2034: }
2035:
2036: ipushfp(Proc *proc)
2037: {
2038: int nauto;
2039: *proc->sp=(SWord)proc->fp;
2040: proc->fp=proc->sp++;
2041: nauto=((SWord)*++proc->pc)/WS;
2042: while(nauto--)
2043: *proc->sp++=0;
2044: if(proc->sp>=&proc->stack[NSTACK])
2045: rerror("stack overflow");
2046: return 1;
2047: }
2048:
2049: icall(Proc *proc)
2050: {
2051: int (**newpc)();
2052: Store *s;
2053: s=(Store *)*--proc->sp;
2054: if(--(s->ref)==0)
2055: rpanic("icall ref==0");
2056: newpc=((int (**)())s->data);
2057: *proc->sp++=(SWord)proc->pc;
2058: proc->pc=newpc-1;
2059: return 1;
2060: }
2061: #include "node.h"
2062: #include "symbol.h"
2063: #include "alloc.h"
2064: #include "ydefs.h"
2065: #include "word.h"
2066: #include "store.h"
2067: #include <libc.h>
2068:
2069: extern int nscope;
2070:
2071: declare(Node *n, int stclass, int dotypchk, int docomp)
2072: {
2073: extern int iflag;
2074: if(n==0)
2075: return;
2076: if(n->t==NList){
2077: declare(n->l, stclass, dotypchk, docomp);
2078: declare(n->r, stclass, dotypchk, docomp);
2079: return;
2080: }
2081: if(n->t==NDeclsc){
2082: declare(n->l, n->o.i, dotypchk, docomp);
2083: return;
2084: }
2085: if(dotypchk)
2086: type(n->o.n, 0);
2087: if(n->r==0){
2088: if(n->o.n==0)
2089: panic("declare: no type");
2090: if(n->o.n->t==NMk && n->o.n->l==0)
2091: lerror(n, "can't derive type in declaration");
2092: n->r=dupnode(etypeof(n->o.n));
2093: }
2094: if(dotypchk){
2095: type(n->r, 0);
2096: if(n->o.n){
2097: /*
2098: * Make it a mk
2099: */
2100: if(n->o.n->t!=NMk)
2101: n->o.n=new(NMk, (Node *)0, n->o.n, (Node *)0);
2102: /*
2103: * Default type for mk
2104: */
2105: if(n->o.n->l==0)
2106: n->o.n->l=dupnode(n->r);
2107: else if(!compattype(n->r, n->o.n->l))
2108: lerror(n, "type clash in declaration (%t %t)\n",
2109: n->r->o.t, etypeof(n->o.n)->o.t);
2110: mkcheck(n->o.n->l, n->o.n->r);
2111: }
2112: }
2113: if(docomp && n->o.n){
2114: if(dotypchk) /* top level declaration */
2115: n->o.n=constants(n->o.n);
2116: gen(n->o.n, 1);
2117: dupgen(n->r, length(n->l)-1);
2118: }else
2119: docomp=0;
2120: dcl(n->l, n->r, stclass, n->o.n, docomp);
2121: if(n->o.n && docomp && nscope==0){
2122: if(iflag)
2123: idump();
2124: execute();
2125: }
2126: }
2127:
2128: dcl(id, typ, stclass, val, docomp)
2129: Node *id, *typ, *val;
2130: {
2131: if(id->t==NList){
2132: dcl(id->l, typ, stclass, val, docomp);
2133: dcl(id->r, typ, stclass, val, docomp);
2134: return;
2135: }
2136: if(typ->o.t==TID && typ->l->o.s->val->type->o.t!=TType)
2137: error("%m not a type", typ->l);
2138: if(id->t!=NID)
2139: panic("dcl not ID");
2140: pushval(id->o.s, dupnode(typ));
2141: if(stclass&SCbltin)
2142: id->o.s->val->store.l=bltinval(id->o.s->name, typ);
2143: if(docomp)
2144: lgen(id);
2145: id->o.s->val->stclass=stclass;
2146: }
2147:
2148: /*
2149: * To compile this
2150: * rec {
2151: * x : chan of T = f(x,y);
2152: * y : chan of T = g(x,y);
2153: * };
2154: * convert it to this
2155: * x : chan of T = mk();
2156: * y : chan of T = mk();
2157: * x1 : chan of T = f(x,y);
2158: * y1 : chan of T = g(x,y);
2159: * x <- x1;
2160: * y <- y1;
2161: * toss x1, y1;
2162: * where the operator x <- x1 means copy the representation of x1 into x.
2163: *
2164: * rec type T: struct of { t:T; };
2165: *
2166: * is handled similarly.
2167: */
2168:
2169: Node *
2170: op1(Node *n)
2171: {
2172: Node *m;
2173: if(n->t==NDeclsc){
2174: m=op1(n->l);
2175: return newi(NDeclsc, m, (Node *)0, n->o.i);
2176: }
2177: if(n->r==0){
2178: if(n->o.n && (n->o.n->t==NProg || (n->o.n->t==NMk && n->o.n->l)))
2179: n->r=dupnode(n->o.n->l);
2180: else
2181: lerror(n, "can't deduce type for rec decl");
2182: }else if(n->r->o.t==TType){
2183: m=newi(NType, (Node *)0, (Node *)0, n->r->l->o.t);
2184: m=new(NDecl, dupnode(n->l), m, (Node *)0);
2185: return m;
2186: }
2187: m=new(NMk, dupnode(n->r), (Node *)0, (Node *)0);
2188: m=new(NDecl, dupnode(n->l), dupnode(n->r), m);
2189: return m;
2190: }
2191:
2192: Node *
2193: op2(Node *n)
2194: {
2195: Node *m;
2196: char s[Namesize+2];
2197: if(n->t==NDeclsc){
2198: m=op2(n->l);
2199: return newi(NDeclsc, m, (Node *)0, n->o.i);
2200: }
2201: if(n->l->t==NList)
2202: error("no identifier lists in rec's, please");
2203: strcpy(s+1, n->l->o.s->name);
2204: s[0]='*';
2205: m=new(NDecl, idnode(lookup(s, ID)), dupnode(n->r), dupnode(n->o.n));
2206: return m;
2207: }
2208:
2209: Node *
2210: op3(Node *n)
2211: {
2212: Node *m;
2213: char s[Namesize+2];
2214: if(n->t==NDeclsc)
2215: return op3(n->l);
2216: if(n->l->t==NList)
2217: error("no lists in rec's, please");
2218: strcpy(s+1, n->l->o.s->name);
2219: s[0]='*';
2220: m=new(NSmash, idnode(lookup(s+1, ID)), idnode(lookup(s, ID)), (Node *)0);
2221: return m;
2222: }
2223:
2224: Node *
2225: rewr(Node *n, Node *(*f)())
2226: {
2227: if(n->t==NList)
2228: return new(NList, rewr(n->l, f), rewr(n->r, f), (Node *)0);
2229: return (*f)(n);
2230: }
2231:
2232: recrewrite(Node *n)
2233: {
2234: Node *n1, *n2, *n3;
2235: n1=rewr(n->l, op1);
2236: n2=rewr(n->l, op2);
2237: n3=rewr(n->l, op3);
2238: freenode(n->l);
2239: n->t=NList;
2240: n->r=n3;
2241: n->l=new(NList, n1, n2, (Node *)0);
2242: ndump(n);
2243: }
2244:
2245: /*
2246: *
2247: * To compile this
2248: *
2249: * prog(a:int){
2250: * begin prog(b:int){ f(a, b); }(b);
2251: * }
2252: *
2253: * convert it to this
2254: *
2255: * prog(a:int){
2256: * begin prog(b:int, a:int){ f(a, b); }(b, a);
2257: * }
2258: *
2259: */
2260:
2261: Node *begf;
2262: Node *bega;
2263: int fscope;
2264: int progerr;
2265:
2266: proglocals(Node *n)
2267: {
2268: progerr=1;
2269: pushscope();
2270: fscope=nscope;
2271: begf=n->l->l;
2272: bega=0;
2273: dclformals(begf);
2274: progid(n->r);
2275: popscope();
2276: }
2277:
2278: begrewrite(Node *n)
2279: {
2280: progerr=0;
2281: pushscope();
2282: fscope=nscope;
2283: begf=n->l->l->l;
2284: bega=n->r;
2285: dclformals(begf);
2286: progid(n->l->r);
2287: popscope();
2288: n->l->l->l=begf;
2289: n->r=bega;
2290: }
2291:
2292: addformal(Node *n)
2293: {
2294: Node *nf;
2295: if(!alreadyformal(n, begf)){
2296: nf=new(NFormal, dupnode(n), dupnode(n->o.s->val->type), (Node *)0);
2297: if(begf)
2298: begf=new(NList, begf, nf, (Node *)0);
2299: else
2300: begf=nf;
2301: nf=dupnode(n);
2302: if(bega)
2303: bega=new(NExprlist, bega, nf, (Node *)0);
2304: else
2305: bega=nf;
2306: }
2307: }
2308:
2309: alreadyformal(Node *n, Node *f)
2310: {
2311: if(f==0)
2312: return 0;
2313: if(f->t==NList)
2314: return alreadyformal(n, f->l) || alreadyformal(n, f->r);
2315: return strcmp(n->o.s->name, f->l->o.s->name)==0;
2316: }
2317:
2318: progid(Node *n)
2319: {
2320: if(n==0)
2321: return;
2322: switch(n->t){
2323: case NArrayref:
2324: case NArraycom:
2325: case NBecome:
2326: case NBegin:
2327: case NCall:
2328: case NCase:
2329: break;
2330: case NDecl:
2331: progid(n->r);
2332: progid(n->o.n);
2333: declare(n, 0, 0, 0);
2334: return;
2335: case NDeclsc:
2336: case NDefault:
2337: break;
2338: case NElem:
2339: return;
2340: case NExpr:
2341: case NExprlist:
2342: case NFormal:
2343: break;
2344: case NID:
2345: if(n->o.s->val)
2346: if(0<n->o.s->val->scope && n->o.s->val->scope<fscope){
2347: if(progerr)
2348: lerror(n, "%m not in an accessible scope", n);
2349: addformal(n);
2350: }
2351: return;
2352: case NLabel:
2353: case NList:
2354: case NLoop:
2355: break;
2356: case NLoopexpr:
2357: progid(n->o.n);
2358: break;
2359: case NIf:
2360: progid(n->o.n);
2361: break;
2362: case NMk:
2363: break;
2364: case NNum:
2365: return;
2366: case NProg:
2367: pushscope();
2368: dclformals(n->l->l);
2369: progid(n->r);
2370: popscope();
2371: return;
2372: case NResult:
2373: break;
2374: case NScope:
2375: pushscope();
2376: progid(n->l);
2377: popscope();
2378: return;
2379: case NSelect:
2380: break;
2381: case NSmash:
2382: return; /* ?? */
2383: case NString:
2384: return;
2385: case NSwitch:
2386: case NStructref:
2387: break;
2388: case NType:
2389: break;
2390: case NUnit:
2391: return;
2392: case NVal:
2393: break;
2394: default:
2395: fprint(2, "can't progid node %n\n", n->t);
2396: return;
2397: }
2398: progid(n->l);
2399: progid(n->r);
2400: }
2401:
2402: #include "nodenames.h"
2403: #include "typenames.h"
2404: #include "errjmp.h"
2405: #include "node.h"
2406: #include "symbol.h"
2407: #include "ydefs.h"
2408: #include <libc.h>
2409:
2410: lerror(Node *n, char *s, a, b, c, d, e, f)
2411: {
2412: lfileline(n->line);
2413: fprint(2, s, a, b, c, d, e, f);
2414: if(s[strlen(s)-1]!='\n')
2415: fprint(2, "\n");
2416: errflush();
2417: errjmp();
2418: }
2419:
2420: error(char *s, a, b, c, d, e, f)
2421: {
2422: fileline();
2423: fprint(2, s, a, b, c, d, e, f);
2424: if(s[strlen(s)-1]!='\n')
2425: fprint(2, "\n");
2426: errflush();
2427: errjmp();
2428: }
2429:
2430: rerror(char *s, a, b, c, d, e, f)
2431: {
2432: fileline();
2433: fprint(2, s, a, b, c, d, e, f);
2434: fprint(2, "\n");
2435: processes(0);
2436: errflush();
2437: errjmp();
2438: }
2439:
2440: warn(char *s, a, b, c, d, e, f)
2441: {
2442: fileline();
2443: fprint(2, "warning: ");
2444: fprint(2, s, a, b, c, d, e, f);
2445: fprint(2, "\n");
2446: }
2447:
2448: panic(char *s, a, b, c, d, e, f)
2449: {
2450: fileline();
2451: fprint(2, "internal error: ");
2452: fprint(2, s, a, b, c, d, e, f);
2453: fprint(2, "\n");
2454: abort();
2455: }
2456:
2457: rpanic(char *s, a, b, c, d, e, f)
2458: {
2459: fileline();
2460: processes(0);
2461: fprint(2, "internal error: ");
2462: fprint(2, s, a, b, c, d, e, f);
2463: fprint(2, "\n");
2464: abort();
2465: }
2466:
2467: bconv(int *o, int f1, int f2)
2468: {
2469: extern int printcol;
2470: while(printcol<*o-8)
2471: strconv("\t", f1, f2);
2472: strconv(" "+(8-(*o-printcol)), f1, f2);
2473: return sizeof(int);
2474: }
2475:
2476: nconv(int *o, int f1, int f2)
2477: {
2478: if(*o<0 || sizeof(Ntypename)/sizeof(Ntypename[0])<=*o)
2479: strconv("mystery node", f1, f2);
2480: else
2481: strconv(Ntypename[*o], f1, f2);
2482: return sizeof(int);
2483: }
2484:
2485: tconv(int *o, int f1, int f2)
2486: {
2487: if(*o<0 || sizeof(Ttypename)/sizeof(Ttypename[0])<=*o)
2488: strconv("mystery type", f1, f2);
2489: else
2490: strconv(Ttypename[*o], f1, f2);
2491: return sizeof(int);
2492: }
2493:
2494: char bufx[128][10];
2495: int bufno=9;
2496:
2497: char *
2498: prbuf(){
2499: if(++bufno==10)
2500: bufno=0;
2501: return bufx[bufno];
2502: }
2503:
2504: econv(int *o, int f1, int f2)
2505: {
2506: char *buf=prbuf();
2507: char *x;
2508: int t=*o;
2509: if(t<128 && strchr("+-*/%|&^~?!><=", t))
2510: sprint(buf, "%c", t);
2511: else{
2512: switch(t){
2513: case GE:
2514: x=">=";
2515: break;
2516: case LE:
2517: x="<=";
2518: break;
2519: case NE:
2520: x="!=";
2521: break;
2522: case EQ:
2523: x="==";
2524: break;
2525: case ANDAND:
2526: x="&&";
2527: break;
2528: case OROR:
2529: x="||";
2530: break;
2531: case REF:
2532: x="ref";
2533: break;
2534: case LEN:
2535: x="len";
2536: break;
2537: case UMINUS:
2538: x="unary -";
2539: break;
2540: case RCV:
2541: x="rcv";
2542: break;
2543: case SND:
2544: x="send";
2545: break;
2546: case LSH:
2547: x="<<";
2548: break;
2549: case RSH:
2550: x=">>";
2551: break;
2552: case DEC:
2553: x="--";
2554: break;
2555: case INC:
2556: x="++";
2557: break;
2558: default:
2559: x="mystery expression";
2560: break;
2561: }
2562: strcpy(buf, x);
2563: }
2564: strconv(buf, f1, f2);
2565: return sizeof(int);
2566: }
2567:
2568: mconv(int *o, int f1, int f2)
2569: {
2570: char *buf=prbuf();
2571: Node *n=(Node *)*o;
2572: switch(n->t){
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.