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