[vala] Convert do loops into simple loops



commit a71e6e0dea67455e741ffe319f796419a3fa42fe
Author: Jürg Billeter <j bitron ch>
Date:   Sat Jun 6 16:20:32 2009 +0200

    Convert do loops into simple loops
---
 codegen/valaccodebasemodule.vala        |    2 +-
 codegen/valaccodecontrolflowmodule.vala |    8 ----
 codegen/valaccodegenerator.vala         |    4 --
 codegen/valaccodemodule.vala            |    4 --
 vala/valadostatement.vala               |   70 +++++++++----------------------
 vala/valaexpression.vala                |    5 +--
 vala/valaflowanalyzer.vala              |   45 --------------------
 vala/valanullchecker.vala               |    6 ---
 8 files changed, 22 insertions(+), 122 deletions(-)

diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 3cc49d6..9b46954 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 192ad8a..2dc23b1 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 263c918..699d59c 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 1da365d..9d263e0 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 efc2d7a..fa64f1f 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 ce67db8..de3824f 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 33fe0da..5d824fa 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 0d0bffa..bf9c0dc 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);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]