|
|
1.1 root 1: /*
2: * C compiler
3: */
4:
5: #include "c0.h"
6:
7: /*
8: * Process a single external definition
9: */
10: extdef()
11: {
12: register o;
13: int sclass, scflag;
14: struct nmlist typer;
15: register struct nmlist *ds;
16:
17: if(((o=symbol())==EOFC) || o==SEMI)
18: return;
19: peeksym = o;
20: sclass = 0;
21: blklev = 0;
22: if (getkeywords(&sclass, &typer)==0) {
23: sclass = EXTERN;
24: if (peeksym!=NAME)
25: goto syntax;
26: }
27: scflag = 0;
28: if (sclass==DEFXTRN) {
29: scflag++;
30: sclass = EXTERN;
31: }
32: if (sclass!=EXTERN && sclass!=STATIC && sclass!=TYPEDEF)
33: error("Illegal storage class");
34: do {
35: defsym = 0;
36: paraml = NULL;
37: parame = NULL;
38: if (sclass==TYPEDEF) {
39: decl1(TYPEDEF, &typer, 0, (struct nmlist *)NULL);
40: continue;
41: }
42: decl1(EXTERN, &typer, 0, (struct nmlist *)NULL);
43: if ((ds=defsym)==0)
44: return;
45: funcsym = ds;
46: if ((ds->htype&XTYPE)==FUNC) {
47: if ((peeksym=symbol())==LBRACE || peeksym==KEYW
48: || (peeksym==NAME && csym->hclass==TYPEDEF)) {
49: funcblk.type = decref(ds->htype);
50: funcblk.strp = ds->hstrp;
51: setinit(ds);
52: outcode("BS", SYMDEF, sclass==EXTERN?ds->name:"");
53: cfunc();
54: return;
55: }
56: if (paraml)
57: error("Inappropriate parameters");
58: } else if ((o=symbol())==COMMA || o==SEMI) {
59: peeksym = o;
60: o = (length((union tree *)ds)+ALIGN) & ~ALIGN;
61: if (sclass==STATIC) {
62: setinit(ds);
63: outcode("BSBBSBN", SYMDEF, "", BSS, NLABEL, ds->name, SSPACE, o);
64: } else if (scflag)
65: outcode("BSN", CSPACE, ds->name, o);
66: } else {
67: if (o!=ASSIGN) {
68: error("Declaration syntax");
69: peeksym = o;
70: }
71: setinit(ds);
72: if (sclass==EXTERN)
73: outcode("BS", SYMDEF, ds->name);
74: outcode("BBS", DATA, NLABEL, ds->name);
75: if (cinit(ds, 1, sclass) & ALIGN)
76: outcode("B", EVEN);
77: }
78: } while ((o=symbol())==COMMA);
79: if (o==SEMI)
80: return;
81: syntax:
82: if (o==RBRACE) {
83: error("Too many }'s");
84: peeksym = 0;
85: return;
86: }
87: error("External definition syntax");
88: errflush(o);
89: statement();
90: }
91:
92: /*
93: * Process a function definition.
94: */
95: cfunc()
96: {
97: register char *cb;
98: register sloc;
99:
100: sloc = isn;
101: isn += 2;
102: outcode("BBS", PROG, RLABEL, funcsym->name);
103: if (proflg)
104: outcode("BN", PROFIL, isn++);
105: regvar = 5;
106: autolen = STAUTO;
107: maxauto = STAUTO;
108: blklev = 1;
109: cb = locbase;
110: declist(ARG);
111: outcode("B", SAVE);
112: funchead();
113: branch(sloc);
114: label(sloc+1);
115: retlab = isn++;
116: blklev = 0;
117: if ((peeksym = symbol()) != LBRACE)
118: error("Compound statement required");
119: statement();
120: outcode("BNB", LABEL, retlab, RETRN);
121: label(sloc);
122: outcode("BN", SETSTK, -maxauto);
123: branch(sloc+1);
124: locbase = cb;
125: }
126:
127: /*
128: * Process the initializers for an external definition.
129: */
130: cinit(anp, flex, sclass)
131: struct nmlist *anp;
132: {
133: struct nmlist np;
134: register nel, ninit;
135: int width, isarray, o, brace, realtype;
136: union tree *s;
137:
138: np = *anp;
139: realtype = np.htype;
140: isarray = 0;
141: if ((realtype&XTYPE) == ARRAY)
142: isarray++;
143: else
144: flex = 0;
145: width = length((union tree *)&np);
146: nel = 1;
147: /*
148: * If it's an array, find the number of elements.
149: * temporarily modify to look like kind of thing it's
150: * an array of.
151: */
152: if (sclass==AUTO)
153: if (isarray || realtype==STRUCT)
154: error("No auto. aggregate initialization");
155: if (isarray) {
156: np.htype = decref(realtype);
157: np.hsubsp++;
158: if (width==0 && flex==0)
159: error("0-length row: %.8s", anp->name);
160: o = length((union tree *)&np);
161: nel = (unsigned)width/o;
162: width = o;
163: }
164: brace = 0;
165: if ((peeksym=symbol())==LBRACE && (isarray || np.htype!=STRUCT)) {
166: peeksym = -1;
167: brace++;
168: }
169: ninit = 0;
170: do {
171: if ((o=symbol())==RBRACE)
172: break;
173: peeksym = o;
174: if (o==STRING && (realtype==ARRAY+CHAR || realtype==ARRAY+UNCHAR)) {
175: if (sclass==AUTO)
176: error("No strings in automatic");
177: peeksym = -1;
178: putstr(0, flex?10000:nel);
179: ninit += nchstr;
180: o = symbol();
181: break;
182: } else if (np.htype==STRUCT) {
183: strinit(&np, sclass);
184: } else if ((np.htype&ARRAY)==ARRAY || peeksym==LBRACE)
185: cinit(&np, 0, sclass);
186: else {
187: char *st;
188: initflg++;
189: st = starttree();
190: s = tree(0);
191: initflg = 0;
192: if (np.hflag&FFIELD)
193: error("No field initialization");
194: *cp++ = nblock(&np);
195: *cp++ = s;
196: build(ASSIGN);
197: if (sclass==AUTO||sclass==REG)
198: rcexpr(*--cp);
199: else if (sclass==ENUMCON) {
200: if (s->t.op!=CON)
201: error("Illegal enum constant for %.8s", anp->name);
202: anp->hoffset = s->c.value;
203: } else
204: rcexpr(block(INIT,np.htype,(int *)NULL,
205: (union str *)NULL, (*--cp)->t.tr2, TNULL));
206: endtree(st);
207: }
208: ninit++;
209: if ((ninit&077)==0 && sclass==EXTERN)
210: outcode("BS", SYMDEF, "");
211: } while ((o=symbol())==COMMA && (ninit<nel || brace || flex));
212: if (brace==0 || o!=RBRACE)
213: peeksym = o;
214: /*
215: * If there are too few initializers, allocate
216: * more storage.
217: * If there are too many initializers, extend
218: * the declared size for benefit of "sizeof"
219: */
220: if (ninit<nel && sclass!=AUTO)
221: outcode("BN", SSPACE, (nel-ninit)*width);
222: else if (ninit>nel) {
223: if (flex && nel==0) {
224: np.hsubsp[-1] = ninit;
225: } else
226: error("Too many initializers: %.8s", anp->name);
227: nel = ninit;
228: }
229: return(nel*width);
230: }
231:
232: /*
233: * Initialize a structure
234: */
235: strinit(np, sclass)
236: struct nmlist *np;
237: {
238: static struct nmlist junk;
239: register struct nmlist **mlp;
240: static struct nmlist *zerloc = NULL;
241: register int o, brace;
242:
243: if ((mlp = np->hstrp->S.memlist)==NULL) {
244: mlp = &zerloc;
245: error("Undefined structure initialization");
246: }
247: brace = 0;
248: if ((o = symbol()) == LBRACE)
249: brace++;
250: else
251: peeksym = o;
252: do {
253: if ((o=symbol()) == RBRACE)
254: break;
255: peeksym = o;
256: if (*mlp==0) {
257: error("Too many structure initializers");
258: cinit(&junk, 0, sclass);
259: } else
260: cinit(*mlp++, 0, sclass);
261: if (*mlp == &structhole) {
262: outcode("B", EVEN);
263: mlp++;
264: }
265: } while ((o=symbol())==COMMA && (*mlp || brace));
266: if (sclass!=AUTO && sclass!=REG) {
267: if (*mlp)
268: outcode("BN", SSPACE, np->hstrp->S.ssize - (*mlp)->hoffset);
269: outcode("B", EVEN);
270: }
271: if (o!=RBRACE || brace==0)
272: peeksym = o;
273: }
274:
275: /*
276: * Mark already initialized
277: */
278: setinit(np)
279: register struct nmlist *np;
280: {
281:
282: if (np->hflag&FINIT)
283: error("%s multiply defined", np->name);
284: np->hflag |= FINIT;
285: }
286:
287: /*
288: * Process one statement in a function.
289: */
290: statement()
291: {
292: register o, o1;
293: int sauto, sreg;
294:
295: stmt:
296: switch(o=symbol()) {
297:
298: case EOFC:
299: error("Unexpected EOF");
300: case SEMI:
301: return;
302:
303: case LBRACE:
304: sauto = autolen;
305: sreg = regvar;
306: blockhead();
307: while (!eof) {
308: if ((o=symbol())==RBRACE) {
309: autolen = sauto;
310: if (sreg!=regvar)
311: outcode("BN", SETREG, sreg);
312: regvar = sreg;
313: blkend();
314: return;
315: }
316: peeksym = o;
317: statement();
318: }
319: error("Missing '}'");
320: return;
321:
322: case KEYW:
323: switch(cval) {
324:
325: case GOTO:
326: if (o1 = simplegoto())
327: branch(o1);
328: else
329: dogoto();
330: goto semi;
331:
332: case RETURN:
333: doret();
334: goto semi;
335:
336: case IF: {
337: register o2;
338: register union tree *np;
339:
340: np = pexpr(1);
341: o2 = 0;
342: if ((o1=symbol())==KEYW) switch (cval) {
343: case GOTO:
344: if (o2=simplegoto())
345: goto simpif;
346: cbranch(np, o2=isn++, 0);
347: dogoto();
348: label(o2);
349: goto hardif;
350:
351: case RETURN:
352: if (nextchar()==';') {
353: o2 = retlab;
354: goto simpif;
355: }
356: cbranch(np, o1=isn++, 0);
357: doret();
358: label(o1);
359: o2++;
360: goto hardif;
361:
362: case BREAK:
363: o2 = brklab;
364: goto simpif;
365:
366: case CONTIN:
367: o2 = contlab;
368: simpif:
369: chconbrk(o2);
370: cbranch(np, o2, 1);
371: hardif:
372: if ((o=symbol())!=SEMI)
373: goto syntax;
374: if ((o1=symbol())==KEYW && cval==ELSE)
375: goto stmt;
376: peeksym = o1;
377: return;
378: }
379: peeksym = o1;
380: cbranch(np, o1=isn++, 0);
381: statement();
382: if ((o=symbol())==KEYW && cval==ELSE) {
383: o2 = isn++;
384: branch(o2);
385: label(o1);
386: statement();
387: label(o2);
388: return;
389: }
390: peeksym = o;
391: label(o1);
392: return;
393: }
394:
395: case WHILE: {
396: register o2;
397: o1 = contlab;
398: o2 = brklab;
399: label(contlab = isn++);
400: cbranch(pexpr(1), brklab=isn++, 0);
401: statement();
402: branch(contlab);
403: label(brklab);
404: contlab = o1;
405: brklab = o2;
406: return;
407: }
408:
409: case BREAK:
410: chconbrk(brklab);
411: branch(brklab);
412: goto semi;
413:
414: case CONTIN:
415: chconbrk(contlab);
416: branch(contlab);
417: goto semi;
418:
419: case DO: {
420: register int o2, o3;
421: o1 = contlab;
422: o2 = brklab;
423: contlab = isn++;
424: brklab = isn++;
425: label(o3 = isn++);
426: statement();
427: label(contlab);
428: contlab = o1;
429: if ((o=symbol())==KEYW && cval==WHILE) {
430: cbranch(tree(1), o3, 1);
431: label(brklab);
432: brklab = o2;
433: goto semi;
434: }
435: goto syntax;
436: }
437:
438: case CASE:
439: o1 = conexp();
440: if ((o=symbol())!=COLON)
441: goto syntax;
442: if (swp==0) {
443: error("Case not in switch");
444: goto stmt;
445: }
446: if(swp>=swtab+SWSIZ) {
447: error("Switch table overflow");
448: } else {
449: swp->swlab = isn;
450: (swp++)->swval = o1;
451: label(isn++);
452: }
453: goto stmt;
454:
455: case SWITCH: {
456: register union tree *np;
457: register char *st;
458:
459: o1 = brklab;
460: brklab = isn++;
461: st = starttree();
462: np = pexpr(0);
463: chkw(np, -1);
464: rcexpr(block(RFORCE,0,(int *)NULL,(union str *)NULL,np,TNULL));
465: endtree(st);
466: pswitch();
467: brklab = o1;
468: return;
469: }
470:
471: case DEFAULT:
472: if (swp==0)
473: error("Default not in switch");
474: if (deflab)
475: error("More than 1 'default'");
476: if ((o=symbol())!=COLON)
477: goto syntax;
478: label(deflab = isn++);
479: goto stmt;
480:
481: case FOR: {
482: register int o2;
483: o1 = contlab;
484: o2 = brklab;
485: contlab = isn++;
486: brklab = isn++;
487: if (o=forstmt())
488: goto syntax;
489: contlab = o1;
490: brklab = o2;
491: return;
492: }
493:
494: case ELSE:
495: error("Inappropriate 'else'");
496: statement();
497: return;
498: }
499: error("Unknown keyword");
500: goto syntax;
501:
502: case NAME: {
503: register struct nmlist *np;
504: if (nextchar()==':') {
505: peekc = 0;
506: np = csym;
507: if (np->hclass>0) {
508: if (np->hblklev==0) {
509: np = pushdecl(np);
510: np->hoffset = 0;
511: } else {
512: defsym = np;
513: redec();
514: goto stmt;
515: }
516: }
517: np->hclass = STATIC;
518: np->htype = ARRAY;
519: np->hflag |= FLABL;
520: if (np->hoffset==0)
521: np->hoffset = isn++;
522: label(np->hoffset);
523: goto stmt;
524: }
525: }
526: }
527: peeksym = o;
528: rcexpr(tree(1));
529:
530: semi:
531: if ((o=symbol())==SEMI)
532: return;
533: syntax:
534: error("Statement syntax");
535: errflush(o);
536: }
537:
538: /*
539: * Process a for statement.
540: */
541: forstmt()
542: {
543: register int o;
544: register union tree *st;
545: register l;
546: char *ss;
547:
548: if ((o=symbol()) != LPARN)
549: return(o);
550: if ((o=symbol()) != SEMI) { /* init part */
551: peeksym = o;
552: rcexpr(tree(1));
553: if ((o=symbol()) != SEMI)
554: return(o);
555: }
556: l = isn;
557: isn += 3;
558: branch(l+0);
559: label(l+1);
560: branch(l+2);
561: label(contlab);
562: st = NULL;
563: if ((o=symbol()) != SEMI) { /* test part */
564: peeksym = o;
565: ss = starttree();
566: st = tree(0);
567: if ((o=symbol()) != SEMI) {
568: endtree(ss);
569: return(o);
570: }
571: }
572: if ((o=symbol()) != RPARN) { /* incr part */
573: peeksym = o;
574: rcexpr(tree(1));
575: if ((o=symbol()) != RPARN) {
576: if (st)
577: endtree(ss);
578: return(o);
579: }
580: }
581: label(l+0);
582: if (st) {
583: cbranch(st, l+1, 1);
584: endtree(ss);
585: } else
586: branch(l+1);
587: branch(brklab);
588: label(l+2);
589: statement();
590: branch(contlab);
591: label(brklab);
592: return(0);
593: }
594:
595: /*
596: * A parenthesized expression,
597: * as after "if".
598: */
599: union tree *
600: pexpr(eflag)
601: {
602: register o;
603: register union tree *t;
604:
605: if ((o=symbol())!=LPARN)
606: goto syntax;
607: t = tree(eflag);
608: if ((o=symbol())!=RPARN)
609: goto syntax;
610: if (t->t.type==VOID)
611: error("Illegal use of void");
612: return(t);
613: syntax:
614: error("Statement syntax");
615: errflush(o);
616: return(0);
617: }
618:
619: /*
620: * The switch statement, which involves collecting the
621: * constants and labels for the cases.
622: */
623: pswitch()
624: {
625: register struct swtab *cswp, *sswp;
626: int dl, swlab;
627:
628: cswp = sswp = swp;
629: if (swp==0)
630: cswp = swp = swtab;
631: branch(swlab=isn++);
632: dl = deflab;
633: deflab = 0;
634: statement();
635: branch(brklab);
636: label(swlab);
637: if (deflab==0)
638: deflab = brklab;
639: outcode("BNN", SWIT, deflab, line);
640: for (; cswp < swp; cswp++)
641: outcode("NN", cswp->swlab, cswp->swval);
642: outcode("0");
643: label(brklab);
644: deflab = dl;
645: swp = sswp;
646: }
647:
648: /*
649: * funchead is called at the start of each function
650: * to process the arguments, which have been linked in a list.
651: * This list is necessary because in
652: * f(a, b) float b; int a; ...
653: * the names are seen before the types.
654: */
655: /*
656: * Structure resembling a block for a register variable.
657: */
658: struct nmlist hreg = { REG, 0, 0, NULL, NULL, 0 };
659: struct tnode areg = { NAME, 0, NULL, NULL, (union tree *)&hreg};
660: funchead()
661: {
662: register pl;
663: register struct nmlist *cs;
664: register char *st;
665:
666: pl = STARG;
667: while(paraml) {
668: parame->sparent = NULL;
669: cs = paraml;
670: paraml = ¶ml->sparent->P;
671: if (cs->htype==FLOAT)
672: cs->htype = DOUBLE;
673: cs->hoffset = pl;
674: if ((cs->htype&XTYPE) == ARRAY) {
675: cs->htype -= (ARRAY-PTR); /* set ptr */
676: cs->hsubsp++; /* pop dims */
677: }
678: pl += rlength((union tree *)cs);
679: if (cs->hclass==AREG && (hreg.hoffset=goodreg(cs))>=0) {
680: st = starttree();
681: *cp++ = (union tree *)&areg;
682: *cp++ = nblock(cs);
683: areg.type = cs->htype;
684: areg.strp = cs->hstrp;
685: cs->hclass = AUTO;
686: build(ASSIGN);
687: rcexpr(*--cp);
688: cs->hoffset = hreg.hoffset;
689: cs->hclass = REG;
690: endtree(st);
691: } else
692: cs->hclass = AUTO;
693: prste(cs);
694: }
695: for (pl=0; pl<HSHSIZ; pl++) {
696: for (cs = hshtab[pl]; cs!=NULL; cs = cs->nextnm) {
697: if (cs->hclass == ARG || cs->hclass==AREG)
698: error("Not an argument: %.8s", cs->name);
699: }
700: }
701: outcode("BN", SETREG, regvar);
702: }
703:
704: blockhead()
705: {
706: register r;
707:
708: r = regvar;
709: blklev++;
710: declist(0);
711: if (r != regvar)
712: outcode("BN", SETREG, regvar);
713: }
714:
715: /*
716: * After the end of a block, delete local
717: * symbols;
718: * Also complain about undefined labels.
719: */
720: blkend()
721: {
722: register struct nmlist *cs, **lcs;
723: register i;
724: int nnames;
725:
726: blklev--;
727: nnames = 0;
728: for (i=0; i<HSHSIZ; i++) {
729: lcs = &hshtab[i];
730: cs = *lcs;
731: while (cs) {
732: if (cs->hblklev > blklev
733: && (((cs->hflag&FLABL)==0 && cs->hclass!=EXTERN) || blklev<=0)) {
734: if (cs->hclass==0)
735: error("%.8s undefined", cs->name);
736: if (cs->hclass==EXTERN)
737: nameconflict(hshtab[i], cs);
738: *lcs = cs->nextnm;
739: } else {
740: lcs = &cs->nextnm;
741: nnames++;
742: }
743: cs = cs->nextnm;
744: }
745: }
746: }
747:
748: nameconflict(ocs, cs)
749: register struct nmlist *ocs, *cs;
750: {
751:
752: for (; ocs!=NULL; ocs = ocs->nextnm)
753: if (ocs!=cs && ocs->hclass==EXTERN && strncmp(cs->name, ocs->name, 7) == 0)
754: error("names %.8s and %.8s conflict", cs->name, ocs->name);
755: }
756:
757: /*
758: * write out special definitions of local symbols for
759: * benefit of the debugger. None of these are used
760: * by the assembler except to save them.
761: */
762: prste(cs)
763: struct nmlist *cs;
764: {
765: register nkind;
766:
767: switch (cs->hclass) {
768: case REG:
769: nkind = RNAME;
770: break;
771:
772: case AUTO:
773: nkind = ANAME;
774: break;
775:
776: case STATIC:
777: nkind = SNAME;
778: break;
779:
780: default:
781: return;
782:
783: }
784: outcode("BSN", nkind, cs->name, cs->hoffset);
785: }
786:
787: /*
788: * In case of error, skip to the next
789: * statement delimiter.
790: */
791: errflush(ao)
792: {
793: register o;
794:
795: o = ao;
796: while(o>RBRACE) { /* ; { } */
797: if (o==STRING)
798: putstr(0, 0);
799: o = symbol();
800: }
801: peeksym = o;
802: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.