[vala/wip/transform: 45/48] Allow floating temp variables with CodeBuilder
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/transform: 45/48] Allow floating temp variables with CodeBuilder
- Date: Wed, 11 Apr 2012 16:52:33 +0000 (UTC)
commit 4fba03614661cd638b14b556214e3f389746a04e
Author: Luca Bruno <lucabru src gnome org>
Date: Fri Jan 6 14:11:22 2012 +0100
Allow floating temp variables with CodeBuilder
codegen/valaccodetransformer.vala | 171 ++++++++++++++-----------------------
vala/valacodebuilder.vala | 3 +-
2 files changed, 66 insertions(+), 108 deletions(-)
---
diff --git a/codegen/valaccodetransformer.vala b/codegen/valaccodetransformer.vala
index 195e954..a1f5859 100644
--- a/codegen/valaccodetransformer.vala
+++ b/codegen/valaccodetransformer.vala
@@ -180,92 +180,65 @@ public class Vala.CCodeTransformer : CodeTransformer {
public override void visit_do_statement (DoStatement stmt) {
// convert to simple loop
+ push_builder (new CodeBuilder (context, stmt, stmt.source_reference));
+ b.open_loop ();
// do not generate variable and if block if condition is always true
- if (always_true (stmt.condition)) {
- var loop = new Loop (stmt.body, stmt.source_reference);
-
- var parent_block = (Block) stmt.parent_node;
- context.analyzer.replaced_nodes.add (stmt);
- parent_block.replace_statement (stmt, loop);
-
- check (loop);
- return;
+ if (!always_true (stmt.condition)) {
+ 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 ();
}
+ b.add_statement (stmt.body);
+ b.close ();
- var block = new Block (stmt.source_reference);
-
- var first_local = new LocalVariable (context.analyzer.bool_type.copy (), stmt.get_temp_name (), new BooleanLiteral (true, stmt.source_reference), stmt.source_reference);
- block.add_statement (new DeclarationStatement (first_local, stmt.source_reference));
-
- var if_condition = new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, stmt.condition, stmt.condition.source_reference);
- var true_block = new Block (stmt.condition.source_reference);
- true_block.add_statement (new BreakStatement (stmt.condition.source_reference));
- var if_stmt = new IfStatement (if_condition, true_block, null, stmt.condition.source_reference);
-
- var condition_block = new Block (stmt.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, stmt.source_reference), stmt.source_reference), condition_block, null, stmt.source_reference);
- stmt.body.insert_statement (0, first_if);
- var first_assign = new ExpressionStatement (new Assignment (new MemberAccess.simple (first_local.name, stmt.source_reference), new BooleanLiteral (false, stmt.source_reference), AssignmentOperator.SIMPLE, stmt.source_reference), stmt.source_reference);
- stmt.body.insert_statement (1, first_assign);
-
- block.add_statement (new Loop (stmt.body, stmt.source_reference));
-
- var parent_block = (Block) stmt.parent_node;
+ var parent_block = context.analyzer.get_current_block (stmt);
context.analyzer.replaced_nodes.add (stmt);
- parent_block.replace_statement (stmt, block);
+ parent_block.replace_statement (stmt, new EmptyStatement (stmt.source_reference));
stmt.body.checked = false;
- check (block);
+ b.check (this);
+ pop_builder ();
}
public override void visit_for_statement (ForStatement stmt) {
// convert to simple loop
+ push_builder (new CodeBuilder (context, stmt, stmt.source_reference));
var block = new Block (stmt.source_reference);
// initializer
foreach (var init_expr in stmt.get_initializer ()) {
- block.add_statement (new ExpressionStatement (init_expr, init_expr.source_reference));
- }
-
- // do not generate if block if condition is always true
- if (stmt.condition == null || always_true (stmt.condition)) {
- } else if (always_false (stmt.condition)) {
- // do not generate if block if condition is always false
- stmt.body.insert_statement (0, new BreakStatement (stmt.condition.source_reference));
- } else {
- // condition
- var if_condition = new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, stmt.condition, stmt.condition.source_reference);
- var true_block = new Block (stmt.condition.source_reference);
- true_block.add_statement (new BreakStatement (stmt.condition.source_reference));
- var if_stmt = new IfStatement (if_condition, true_block, null, stmt.condition.source_reference);
- stmt.body.insert_statement (0, if_stmt);
+ b.add_expression (init_expr);
}
- // iterator
- var first_local = new LocalVariable (context.analyzer.bool_type.copy (), stmt.get_temp_name (), new BooleanLiteral (true, stmt.source_reference), stmt.source_reference);
- block.add_statement (new DeclarationStatement (first_local, stmt.source_reference));
+ if (stmt.condition == null || !always_false (stmt.condition)) {
+ b.open_loop ();
+ if (stmt.condition != null && !always_true (stmt.condition)) {
+ b.open_if (new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, stmt.condition, stmt.source_reference));
+ b.add_break ();
+ b.close ();
+ }
+ b.add_statement (stmt.body);
- var iterator_block = new Block (stmt.source_reference);
- foreach (var it_expr in stmt.get_iterator ()) {
- iterator_block.add_statement (new ExpressionStatement (it_expr, it_expr.source_reference));
+ foreach (var it_expr in stmt.get_iterator ()) {
+ b.add_expression (it_expr);
+ }
+ b.close ();
}
- var first_if = new IfStatement (new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, new MemberAccess.simple (first_local.name, stmt.source_reference), stmt.source_reference), iterator_block, null, stmt.source_reference);
- stmt.body.insert_statement (0, first_if);
- stmt.body.insert_statement (1, new ExpressionStatement (new Assignment (new MemberAccess.simple (first_local.name, stmt.source_reference), new BooleanLiteral (false, stmt.source_reference), AssignmentOperator.SIMPLE, stmt.source_reference), stmt.source_reference));
-
- block.add_statement (new Loop (stmt.body, stmt.source_reference));
-
- var parent_block = (Block) stmt.parent_node;
+ var parent_block = context.analyzer.get_current_block (stmt);
context.analyzer.replaced_nodes.add (stmt);
- parent_block.replace_statement (stmt, block);
+ parent_block.replace_statement (stmt, new EmptyStatement (stmt.source_reference));
stmt.body.checked = false;
- check (block);
+ b.check (this);
+ pop_builder ();
}
public override void visit_foreach_statement (ForeachStatement stmt) {
@@ -386,62 +359,46 @@ public class Vala.CCodeTransformer : CodeTransformer {
} else {
// store parent_node as we need to replace the expression in the old parent node later on
var old_parent_node = expr.parent_node;
+ var formal_target_type = expr.target_type != null ? expr.target_type.copy () : null;
+ var target_type = expr.target_type != null ? expr.target_type.copy () : null;
+ push_builder (new CodeBuilder (context, expr.parent_statement, expr.source_reference));
- var local = new LocalVariable (expr.value_type, expr.get_temp_name (), null, expr.source_reference);
- // use floating variable to avoid unnecessary (and sometimes impossible) copies
- local.floating = true;
- var decl = new DeclarationStatement (local, expr.source_reference);
-
- expr.insert_statement (context.analyzer.get_current_block (expr), decl);
-
- Expression temp_access = new MemberAccess.simple (local.name, expr.source_reference);
- temp_access.target_type = expr.target_type;
-
- // don't set initializer earlier as this changes parent_node and parent_statement
- local.initializer = expr;
- check (decl);
-
- // move temp variable to insert block to ensure
- // variable is in the same block as the declarat
- // otherwise there will be scoping issues in the
- var block = context.analyzer.get_current_block (expr);
- block.remove_local_variable (local);
- context.analyzer.get_current_block (expr).add_local_variable (local);
+ var replacement = expression (b.add_temp_declaration (expr.value_type, expr, true));
+ replacement.target_type = target_type;
+ replacement.formal_target_type = formal_target_type;
context.analyzer.replaced_nodes.add (expr);
- old_parent_node.replace_expression (expr, temp_access);
- check (temp_access);
+ old_parent_node.replace_expression (expr, replacement);
+ b.check (this);
+ pop_builder ();
+ check (replacement);
}
}
}
public override void visit_conditional_expression (ConditionalExpression expr) {
// convert to if statement
+ Expression replacement = null;
+ var old_parent_node = expr.parent_node;
+ var formal_target_type = expr.target_type != null ? expr.target_type.copy () : null;
+ var target_type = expr.target_type != null ? expr.target_type.copy () : null;
+ push_builder (new CodeBuilder (context, expr.parent_statement, expr.source_reference));
- var local = new LocalVariable (expr.value_type, expr.get_temp_name (), null, expr.source_reference);
- var decl = new DeclarationStatement (local, expr.source_reference);
- expr.insert_statement (context.analyzer.get_current_block (expr), decl);
- check (decl);
-
- var true_stmt = new ExpressionStatement (new Assignment (new MemberAccess.simple (local.name, expr.true_expression.source_reference), expr.true_expression, AssignmentOperator.SIMPLE, expr.true_expression.source_reference), expr.true_expression.source_reference);
- var true_block = new Block (expr.true_expression.source_reference);
- true_block.add_statement (true_stmt);
-
- var false_stmt = new ExpressionStatement (new Assignment (new MemberAccess.simple (local.name, expr.false_expression.source_reference), expr.false_expression, AssignmentOperator.SIMPLE, expr.false_expression.source_reference), expr.false_expression.source_reference);
- var false_block = new Block (expr.false_expression.source_reference);
- false_block.add_statement (false_stmt);
-
- var if_stmt = new IfStatement (expr.condition, true_block, false_block, expr.source_reference);
- expr.insert_statement (context.analyzer.get_current_block (expr), if_stmt);
- check (if_stmt);
-
- var ma = new MemberAccess.simple (local.name, expr.source_reference);
- ma.formal_target_type = expr.formal_target_type;
- ma.target_type = expr.target_type;
+ var result = b.add_temp_declaration (expr.value_type);
+ b.open_if (expr.condition);
+ b.add_assignment (expression (result), expr.true_expression);
+ b.add_else ();
+ b.add_assignment (expression (result), expr.false_expression);
+ b.close ();
+ replacement = expression (result);
+ replacement.target_type = target_type;
+ replacement.formal_target_type = formal_target_type;
context.analyzer.replaced_nodes.add (expr);
- expr.parent_node.replace_expression (expr, ma);
- check (ma);
+ old_parent_node.replace_expression (expr, replacement);
+ b.check (this);
+ pop_builder ();
+ check (replacement);
}
public override void visit_binary_expression (BinaryExpression expr) {
@@ -504,7 +461,7 @@ public class Vala.CCodeTransformer : CodeTransformer {
var target_type = expr.target_type != null ? expr.target_type.copy () : null;
push_builder (new CodeBuilder (context, expr.parent_statement, expr.source_reference));
- var replacement = expression (b.add_temp_declaration (expr.value_type, expr));
+ var replacement = expression (b.add_temp_declaration (expr.value_type, expr, true));
replacement.target_type = target_type;
context.analyzer.replaced_nodes.add (expr);
diff --git a/vala/valacodebuilder.vala b/vala/valacodebuilder.vala
index 1b8bcdf..4b43f96 100644
--- a/vala/valacodebuilder.vala
+++ b/vala/valacodebuilder.vala
@@ -231,8 +231,9 @@ public class Vala.CodeBuilder {
add_statement (new ContinueStatement (source_reference));
}
- public string add_temp_declaration (DataType? type, Expression? initializer = null) {
+ public string add_temp_declaration (DataType? type, Expression? initializer = null, bool floating = false) {
var local = new LocalVariable (type, CodeNode.get_temp_name (), initializer, source_reference);
+ local.floating = floating;
var stmt = new DeclarationStatement (local, source_reference);
insert_block.insert_before (insert_statement, stmt);
decl_nodes.add (stmt);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]