stmt.c (6933B)
1 static char sccsid[] = "@(#) ./cc1/stmt.c"; 2 #include <stddef.h> 3 #include <setjmp.h> 4 5 #include <cstd.h> 6 #include "../inc/scc.h" 7 #include "cc1.h" 8 9 #define NEGATE 1 10 #define NONEGATE 0 11 12 Symbol *curfun; 13 14 static void stmt(Symbol *lbreak, Symbol *lcont, Switch *lswitch); 15 16 static void 17 label(void) 18 { 19 Symbol *sym; 20 21 switch (yytoken) { 22 case IDEN: 23 case TYPEIDEN: 24 sym = lookup(NS_LABEL, yytext, ALLOC); 25 if (sym->flags & SDEFINED) 26 error("label '%s' already defined", yytext); 27 if ((sym->flags & SDECLARED) == 0) 28 sym = install(NS_LABEL, sym); 29 sym->flags |= SDEFINED; 30 emit(OLABEL, sym); 31 next(); 32 expect(':'); 33 break; 34 default: 35 unexpected(); 36 } 37 } 38 39 static void 40 stmtexp(Symbol *lbreak, Symbol *lcont, Switch *lswitch) 41 { 42 Node *np; 43 44 if (accept(';')) 45 return; 46 if (yytoken == IDEN && ahead() == ':') { 47 label(); 48 stmt(lbreak, lcont, lswitch); 49 return; 50 } 51 np = expr(); 52 if ((np->flags & NEFFECT) == 0) 53 warn("expression without side effects"); 54 emit(OEXPR, np); 55 expect(';'); 56 } 57 58 static Node * 59 condition(int neg) 60 { 61 Node *np; 62 63 expect('('); 64 np = condexpr(neg); 65 expect(')'); 66 67 return np; 68 } 69 70 static void 71 While(Symbol *lbreak, Symbol *lcont, Switch *lswitch) 72 { 73 Symbol *begin; 74 Node *np; 75 76 begin = newlabel(); 77 lcont = newlabel(); 78 lbreak = newlabel(); 79 80 expect(WHILE); 81 np = condition(NONEGATE); 82 83 emit(OJUMP, lcont); 84 85 emit(OBLOOP, NULL); 86 emit(OLABEL, begin); 87 stmt(lbreak, lcont, lswitch); 88 emit(OLABEL, lcont); 89 emit(OBRANCH, begin); 90 emit(OEXPR, np); 91 emit(OELOOP, NULL); 92 93 emit(OLABEL, lbreak); 94 } 95 96 static void 97 For(Symbol *lbreak, Symbol *lcont, Switch *lswitch) 98 { 99 Symbol *begin, *cond; 100 Node *econd, *einc; 101 102 begin = newlabel(); 103 lcont = newlabel(); 104 cond = newlabel(); 105 lbreak = newlabel(); 106 107 pushctx(); 108 109 expect(FOR); 110 expect('('); 111 switch (yytoken) { 112 case TYPE: 113 case TYPEIDEN: 114 case TQUALIFIER: 115 case SCLASS: 116 decl(); 117 break; 118 default: 119 emit(OEXPR, expr()); 120 case ';': 121 expect(';'); 122 break; 123 } 124 econd = (yytoken != ';') ? condexpr(NONEGATE) : NULL; 125 expect(';'); 126 einc = (yytoken != ')') ? expr() : NULL; 127 expect(')'); 128 129 emit(OJUMP, cond); 130 131 emit(OBLOOP, NULL); 132 emit(OLABEL, begin); 133 stmt(lbreak, lcont, lswitch); 134 emit(OLABEL, lcont); 135 emit(OEXPR, einc); 136 emit(OLABEL, cond); 137 emit((econd) ? OBRANCH : OJUMP, begin); 138 emit(OEXPR, econd); 139 emit(OELOOP, NULL); 140 141 emit(OLABEL, lbreak); 142 143 popctx(); 144 } 145 146 static void 147 Dowhile(Symbol *lbreak, Symbol *lcont, Switch *lswitch) 148 { 149 Symbol *begin; 150 Node *np; 151 152 begin = newlabel(); 153 lcont = newlabel(); 154 lbreak = newlabel(); 155 156 expect(DO); 157 158 emit(OBLOOP, NULL); 159 emit(OLABEL, begin); 160 stmt(lbreak, lcont, lswitch); 161 expect(WHILE); 162 np = condition(NONEGATE); 163 emit(OLABEL, lcont); 164 emit(OBRANCH, begin); 165 emit(OEXPR, np); 166 emit(OELOOP, NULL); 167 168 emit(OLABEL, lbreak); 169 } 170 171 static void 172 Return(Symbol *lbreak, Symbol *lcont, Switch *lswitch) 173 { 174 Node *np; 175 Type *tp = curfun->type->type; 176 177 expect(RETURN); 178 np = (yytoken != ';') ? decay(expr()) : NULL; 179 expect(';'); 180 if (!np) { 181 if (tp != voidtype) 182 warn("function returning non void returns no value"); 183 tp = voidtype; 184 } else if (np->type != tp) { 185 if (tp == voidtype) 186 warn("function returning void returns a value"); 187 else if ((np = convert(np, tp, 0)) == NULL) 188 errorp("incorrect type in return"); 189 } 190 emit(ORET, NULL); 191 emit(OEXPR, np); 192 } 193 194 static void 195 Break(Symbol *lbreak, Symbol *lcont, Switch *lswitch) 196 { 197 expect(BREAK); 198 if (!lbreak) { 199 errorp("break statement not within loop or switch"); 200 } else { 201 emit(OJUMP, lbreak); 202 expect(';'); 203 } 204 } 205 206 static void 207 Continue(Symbol *lbreak, Symbol *lcont, Switch *lswitch) 208 { 209 expect(CONTINUE); 210 if (!lcont) { 211 errorp("continue statement not within loop"); 212 } else { 213 emit(OJUMP, lcont); 214 expect(';'); 215 } 216 } 217 218 static void 219 Goto(Symbol *lbreak, Symbol *lcont, Switch *lswitch) 220 { 221 Symbol *sym; 222 223 namespace = NS_LABEL; 224 next(); 225 namespace = NS_IDEN; 226 227 if (yytoken != IDEN) 228 unexpected(); 229 sym = yylval.sym; 230 if ((sym->flags & SDECLARED) == 0) 231 sym = install(NS_LABEL, sym); 232 sym->flags |= SUSED; 233 emit(OJUMP, sym); 234 next(); 235 expect(';'); 236 } 237 238 static void 239 Swtch(Symbol *obr, Symbol *lcont, Switch *osw) 240 { 241 Switch sw = {0}; 242 Node *cond; 243 Symbol *lbreak; 244 245 expect(SWITCH); 246 247 expect ('('); 248 if ((cond = convert(expr(), inttype, 0)) == NULL) { 249 errorp("incorrect type in switch statement"); 250 cond = constnode(zero); 251 } 252 expect (')'); 253 254 lbreak = newlabel(); 255 emit(OBSWITCH, NULL); 256 emit(OEXPR, cond); 257 stmt(lbreak, lcont, &sw); 258 emit(OESWITCH, lbreak); 259 emit(OLABEL, lbreak); 260 } 261 262 static void 263 Case(Symbol *lbreak, Symbol *lcont, Switch *sw) 264 { 265 Node *np; 266 Symbol *label; 267 268 expect(CASE); 269 if ((np = constexpr()) == NULL) 270 errorp("case label does not reduce to an integer constant"); 271 if (!sw) { 272 errorp("case label not within a switch statement"); 273 } else if (sw->nr >= 0 && ++sw->nr == NR_SWITCH) { 274 errorp("too many case labels for a switch statement"); 275 sw->nr = -1; 276 } 277 expect(':'); 278 279 label = newlabel(); 280 emit(OCASE, label); 281 emit(OEXPR, np); 282 emit(OLABEL, label); 283 stmt(lbreak, lcont, sw); 284 } 285 286 static void 287 Default(Symbol *lbreak, Symbol *lcont, Switch *sw) 288 { 289 Symbol *label = newlabel(); 290 291 if (sw->hasdef) 292 errorp("multiple default labels in one switch"); 293 sw->hasdef = 1; 294 expect(DEFAULT); 295 expect(':'); 296 emit(ODEFAULT, label); 297 emit(OLABEL, label); 298 stmt(lbreak, lcont, sw); 299 } 300 301 static void 302 If(Symbol *lbreak, Symbol *lcont, Switch *lswitch) 303 { 304 Symbol *end, *lelse; 305 Node *np; 306 307 lelse = newlabel(); 308 expect(IF); 309 np = condition(NEGATE); 310 emit(OBRANCH, lelse); 311 emit(OEXPR, np); 312 stmt(lbreak, lcont, lswitch); 313 if (accept(ELSE)) { 314 end = newlabel(); 315 emit(OJUMP, end); 316 emit(OLABEL, lelse); 317 stmt(lbreak, lcont, lswitch); 318 emit(OLABEL, end); 319 } else { 320 emit(OLABEL, lelse); 321 } 322 } 323 324 static void 325 blockit(Symbol *lbreak, Symbol *lcont, Switch *lswitch) 326 { 327 switch (yytoken) { 328 case TYPEIDEN: 329 if (ahead() == ':') 330 goto parse_stmt; 331 case TYPE: 332 case TQUALIFIER: 333 case SCLASS: 334 decl(); 335 return; 336 default: 337 parse_stmt: 338 stmt(lbreak, lcont, lswitch); 339 } 340 } 341 342 void 343 compound(Symbol *lbreak, Symbol *lcont, Switch *lswitch) 344 { 345 static int nested; 346 347 pushctx(); 348 expect('{'); 349 350 if (nested == NR_BLOCK) 351 error("too many nesting levels of compound statements"); 352 353 ++nested; 354 for (;;) { 355 if (yytoken == '}') 356 break; 357 blockit(lbreak, lcont, lswitch); 358 } 359 --nested; 360 361 popctx(); 362 expect('}'); 363 } 364 365 static void 366 stmt(Symbol *lbreak, Symbol *lcont, Switch *lswitch) 367 { 368 void (*fun)(Symbol *, Symbol *, Switch *); 369 370 switch (yytoken) { 371 case '{': fun = compound; break; 372 case RETURN: fun = Return; break; 373 case WHILE: fun = While; break; 374 case FOR: fun = For; break; 375 case DO: fun = Dowhile; break; 376 case IF: fun = If; break; 377 case BREAK: fun = Break; break; 378 case CONTINUE: fun = Continue; break; 379 case GOTO: fun = Goto; break; 380 case SWITCH: fun = Swtch; break; 381 case CASE: fun = Case; break; 382 case DEFAULT: fun = Default; break; 383 default: fun = stmtexp; break; 384 } 385 (*fun)(lbreak, lcont, lswitch); 386 }