From d19f0dc1dbb490a7d0fc159d45b5099875d8b84d Mon Sep 17 00:00:00 2001 From: eecheng Date: Wed, 28 Oct 2020 22:04:06 +0800 Subject: [PATCH] Consolidate break for general loop Close #21 --- src/cfront.c | 38 +++++++++++++++++++++++++++++++++----- tests/driver.sh | 6 +++--- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/cfront.c b/src/cfront.c index cdeb6844..06ef0a4e 100644 --- a/src/cfront.c +++ b/src/cfront.c @@ -1514,8 +1514,11 @@ 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); @@ -1523,15 +1526,23 @@ void read_body_statement(block_t *parent) 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; } @@ -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; @@ -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 */ @@ -1671,7 +1687,9 @@ 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); @@ -1679,14 +1697,22 @@ void read_body_statement(block_t *parent) 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 */ @@ -1694,7 +1720,9 @@ void read_body_statement(block_t *parent) 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; diff --git a/tests/driver.sh b/tests/driver.sh index c9620c87..950773e5 100755 --- a/tests/driver.sh +++ b/tests/driver.sh @@ -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);"