end_replace_statement ();
}
+ public override void visit_do_statement (DoStatement stmt) {
+ // convert to simple loop
+ begin_replace_statement (stmt);
+
+ b.open_loop ();
+ // do not generate variable and if block if condition is always true
+ if (!stmt.condition.is_always_true ()) {
+ var notfirst = b.add_temp_declaration (null, expression ("false"));
+ b.open_if (expression (notfirst));
+ b.open_if (new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, stmt.condition, stmt.source_reference));
+ b.add_break ();
+ b.close ();
+ b.add_else ();
+ b.add_assignment (expression (notfirst), expression ("true"));
+ b.close ();
+ }
+ stmt.body.checked = false;
+ b.add_statement (stmt.body);
+ b.close ();
+
+ end_replace_statement ();
+ }
+
public override void visit_expression (Expression expr) {
if (expr in context.analyzer.replaced_nodes) {
return;
checked = true;
- // convert to simple loop
+ condition.target_type = context.analyzer.bool_type.copy ();
- // do not generate variable and if block if condition is always true
- if (condition.is_always_true ()) {
- var loop = new Loop (body, source_reference);
+ condition.check (context);
- unowned Block parent_block = (Block) parent_node;
- parent_block.replace_statement (this, loop);
-
- if (!loop.check (context)) {
- error = true;
- }
-
- return !error;
+ if (condition.error) {
+ /* if there was an error in the condition, skip this check */
+ error = true;
+ return false;
}
- var block = new Block (source_reference);
-
- var first_local = new LocalVariable (context.analyzer.bool_type.copy (), get_temp_name (), new BooleanLiteral (true, source_reference), source_reference);
- block.add_statement (new DeclarationStatement (first_local, source_reference));
-
- var if_condition = new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, condition, condition.source_reference);
- var true_block = new Block (condition.source_reference);
- true_block.add_statement (new BreakStatement (condition.source_reference));
- var if_stmt = new IfStatement (if_condition, true_block, null, condition.source_reference);
-
- var condition_block = new Block (condition.source_reference);
- condition_block.add_statement (if_stmt);
-
- var first_if = new IfStatement (new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, new MemberAccess.simple (first_local.name, source_reference), source_reference), condition_block, null, source_reference);
- body.insert_statement (0, first_if);
- body.insert_statement (1, new ExpressionStatement (new Assignment (new MemberAccess.simple (first_local.name, source_reference), new BooleanLiteral (false, source_reference), AssignmentOperator.SIMPLE, source_reference), source_reference));
-
- block.add_statement (new Loop (body, source_reference));
-
- unowned Block parent_block = (Block) parent_node;
- parent_block.replace_statement (this, block);
+ if (condition.value_type == null || !condition.value_type.compatible (context.analyzer.bool_type)) {
+ error = true;
+ Report.error (condition.source_reference, "Condition must be boolean");
+ return false;
+ }
- if (!block.check (context)) {
+ if (!body.check (context)) {
error = true;
+ return false;
}
return !error;
jump_stack.remove_at (jump_stack.size - 1);
}
+ public override void visit_do_statement (DoStatement stmt) {
+ if (unreachable (stmt)) {
+ return;
+ }
+
+ var body_block = new BasicBlock ();
+ all_basic_blocks.add (body_block);
+ current_block.connect (body_block);
+ current_block = body_block;
+
+ var loop_block = new BasicBlock ();
+ all_basic_blocks.add (loop_block);
+ jump_stack.add (new JumpTarget.continue_target (loop_block));
+ var after_loop_block = new BasicBlock ();
+ all_basic_blocks.add (after_loop_block);
+ jump_stack.add (new JumpTarget.break_target (after_loop_block));
+
+ // body
+ stmt.body.accept (this);
+
+ // end of loop block reachable?
+ if (current_block != null) {
+ current_block.connect (loop_block);
+ }
+
+ // condition
+ current_block = loop_block;
+ loop_block.add_node (stmt.condition);
+ handle_errors (stmt.condition);
+
+ if (!stmt.condition.is_always_false ()) {
+ loop_block.connect (body_block);
+ }
+
+ if (!stmt.condition.is_always_true ()) {
+ loop_block.connect (after_loop_block);
+ }
+
+ // after loop block reachable?
+ if (after_loop_block.get_predecessors ().size == 0) {
+ // after loop block not reachable
+ mark_unreachable ();
+ } else {
+ // after loop block reachable
+ current_block = after_loop_block;
+ }
+
+ jump_stack.remove_at (jump_stack.size - 1);
+ jump_stack.remove_at (jump_stack.size - 1);
+ }
+
public override void visit_foreach_statement (ForeachStatement stmt) {
if (unreachable (stmt)) {
return;