From: Jürg Billeter Date: Sat, 6 Jun 2009 14:20:32 +0000 (+0200) Subject: Convert do loops into simple loops X-Git-Tag: 0.7.4~49 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a71e6e0dea67455e741ffe319f796419a3fa42fe;p=thirdparty%2Fvala.git Convert do loops into simple loops --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 3cc49d639..9b46954fa 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -2231,7 +2231,7 @@ internal class Vala.CCodeBaseModule : CCodeModule { } if (stop_at_loop) { - if (b.parent_node is DoStatement || b.parent_node is Loop || + if (b.parent_node is Loop || b.parent_node is ForStatement || b.parent_node is ForeachStatement || b.parent_node is SwitchStatement) { return; diff --git a/codegen/valaccodecontrolflowmodule.vala b/codegen/valaccodecontrolflowmodule.vala index 192ad8aa3..2dc23b14c 100644 --- a/codegen/valaccodecontrolflowmodule.vala +++ b/codegen/valaccodecontrolflowmodule.vala @@ -227,14 +227,6 @@ internal class Vala.CCodeControlFlowModule : CCodeMethodModule { stmt.ccodenode = new CCodeWhileStatement (new CCodeConstant ("TRUE"), (CCodeStatement) stmt.body.ccodenode); } - public override void visit_do_statement (DoStatement stmt) { - stmt.accept_children (codegen); - - stmt.ccodenode = new CCodeDoStatement ((CCodeStatement) stmt.body.ccodenode, (CCodeExpression) stmt.condition.ccodenode); - - create_temp_decl (stmt, stmt.condition.temp_vars); - } - public override void visit_for_statement (ForStatement stmt) { stmt.accept_children (codegen); diff --git a/codegen/valaccodegenerator.vala b/codegen/valaccodegenerator.vala index 263c9182b..699d59cdf 100644 --- a/codegen/valaccodegenerator.vala +++ b/codegen/valaccodegenerator.vala @@ -193,10 +193,6 @@ public class Vala.CCodeGenerator : CodeGenerator { head.visit_loop (stmt); } - public override void visit_do_statement (DoStatement stmt) { - head.visit_do_statement (stmt); - } - public override void visit_for_statement (ForStatement stmt) { head.visit_for_statement (stmt); } diff --git a/codegen/valaccodemodule.vala b/codegen/valaccodemodule.vala index 1da365d4b..9d263e053 100644 --- a/codegen/valaccodemodule.vala +++ b/codegen/valaccodemodule.vala @@ -172,10 +172,6 @@ public abstract class Vala.CCodeModule { next.visit_loop (stmt); } - public virtual void visit_do_statement (DoStatement stmt) { - next.visit_do_statement (stmt); - } - public virtual void visit_for_statement (ForStatement stmt) { next.visit_for_statement (stmt); } diff --git a/vala/valadostatement.vala b/vala/valadostatement.vala index efc2d7acd..fa64f1fee 100644 --- a/vala/valadostatement.vala +++ b/vala/valadostatement.vala @@ -81,60 +81,28 @@ public class Vala.DoStatement : CodeNode, Statement { visitor.visit_end_full_expression (condition); } - public override void replace_expression (Expression old_node, Expression new_node) { - if (condition == old_node) { - condition = new_node; - } + bool always_true (Expression condition) { + var literal = condition as BooleanLiteral; + return (literal != null && literal.value); } public override bool check (SemanticAnalyzer analyzer) { - if (checked) { - return !error; - } + // convert to simple loop - checked = true; + // do not generate variable and if block if condition is always true + if (always_true (condition)) { + var loop = new Loop (body, source_reference); - if (!condition.check (analyzer)) { - /* if there was an error in the condition, skip this check */ - error = true; - return false; - } + var parent_block = (Block) parent_node; + parent_block.replace_statement (this, loop); - if (!condition.value_type.compatible (analyzer.bool_type)) { - error = true; - Report.error (condition.source_reference, "Condition must be boolean"); - return false; + return loop.check (analyzer); } - body.check (analyzer); + var block = new Block (source_reference); - add_error_types (condition.get_error_types ()); - add_error_types (body.get_error_types ()); - - return !error; - } - - public Block prepare_condition_split (SemanticAnalyzer analyzer) { - /* move condition into the loop body to allow split - * in multiple statements - * - * first = false; - * do { - * if (first) { - * if (!condition) { - * break; - * } - * } - * first = true; - * ... - * } while (true); - */ - - var first_local = new LocalVariable (analyzer.bool_type.copy (), get_temp_name (), new BooleanLiteral (false, source_reference), source_reference); - var first_decl = new DeclarationStatement (first_local, source_reference); - first_decl.check (analyzer); - var block = (Block) analyzer.current_symbol; - block.insert_before (this, first_decl); + var first_local = new LocalVariable (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); @@ -144,13 +112,15 @@ public class Vala.DoStatement : CodeNode, Statement { var condition_block = new Block (condition.source_reference); condition_block.add_statement (if_stmt); - var first_if = new IfStatement (new MemberAccess.simple (first_local.name, source_reference), condition_block, null, source_reference); + 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 (true, source_reference), AssignmentOperator.SIMPLE, source_reference), source_reference)); + 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)); - condition = new BooleanLiteral (true, source_reference); - condition.check (analyzer); + var parent_block = (Block) parent_node; + parent_block.replace_statement (this, block); - return condition_block; + return block.check (analyzer); } } diff --git a/vala/valaexpression.vala b/vala/valaexpression.vala index ce67db8c5..de3824f1b 100644 --- a/vala/valaexpression.vala +++ b/vala/valaexpression.vala @@ -103,12 +103,9 @@ public abstract class Vala.Expression : CodeNode { } public Block prepare_condition_split (SemanticAnalyzer analyzer) { - var do_stmt = parent_statement as DoStatement; var for_stmt = parent_statement as ForStatement; - if (do_stmt != null) { - return do_stmt.prepare_condition_split (analyzer); - } else if (for_stmt != null) { + if (for_stmt != null) { return for_stmt.prepare_condition_split (analyzer); } diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala index 33fe0da6a..5d824fa49 100644 --- a/vala/valaflowanalyzer.vala +++ b/vala/valaflowanalyzer.vala @@ -691,51 +691,6 @@ public class Vala.FlowAnalyzer : CodeVisitor { jump_stack.remove_at (jump_stack.size - 1); } - public override void visit_do_statement (DoStatement stmt) { - if (unreachable (stmt)) { - return; - } - - var condition_block = new BasicBlock (); - jump_stack.add (new JumpTarget.continue_target (condition_block)); - var after_loop_block = new BasicBlock (); - jump_stack.add (new JumpTarget.break_target (after_loop_block)); - - // loop block - var last_block = current_block; - var loop_block = new BasicBlock (); - last_block.connect (loop_block); - current_block = loop_block; - stmt.body.accept (this); - - // condition - // reachable? - if (current_block != null || condition_block.get_predecessors ().size > 0) { - if (current_block != null) { - last_block = current_block; - last_block.connect (condition_block); - } - condition_block.add_node (stmt.condition); - condition_block.connect (loop_block); - current_block = condition_block; - - handle_errors (stmt.condition); - } - - // after loop - // reachable? - if (current_block != null || after_loop_block.get_predecessors ().size > 0) { - if (current_block != null) { - last_block = current_block; - last_block.connect (after_loop_block); - } - 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_for_statement (ForStatement stmt) { if (unreachable (stmt)) { return; diff --git a/vala/valanullchecker.vala b/vala/valanullchecker.vala index 0d0bffa82..bf9c0dcb3 100644 --- a/vala/valanullchecker.vala +++ b/vala/valanullchecker.vala @@ -156,12 +156,6 @@ public class Vala.NullChecker : CodeVisitor { stmt.accept_children (this); } - public override void visit_do_statement (DoStatement stmt) { - stmt.accept_children (this); - - check_non_null (stmt.condition); - } - public override void visit_for_statement (ForStatement stmt) { stmt.accept_children (this);