[vala] Convert for loops into simple loops
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Subject: [vala] Convert for loops into simple loops
- Date: Sat, 6 Jun 2009 11:20:57 -0400 (EDT)
commit fef10859ae29c524cac6a7388759f02e26df160d
Author: Jürg Billeter <j bitron ch>
Date: Sat Jun 6 17:04:02 2009 +0200
Convert for loops into simple loops
---
codegen/valaccodebasemodule.vala | 2 +-
codegen/valaccodecontrolflowmodule.vala | 26 --------
codegen/valaccodegenerator.vala | 4 -
codegen/valaccodemodule.vala | 4 -
gee/hashmap.vala | 2 +-
gee/hashset.vala | 2 +-
vala/valabinaryexpression.vala | 4 -
vala/valaconditionalexpression.vala | 6 +--
vala/valaexpression.vala | 10 ---
vala/valaflowanalyzer.vala | 55 -----------------
vala/valaforstatement.vala | 98 +++++++++---------------------
vala/valamethodcall.vala | 5 --
vala/valanullchecker.vala | 6 --
13 files changed, 34 insertions(+), 190 deletions(-)
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 9b46954..8073265 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -2232,7 +2232,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
if (stop_at_loop) {
if (b.parent_node is Loop ||
- b.parent_node is ForStatement || b.parent_node is ForeachStatement ||
+ b.parent_node is ForeachStatement ||
b.parent_node is SwitchStatement) {
return;
}
diff --git a/codegen/valaccodecontrolflowmodule.vala b/codegen/valaccodecontrolflowmodule.vala
index 2dc23b1..b0c84c0 100644
--- a/codegen/valaccodecontrolflowmodule.vala
+++ b/codegen/valaccodecontrolflowmodule.vala
@@ -227,32 +227,6 @@ internal class Vala.CCodeControlFlowModule : CCodeMethodModule {
stmt.ccodenode = new CCodeWhileStatement (new CCodeConstant ("TRUE"), (CCodeStatement) stmt.body.ccodenode);
}
- public override void visit_for_statement (ForStatement stmt) {
- stmt.accept_children (codegen);
-
- CCodeExpression ccondition = null;
- if (stmt.condition != null) {
- ccondition = (CCodeExpression) stmt.condition.ccodenode;
- }
-
- var cfor = new CCodeForStatement (ccondition, (CCodeStatement) stmt.body.ccodenode);
- stmt.ccodenode = cfor;
-
- foreach (Expression init_expr in stmt.get_initializer ()) {
- cfor.add_initializer ((CCodeExpression) init_expr.ccodenode);
- create_temp_decl (stmt, init_expr.temp_vars);
- }
-
- foreach (Expression it_expr in stmt.get_iterator ()) {
- cfor.add_iterator ((CCodeExpression) it_expr.ccodenode);
- create_temp_decl (stmt, it_expr.temp_vars);
- }
-
- if (stmt.condition != null) {
- create_temp_decl (stmt, stmt.condition.temp_vars);
- }
- }
-
public override void visit_foreach_statement (ForeachStatement stmt) {
stmt.element_variable.active = true;
stmt.collection_variable.active = true;
diff --git a/codegen/valaccodegenerator.vala b/codegen/valaccodegenerator.vala
index 699d59c..f66e6dc 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_for_statement (ForStatement stmt) {
- head.visit_for_statement (stmt);
- }
-
public override void visit_foreach_statement (ForeachStatement stmt) {
head.visit_foreach_statement (stmt);
}
diff --git a/codegen/valaccodemodule.vala b/codegen/valaccodemodule.vala
index 9d263e0..1743d2e 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_for_statement (ForStatement stmt) {
- next.visit_for_statement (stmt);
- }
-
public virtual void visit_foreach_statement (ForeachStatement stmt) {
next.visit_foreach_statement (stmt);
}
diff --git a/gee/hashmap.vala b/gee/hashmap.vala
index 67b08ba..c152b7b 100644
--- a/gee/hashmap.vala
+++ b/gee/hashmap.vala
@@ -153,7 +153,7 @@ public class Gee.HashMap<K,V> : CollectionObject, Map<K,V> {
for (int i = 0; i < _array_size; i++) {
Node<K,V> node;
- Node<K,V> next;
+ Node<K,V> next = null;
for (node = (owned) _nodes[i]; node != null; node = (owned) next) {
next = (owned) node.next;
uint hash_val = node.key_hash % new_array_size;
diff --git a/gee/hashset.vala b/gee/hashset.vala
index a5a9805..712fd8d 100644
--- a/gee/hashset.vala
+++ b/gee/hashset.vala
@@ -137,7 +137,7 @@ public class Gee.HashSet<G> : CollectionObject, Iterable<G>, Collection<G>, Set<
for (int i = 0; i < _array_size; i++) {
Node<G> node;
- Node<G> next;
+ Node<G> next = null;
for (node = (owned) _nodes[i]; node != null; node = (owned) next) {
next = (owned) node.next;
uint hash_val = node.key_hash % new_array_size;
diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala
index cbfb132..54f5890 100644
--- a/vala/valabinaryexpression.vala
+++ b/vala/valabinaryexpression.vala
@@ -151,9 +151,6 @@ public class Vala.BinaryExpression : Expression {
// for example, expressions in method contracts
if (analyzer.current_symbol is Block
&& (operator == BinaryOperator.AND || operator == BinaryOperator.OR)) {
- var old_insert_block = analyzer.insert_block;
- analyzer.insert_block = prepare_condition_split (analyzer);
-
// convert conditional expression into if statement
// required for flow analysis and exception handling
@@ -185,7 +182,6 @@ public class Vala.BinaryExpression : Expression {
error = true;
return false;
}
- analyzer.insert_block = old_insert_block;
var ma = new MemberAccess.simple (local.name, source_reference);
ma.target_type = target_type;
diff --git a/vala/valaconditionalexpression.vala b/vala/valaconditionalexpression.vala
index 191d0fc..f521bc8 100644
--- a/vala/valaconditionalexpression.vala
+++ b/vala/valaconditionalexpression.vala
@@ -1,6 +1,6 @@
/* valaconditionalexpression.vala
*
- * Copyright (C) 2006-2008 Jürg Billeter
+ * Copyright (C) 2006-2009 Jürg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -111,9 +111,6 @@ public class Vala.ConditionalExpression : Expression {
return false;
}
- var old_insert_block = analyzer.insert_block;
- analyzer.insert_block = prepare_condition_split (analyzer);
-
// convert ternary expression into if statement
// required for flow analysis and exception handling
@@ -143,7 +140,6 @@ public class Vala.ConditionalExpression : Expression {
if (!if_stmt.check (analyzer)) {
return false;
}
- analyzer.insert_block = old_insert_block;
true_expression = true_local.initializer;
false_expression = false_local.initializer;
diff --git a/vala/valaexpression.vala b/vala/valaexpression.vala
index de3824f..ab73c4d 100644
--- a/vala/valaexpression.vala
+++ b/vala/valaexpression.vala
@@ -102,16 +102,6 @@ public abstract class Vala.Expression : CodeNode {
}
}
- public Block prepare_condition_split (SemanticAnalyzer analyzer) {
- var for_stmt = parent_statement as ForStatement;
-
- if (for_stmt != null) {
- return for_stmt.prepare_condition_split (analyzer);
- }
-
- return analyzer.insert_block;
- }
-
public void insert_statement (Block block, Statement stmt) {
block.insert_before (parent_statement, stmt);
}
diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala
index 5d824fa..cf093e2 100644
--- a/vala/valaflowanalyzer.vala
+++ b/vala/valaflowanalyzer.vala
@@ -691,61 +691,6 @@ public class Vala.FlowAnalyzer : CodeVisitor {
jump_stack.remove_at (jump_stack.size - 1);
}
- public override void visit_for_statement (ForStatement stmt) {
- if (unreachable (stmt)) {
- return;
- }
-
- // initializer
- foreach (Expression init_expr in stmt.get_initializer ()) {
- current_block.add_node (init_expr);
- handle_errors (init_expr);
- }
-
- var iterator_block = new BasicBlock ();
- jump_stack.add (new JumpTarget.continue_target (iterator_block));
- var after_loop_block = new BasicBlock ();
- jump_stack.add (new JumpTarget.break_target (after_loop_block));
-
- // condition
- var condition_block = new BasicBlock ();
- current_block.connect (condition_block);
- current_block = condition_block;
- if (stmt.condition != null) {
- current_block.add_node (stmt.condition);
- }
-
- if (stmt.condition != null) {
- handle_errors (stmt.condition);
- }
-
- // loop block
- current_block = new BasicBlock ();
- condition_block.connect (current_block);
- stmt.body.accept (this);
-
- // iterator
- // reachable?
- if (current_block != null || iterator_block.get_predecessors ().size > 0) {
- if (current_block != null) {
- current_block.connect (iterator_block);
- }
- current_block = iterator_block;
- foreach (Expression it_expr in stmt.get_iterator ()) {
- current_block.add_node (it_expr);
- handle_errors (it_expr);
- }
- current_block.connect (condition_block);
- }
-
- // after loop
- condition_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_foreach_statement (ForeachStatement stmt) {
if (unreachable (stmt)) {
return;
diff --git a/vala/valaforstatement.vala b/vala/valaforstatement.vala
index bdc048a..38e79bc 100644
--- a/vala/valaforstatement.vala
+++ b/vala/valaforstatement.vala
@@ -1,6 +1,6 @@
/* valaforstatement.vala
*
- * Copyright (C) 2006-2008 Jürg Billeter
+ * Copyright (C) 2006-2009 Jürg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -137,87 +137,49 @@ public class Vala.ForStatement : CodeNode, Statement {
body.accept (visitor);
}
- public override void replace_expression (Expression old_node, Expression new_node) {
- if (condition == old_node) {
- condition = new_node;
- return;
- }
-
- for (int i = 0; i < initializer.size; i++) {
- if (initializer[i] == old_node) {
- initializer[i] = new_node;
- return;
- }
- }
- for (int i = 0; i < iterator.size; i++) {
- if (iterator[i] == old_node) {
- iterator[i] = new_node;
- return;
- }
- }
+ 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;
- }
-
- checked = true;
-
- foreach (Expression init_expr in initializer) {
- init_expr.check (analyzer);
- }
+ // convert to simple loop
- if (condition != null) {
- condition.check (analyzer);
- }
+ var block = new Block (source_reference);
- foreach (Expression it_expr in iterator) {
- it_expr.check (analyzer);
+ // initializer
+ foreach (var init_expr in initializer) {
+ block.add_statement (new ExpressionStatement (init_expr, init_expr.source_reference));
}
-
- body.check (analyzer);
- if (condition != null && condition.error) {
- /* if there was an error in the condition, skip this check */
- error = true;
- return false;
+ // do not generate if block if condition is always true
+ if (condition != null && !always_true (condition)) {
+ // condition
+ 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);
+ body.insert_statement (0, if_stmt);
}
- if (condition != null && !condition.value_type.compatible (analyzer.bool_type)) {
- error = true;
- Report.error (condition.source_reference, "Condition must be boolean");
- return false;
- }
+ // iterator
+ 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));
- if (condition != null) {
- add_error_types (condition.get_error_types ());
+ var iterator_block = new Block (source_reference);
+ foreach (var it_expr in iterator) {
+ iterator_block.add_statement (new ExpressionStatement (it_expr, it_expr.source_reference));
}
- add_error_types (body.get_error_types ());
- foreach (Expression exp in get_initializer ()) {
- add_error_types (exp.get_error_types ());
- }
- foreach (Expression exp in get_iterator ()) {
- add_error_types (exp.get_error_types ());
- }
-
- return !error;
- }
-
- public Block prepare_condition_split (SemanticAnalyzer analyzer) {
- // move condition into the loop body to allow split
- // in multiple statements
+ var first_if = new IfStatement (new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, new MemberAccess.simple (first_local.name, source_reference), source_reference), iterator_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));
- 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);
- body.insert_statement (0, if_stmt);
+ 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 body;
+ return block.check (analyzer);
}
}
diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala
index 450f187..74fb2f8 100644
--- a/vala/valamethodcall.vala
+++ b/vala/valamethodcall.vala
@@ -436,9 +436,6 @@ public class Vala.MethodCall : Expression {
if (parent_node is LocalVariable || parent_node is ExpressionStatement) {
// simple statements, no side effects after method call
} else {
- var old_insert_block = analyzer.insert_block;
- analyzer.insert_block = prepare_condition_split (analyzer);
-
// store parent_node as we need to replace the expression in the old parent node later on
var old_parent_node = parent_node;
@@ -464,8 +461,6 @@ public class Vala.MethodCall : Expression {
block.remove_local_variable (local);
analyzer.insert_block.add_local_variable (local);
- analyzer.insert_block = old_insert_block;
-
old_parent_node.replace_expression (this, temp_access);
}
}
diff --git a/vala/valanullchecker.vala b/vala/valanullchecker.vala
index bf9c0dc..8566fb7 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_for_statement (ForStatement stmt) {
- stmt.accept_children (this);
-
- check_non_null (stmt.condition);
- }
-
public override void visit_foreach_statement (ForeachStatement stmt) {
stmt.accept_children (this);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]