Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 33 additions & 5 deletions src/cfront.c
Original file line number Diff line number Diff line change
Expand Up @@ -1514,24 +1514,35 @@ void read_body_statement(block_t *parent)

if (lex_accept(T_while)) {
ir_instr_t *false_jump;
ir_instr_t *start = add_instr(OP_label); /* start to return to */

ir_instr_t *start_jump =
add_instr(OP_jump); /* jump to while condition */
ir_instr_t *exit_label = add_instr(OP_label);
ir_instr_t *exit_jump = add_instr(OP_jump);
ir_instr_t *start_label = add_instr(OP_label); /* start to return to */
lex_expect(T_open_bracket);
read_expr(0, parent); /* get expression value into return value */
lex_expect(T_close_bracket);

false_jump = add_instr(OP_jz);
false_jump->param_no = 0;

start_jump->int_param1 = start_label->ir_index;

/* create exit jump for breaks */
break_exit_ir_index[break_level++] = exit_label->ir_index;

read_body_statement(parent);

break_level--;

/* unconditional jump back to expression */
ii = add_instr(OP_jump);
ii->int_param1 = start->ir_index;
ii->int_param1 = start_label->ir_index;

/* exit label */
ii = add_instr(OP_label);
false_jump->int_param1 = ii->ir_index;
exit_jump->int_param1 = ii->ir_index;
return;
}

Expand Down Expand Up @@ -1621,6 +1632,10 @@ void read_body_statement(block_t *parent)
}

if (lex_accept(T_for)) {
ir_instr_t *start_jump = add_instr(OP_jump);
ir_instr_t *exit_label = add_instr(OP_label);
ir_instr_t *exit_jump = add_instr(OP_jump);
ir_instr_t *start_label = add_instr(OP_label);
ir_instr_t *condition_start;
ir_instr_t *condition_jump_out;
ir_instr_t *condition_jump_in;
Expand All @@ -1630,6 +1645,7 @@ void read_body_statement(block_t *parent)
ir_instr_t *body_jump;
ir_instr_t *end;

start_jump->int_param1 = start_label->ir_index;
lex_expect(T_open_bracket);

/* setup - execute once */
Expand Down Expand Up @@ -1671,30 +1687,42 @@ void read_body_statement(block_t *parent)
/* loop body */
body_start = add_instr(OP_label);
condition_jump_in->int_param1 = body_start->ir_index;
break_exit_ir_index[break_level++] = exit_label->ir_index;
read_body_statement(parent);
break_level--;

/* jump to increment */
body_jump = add_instr(OP_jump);
body_jump->int_param1 = increment->ir_index;

end = add_instr(OP_label);
condition_jump_out->int_param1 = end->ir_index;
exit_jump->int_param1 = end->ir_index;
return;
}

if (lex_accept(T_do)) {
ir_instr_t *false_jump;
ir_instr_t *start = add_instr(OP_label); /* start to return to */
ir_instr_t *start_jump = add_instr(OP_jump);
ir_instr_t *exit_label;
ir_instr_t *exit_jump = add_instr(OP_jump);
ir_instr_t *start_label = add_instr(OP_label); /* start to return to */
start_jump->int_param1 = start_label->ir_index;

break_exit_ir_index[break_level++] = exit_jump->ir_index;
read_body_statement(parent);
break_level--;

lex_expect(T_while);
lex_expect(T_open_bracket);
read_expr(0, parent); /* get expression value into return value */
lex_expect(T_close_bracket);

false_jump = add_instr(OP_jnz);
false_jump->param_no = 0;
false_jump->int_param1 = start->ir_index;
false_jump->int_param1 = start_label->ir_index;
exit_label = add_instr(OP_label);
exit_jump->int_param1 = exit_label->ir_index;

lex_expect(T_semicolon);
return;
Expand Down
6 changes: 3 additions & 3 deletions tests/driver.sh
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,12 @@ items 55 "int acc; int p; acc = 0; p = 10; while (p) { acc = acc + p; p = p - 1;
items 60 "int acc; acc = 15; do { acc = acc * -2; } while (acc < 0); exit(acc);"
# items 45 "int i; int acc; acc = 0; for (i = 0; i < 10; ++i) { acc = acc + i; } exit(acc);"
# items 45 "int i; int j; i=0; j=0; while (i<10) { j=j+i; i=i+1; } exit(j);"
# items 1 "int x; x=0; do {x = x + 1; break;} while (1); exit(x);"
items 1 "int x; x=0; do {x = x + 1; break;} while (1); exit(x);"
# items 1 "int x; x=0; do {x = x + 1; continue;} while (0); exit(x);"
# items 7 "int i; i=0; int j; for (j = 0; j < 10; j++) { if (j < 3) continue; i = i + 1; } exit(i);"
items 10 "while(0); exit(10);"
# items 10 "while(1) break; exit(10);"
# items 10 "for(;;) break; exit(10);"
items 10 "while(1) break; exit(10);"
items 10 "for(;;) break; exit(10);"
items 0 "int x; for(x = 10; x > 0; x--); exit(x);"
# items 30 "int i; int acc; i = 0; acc = 0; do { i = i + 1; if (i - 1 < 5) continue; acc = acc + i; if (i == 9) break; } while (i < 10); exit(acc);"
# items 26 "int acc; acc = 0; int i; for (i = 0; i < 100; ++i) { if (i < 5) continue; if (i == 9) break; acc = acc + i; } exit(acc);"
Expand Down