|
|
1.1 root 1: /*
2: * n0/stat.c
3: * C compiler.
4: * Statement compilation.
5: * The routines in this file compile C statements.
6: * This file also contains a number of small routines that are
7: * only used by the statement compilation code.
8: * This is the new VAX/VMS base version.
9: */
10:
11: #ifdef vax
12: #include "INC$LIB:cc0.h"
13: #else
14: #include "cc0.h"
15: #endif
16:
17: /*
18: * Compile one statement.
19: * On entry, 's' contains the first symbol of the new statement.
20: * On exit, 's' contains the first token beyond the end of the statement.
21: */
22: statement()
23: {
24: register TREE *tp;
25: register int lab1, lab2;
26: TREE *lp, *rp;
27: TREE *itree, *ctree, *stree;
28: SBLOCK *ssbp;
29: int i, sclab, sblab, tt;
30: ival_t v;
31:
32: loop:
33: dbstat(s, line);
34: switch (s) {
35:
36: case EOF:
37: cerror("unexpected end of file");
38: break;
39:
40: case SEMI:
41: lex();
42: break;
43:
44: case LBRACE:
45: lex();
46: savelocals();
47: ++llex;
48: locals();
49: putautos();
50: while (s!=EOF && s!=RBRACE)
51: statement();
52: mustbe(RBRACE);
53: --llex;
54: downlex();
55: dbstat(RBRACE, line);
56: restlocals();
57: break;
58:
59: case BREAK:
60: lex();
61: if (cblab == 0)
62: cerror("break not in a loop");
63: jump(cblab);
64: mustbe(SEMI);
65: break;
66:
67: case CONTINUE:
68: lex();
69: if (cclab == 0)
70: cerror("continue not in a loop");
71: jump(cclab);
72: mustbe(SEMI);
73: break;
74:
75: case CASE:
76: lex();
77: newtree(sizeof(TREE));
78: ++incase;
79: v = iconexpr();
80: --incase;
81: mustbe(COLON);
82: if (sbp == NULL)
83: cerror("case not in a switch");
84: else
85: newcase(v);
86: goto loop;
87:
88: case DEFAULT:
89: lex();
90: mustbe(COLON);
91: if (sbp == NULL)
92: cerror("default label not in a switch");
93: else {
94: if (sbp->sb_dlab != 0)
95: cerror("only one default label allowed");
96: sbp->sb_dlab = here();
97: }
98: goto loop;
99:
100: case GOTO:
101: lex();
102: if (s != ID) {
103: cerror("missing label name in goto");
104: skip();
105: } else {
106: dogoto();
107: lex();
108: mustbe(SEMI);
109: }
110: break;
111:
112: case IF:
113: lex();
114: tp = pexpr();
115: truth(tp);
116: tput(FEXPR, lab1=newlab(), tp);
117: statement();
118: if (s == ELSE) {
119: lab2 = newlab();
120: jump(lab2);
121: label(lab1);
122: lex();
123: statement();
124: label(lab2);
125: break;
126: }
127: label(lab1);
128: break;
129:
130: case DO:
131: sblab = cblab;
132: sclab = cclab;
133: cblab = newlab();
134: cclab = newlab();
135: lab1 = here();
136: lex();
137: statement();
138: label(cclab);
139: dbstat(s, line);
140: mustbe(WHILE);
141: tp = pexpr();
142: truth(tp);
143: tput(TEXPR, lab1, tp);
144: label(cblab);
145: mustbe(SEMI);
146: cclab = sclab;
147: cblab = sblab;
148: break;
149:
150: case WHILE:
151: sblab = cblab;
152: sclab = cclab;
153: cblab = newlab();
154: cclab = here();
155: lex();
156: tp = pexpr();
157: truth(tp);
158: tput(FEXPR, cblab, tp);
159: statement();
160: jump(cclab);
161: label(cblab);
162: cclab = sclab;
163: cblab = sblab;
164: break;
165:
166: case SWITCH:
167: lex();
168: tp = pexpr();
169: tt = tltype(tp);
170: if ((tt == T_LONG && mytypes[T_INT] == mytypes[T_LONG])
171: || (tt == T_ULONG && mytypes[T_UINT] == mytypes[T_ULONG])) {
172: if (isvariant(VSBOOK))
173: cstrict("switch expression is long");
174: } else if (tt > T_UINT)
175: cerror("switch of non integer");
176: if (tt != T_INT) {
177: rp = NULL;
178: if (tt == T_PTR)
179: rp = bzcon(psize(tp));
180: tp = bconvert(tp, T_INT, NULL, NULL, rp);
181: }
182: tput(SEXPR, 0, tp);
183: ssbp = sbp;
184: sbp = (SBLOCK *) new(sizeof(SBLOCK));
185: sbp->sb_dlab = 0;
186: sbp->sb_ncase = 0;
187: sblab = cblab;
188: cblab = newlab();
189: statement();
190: jump(cblab);
191: if (sbp->sb_dlab==0 && sbp->sb_ncase==0)
192: cwarn("empty switch");
193: if (sbp->sb_dlab == 0)
194: sbp->sb_dlab = cblab;
195: bput(SBODY);
196: iput((ival_t) sbp->sb_dlab);
197: iput((ival_t) sbp->sb_ncase);
198: for (i=0; i<sbp->sb_ncase; ++i) {
199: iput((ival_t) sbp->sb_case[i].sc_val);
200: iput((ival_t) sbp->sb_case[i].sc_lab);
201: }
202: label(cblab);
203: cblab = sblab;
204: free((char *) sbp);
205: sbp = ssbp;
206: break;
207:
208: case FOR:
209: lex();
210: mustbe(LPAREN);
211: newtree(sizeof(TREE));
212: itree = NULL;
213: if (s != SEMI)
214: itree = expr();
215: mustbe(SEMI);
216: ctree = NULL;
217: if (s != SEMI) {
218: ctree = expr();
219: truth(ctree);
220: }
221: mustbe(SEMI);
222: stree = NULL;
223: if (s != RPAREN)
224: stree = expr();
225: mustbe(RPAREN);
226: sblab = cblab;
227: sclab = cclab;
228: cblab = newlab();
229: cclab = newlab();
230: if (itree != NULL) {
231: tput(EEXPR, 0, itree);
232: }
233: if (stree != NULL)
234: jump(lab1 = newlab());
235: label(cclab);
236: if (stree != NULL) {
237: tput(EEXPR, 0, stree);
238: label(lab1);
239: }
240: if (ctree != NULL) {
241: tput(FEXPR, cblab, ctree);
242: }
243: statement();
244: jump(cclab);
245: label(cblab);
246: cclab = sclab;
247: cblab = sblab;
248: break;
249:
250: case RETURN:
251: lex();
252: if (s != SEMI) {
253: newtree(sizeof(TREE));
254: tp = expr();
255: if (cfsym==NULL) {
256: cerror("return(e) not inside valid function");
257: mustbe(SEMI);
258: break;
259: }
260: lp = talloc();
261: lp->t_op = CONVERT;
262: lp->t_type = cfsym->s_type;
263: lp->t_dp = cfsym->s_dp->d_dp; /* Skip D_FUNC */
264: lp->t_ip = cfsym->s_ip;
265: if (lp->t_dp==NULL && lp->t_type==T_VOID) {
266: cerror("return(e) illegal in void function");
267: mustbe(SEMI);
268: break;
269: }
270: if ((tltype(lp)==T_STRUCT || tltype(tp)==T_STRUCT)
271: && (lp->t_type!=tp->t_type||lp->t_dp!=tp->t_dp||lp->t_ip!=tp->t_ip)) {
272: cerror("return type/function type mismatch");
273: mustbe(SEMI);
274: break;
275: }
276: if (bitcompat(tltype(lp), tltype(tp)))
277: adjust(tp, lp->t_type, lp->t_dp, lp->t_ip);
278: else {
279: lp->t_lp = tp;
280: tp = lp;
281: }
282: tput(REXPR, 0, tp);
283: }
284: jump(cflab);
285: mustbe(SEMI);
286: break;
287:
288: case ID:
289: if (spnextis(':')) {
290: dolabel();
291: lex();
292: lex();
293: goto loop;
294: }
295:
296: default:
297: newtree(sizeof(TREE));
298: tp = expr();
299: tput(EEXPR, 0, tp);
300: mustbe(SEMI);
301: }
302: }
303:
304: /*
305: * Check if the given tree can be used in a truth value context.
306: * Put out the appropriate diagnostics.
307: * What does this have to do with stat()?
308: */
309: truth(tp)
310: TREE *tp;
311: {
312: register int tt, op;
313:
314: tt = tltype(tp);
315: op = tp->t_op;
316: if (tt>=T_STRUCT && tt<=T_FUNION)
317: cerror("structure or union used in truth context");
318: if (incpp)
319: return;
320: if (isvariant(VSRTVC)) {
321: if ((tt>=T_PTR && tt<=T_DOUBLE)
322: || (op==EQ && tp->t_lp->t_type==T_DOUBLE))
323: cstrict("risky type in truth context");
324: }
325: if (isvariant(VSCCON)) {
326: /* Catch typing error "if (i = 1) ..." for "if (i == 1)...". */
327: while (op == ASSIGN) {
328: tp = tp->t_rp;
329: op = tp->t_op;
330: }
331: if (op==ICON || op==LCON || op==DCON)
332: cstrict("constant used in truth context");
333: }
334: }
335:
336: /*
337: * Read an expression enclosed in parentheses.
338: * Used to read the control expressions in 'if', 'do', 'while' and 'switch'.
339: */
340: TREE *
341: pexpr()
342: {
343: register TREE *tp;
344:
345: mustbe(LPAREN);
346: newtree(sizeof(TREE));
347: tp = expr();
348: mustbe(RPAREN);
349: return (tp);
350: }
351:
352: /*
353: * Labels.
354: */
355: dolabel()
356: {
357: register SYM *sp;
358: register int c;
359:
360: sp = deflookup(SL_LAB, 2);
361: c = sp->s_class;
362: if (c==C_NONE || c==C_FREF) {
363: if (c == C_NONE)
364: sp->s_value = newlab();
365: sp->s_class = C_LAB;
366: sp->s_dline = line;
367: label(sp->s_value);
368: dblabel(sp);
369: } else
370: cerror("illegal label \"%s\"", sp->s_id);
371: }
372:
373: /*
374: * The dreaded 'goto' statement.
375: */
376: dogoto()
377: {
378: register SYM *sp;
379: register int c;
380:
381: sp = deflookup(SL_LAB, 2);
382: c = sp->s_class;
383: if (c == C_NONE) {
384: sp->s_class = C_FREF;
385: sp->s_value = newlab();
386: } else if (c!=C_LAB && c!=C_FREF)
387: cerror("identifier \"%s\" is not a label", sp->s_id);
388: jump(sp->s_value);
389: sp->s_flag |= S_USED;
390: }
391:
392: /*
393: * Append a new case to the current switch,
394: * adjusting the size of the switch block if necessary and possible.
395: */
396: newcase(v)
397: ival_t v;
398: {
399: SBLOCK *ssbp;
400: register SCASE *scp, *ocp;
401: register int i;
402:
403: i = sbp->sb_ncase;
404: scp = sbp->sb_case;
405: while (--i >= 0) {
406: if (scp->sc_val == v) {
407: cerror("duplicated case constant");
408: return;
409: } else
410: scp += 1;
411: }
412: i = sbp->sb_ncase;
413: scp = &sbp->sb_case[i];
414: if ((i % 32) == 0) {
415: ssbp = sbp;
416: sbp = new(sizeof(SBLOCK) + (i+32) * sizeof(SCASE));
417: sbp->sb_ncase = ssbp->sb_ncase;
418: sbp->sb_dlab = ssbp->sb_dlab;
419: scp = sbp->sb_case;
420: ocp = ssbp->sb_case;
421: while (--i >= 0) {
422: scp->sc_val = ocp->sc_val;
423: scp->sc_lab = ocp->sc_lab;
424: scp += 1;
425: ocp += 1;
426: }
427: free((char *) ssbp);
428: scp = &sbp->sb_case[sbp->sb_ncase];
429: }
430: scp->sc_val = v;
431: scp->sc_lab = here();
432: sbp->sb_ncase += 1;
433: }
434:
435: /* end of n0/stat.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.