/ * codegen_while: Generate code for a while loop statement. * numlocals should be # of local variables for message excluding temps. * Returns highest # local variable used in code for statement. */
| 411 | * Returns highest # local variable used in code for statement. |
| 412 | */ |
| 413 | int codegen_while(while_stmt_type s, int numlocals) |
| 414 | { |
| 415 | opcode_type opcode; |
| 416 | int our_maxlocal = numlocals, numtemps, sourceval; |
| 417 | long toppos; |
| 418 | list_type p; |
| 419 | |
| 420 | toppos = FileCurPos(outfile); |
| 421 | codegen_enter_loop(); |
| 422 | |
| 423 | /* First generate code for condition */ |
| 424 | our_maxlocal = simplify_expr(s->condition, numlocals); |
| 425 | |
| 426 | /* Jump over body if condition is false */ |
| 427 | memset(&opcode, 0, sizeof(opcode)); /* Set opcode to all zeros */ |
| 428 | opcode.command = GOTO; |
| 429 | opcode.dest = GOTO_IF_FALSE; |
| 430 | sourceval = set_source_id(&opcode, SOURCE1, s->condition); |
| 431 | OutputOpcode(outfile, opcode); |
| 432 | |
| 433 | /* Make believe goto is a break statement & leave space for backpatching */ |
| 434 | current_loop->break_list = |
| 435 | list_add_item(current_loop->break_list, (void *) FileCurPos(outfile)); |
| 436 | OutputInt(outfile, 0); |
| 437 | OutputInt(outfile, sourceval); |
| 438 | |
| 439 | /* Write code for loop body */ |
| 440 | for (p = s->body; p != NULL; p = p->next) |
| 441 | { |
| 442 | numtemps = codegen_statement( (stmt_type) p->data, numlocals); |
| 443 | if (numtemps > our_maxlocal) |
| 444 | our_maxlocal = numtemps; |
| 445 | } |
| 446 | |
| 447 | /* Goto top of loop is last statement of while loop */ |
| 448 | opcode.source1 = 0; |
| 449 | opcode.source2 = GOTO_UNCONDITIONAL; |
| 450 | opcode.dest = 0; |
| 451 | OutputOpcode(outfile, opcode); |
| 452 | OutputGotoOffset(outfile, FileCurPos(outfile), toppos); |
| 453 | |
| 454 | codegen_exit_loop(); /* Takes care of break statements */ |
| 455 | |
| 456 | return our_maxlocal; |
| 457 | } |
| 458 | /************************************************************************/ |
| 459 | /* |
| 460 | * codegen_for: Generate code for a for loop statement. |
no test coverage detected