Merge pull request #935 from larsclausen/do-while-continue-break

Handle continue/break in do-while loops
This commit is contained in:
Cary R 2023-06-11 07:59:01 -07:00 committed by GitHub
commit edaa6e6c76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 65 additions and 27 deletions

View File

@ -35,6 +35,18 @@ module main;
$finish;
end
idx = 0;
do begin
if (idx >= 2)
break;
idx += 1;
end while (idx < 5);
if (idx != 2) begin
$display("FAILED -- break from do-while loop");
$finish;
end
idx = 0;
repeat (5) begin
if (idx >= 2)

View File

@ -51,6 +51,21 @@ module main;
$finish;
end
idx = 0;
do begin
idx += 1;
if (idx < 2)
continue;
if (idx < 2) begin
$display("FAILED -- continue in do-while loop");
$finish;
end
end while (idx < 5);
if (idx != 5) begin
$display("FAILED -- break from do-while loop");
$finish;
end
idx = 0;
repeat (5) begin
idx += 1;

View File

@ -285,5 +285,6 @@ extern int show_stmt_forever(ivl_statement_t net, ivl_scope_t sscope);
extern int show_stmt_forloop(ivl_statement_t net, ivl_scope_t sscope);
extern int show_stmt_repeat(ivl_statement_t net, ivl_scope_t sscope);
extern int show_stmt_while(ivl_statement_t net, ivl_scope_t sscope);
extern int show_stmt_do_while(ivl_statement_t net, ivl_scope_t sscope);
#endif /* IVL_vvp_priv_H */

View File

@ -220,3 +220,40 @@ int show_stmt_while(ivl_statement_t net, ivl_scope_t sscope)
return rc;
}
int show_stmt_do_while(ivl_statement_t net, ivl_scope_t sscope)
{
int rc = 0;
unsigned top_label = local_count++;
unsigned cont_label = local_count++;
unsigned out_label = local_count++;
unsigned save_break_label, save_continue_label;
PUSH_JUMPS(out_label, cont_label);
show_stmt_file_line(net, "Do/While statement.");
/* Start the loop. The top of the loop starts a basic block
because it can be entered from above or from the bottom of
the loop. */
fprintf(vvp_out, "T_%u.%u ;\n", thread_count, top_label);
/* Draw the body of the loop. */
rc += show_statement(ivl_stmt_sub_stmt(net), sscope);
fprintf(vvp_out, "T_%u.%u ;\n", thread_count, cont_label);
/* Draw the evaluation of the condition expression, and test
the result. If the expression evaluates to true, then
branch to the top label. */
int use_flag = draw_eval_condition(ivl_stmt_cond_expr(net));
fprintf(vvp_out, " %%jmp/1 T_%u.%u, %d;\n",
thread_count, top_label, use_flag);
clr_flag(use_flag);
fprintf(vvp_out, "T_%u.%u ;\n", thread_count, out_label);
POP_JUMPS;
return rc;
}

View File

@ -1355,33 +1355,6 @@ static int show_stmt_disable(ivl_statement_t net, ivl_scope_t sscope)
return rc;
}
static int show_stmt_do_while(ivl_statement_t net, ivl_scope_t sscope)
{
int rc = 0;
unsigned top_label = local_count++;
show_stmt_file_line(net, "Do/While statement.");
/* Start the loop. The top of the loop starts a basic block
because it can be entered from above or from the bottom of
the loop. */
fprintf(vvp_out, "T_%u.%u ;\n", thread_count, top_label);
/* Draw the body of the loop. */
rc += show_statement(ivl_stmt_sub_stmt(net), sscope);
/* Draw the evaluation of the condition expression, and test
the result. If the expression evaluates to true, then
branch to the top label. */
int use_flag = draw_eval_condition(ivl_stmt_cond_expr(net));
fprintf(vvp_out, " %%jmp/1 T_%u.%u, %d;\n",
thread_count, top_label, use_flag);
clr_flag(use_flag);
return rc;
}
static int show_stmt_force(ivl_statement_t net)
{
ivl_expr_t rval;