]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Convert do loops into simple loops
authorJürg Billeter <j@bitron.ch>
Sat, 6 Jun 2009 14:20:32 +0000 (16:20 +0200)
committerJürg Billeter <j@bitron.ch>
Sat, 6 Jun 2009 15:20:19 +0000 (17:20 +0200)
codegen/valaccodebasemodule.vala
codegen/valaccodecontrolflowmodule.vala
codegen/valaccodegenerator.vala
codegen/valaccodemodule.vala
vala/valadostatement.vala
vala/valaexpression.vala
vala/valaflowanalyzer.vala
vala/valanullchecker.vala

index 3cc49d63974f10835fc54a778bb20c500d158503..9b46954fa753a379c4bb0afdcacf16bba701abfc 100644 (file)
@@ -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;
index 192ad8aa33fa5814c2bb4cb91985be0f9e24db5e..2dc23b14c4af07d9cb1366a0066c6860e5d9a721 100644 (file)
@@ -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);
 
index 263c9182b3b1cb4c23dbcbd6454ad11f197d45c1..699d59cdf9df2c9dc86de9696f25f31cedaf62f0 100644 (file)
@@ -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);
        }
index 1da365d4b9545a373cd3d0bb530a45c333571166..9d263e053ff0c91e87d6da14bfa864a5e760c5ca 100644 (file)
@@ -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);
        }
index efc2d7acd9df74f39eef706f5c18d964c3d02e5c..fa64f1feeeb115be7ddff88396403451ae99099d 100644 (file)
@@ -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);
        }
 }
index ce67db8c50829c76b06a38fbcc7c6ec31266c941..de3824f1bf67dae6b1e21d1137202529467e53d0 100644 (file)
@@ -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);
                }
 
index 33fe0da6ad407f5cee6c5ac36fda748294cf878e..5d824fa49ea8d54a03fca5406dfe54c3999d3ead 100644 (file)
@@ -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;
index 0d0bffa8227f7baff5fca8296bf3054533cdd634..bf9c0dcb3fa944ed7e1f2d14612eb523db55bac5 100644 (file)
@@ -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);