[vala/wip/transform: 38/50] Move BinaryExpression transformation to the code transformer
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/transform: 38/50] Move BinaryExpression transformation to the code transformer
- Date: Fri, 13 Apr 2012 13:10:27 +0000 (UTC)
commit f8ff74640c4bace577af7ba236fa3df195d2c82a
Author: Luca Bruno <lucabru src gnome org>
Date: Wed Jan 4 23:59:34 2012 +0100
Move BinaryExpression transformation to the code transformer
codegen/valaccodetransformer.vala | 48 +++++++++++++++++-
codegen/valagvarianttransformer.vala | 4 ++
vala/valabinaryexpression.vala | 95 ++--------------------------------
vala/valaforeachstatement.vala | 16 +++---
4 files changed, 64 insertions(+), 99 deletions(-)
---
diff --git a/codegen/valaccodetransformer.vala b/codegen/valaccodetransformer.vala
index cdd512d..829cc08 100644
--- a/codegen/valaccodetransformer.vala
+++ b/codegen/valaccodetransformer.vala
@@ -297,7 +297,7 @@ public class Vala.CCodeTransformer : CodeTransformer {
break;
case ForeachIteration.INDEX:
// get()+size
- var size = b.add_temp_declaration (null, expression ("$collection.size"));
+ var size = b.add_temp_declaration (null, expression (@"$collection.size"));
var i = b.add_temp_declaration (null, expression ("0"));
b.open_for (null, expression (@"$i < $size"), expression (@"$i++"));
stmt.element_variable.initializer = expression (@"$collection.get ($i)");
@@ -445,4 +445,50 @@ public class Vala.CCodeTransformer : CodeTransformer {
expr.parent_node.replace_expression (expr, ma);
check (ma);
}
+
+ public override void visit_binary_expression (BinaryExpression expr) {
+ Expression replacement = null;
+ var old_parent_node = expr.parent_node;
+ var target_type = expr.target_type != null ? expr.target_type.copy () : null;
+ push_builder (new CodeBuilder (context, expr.parent_statement, expr.source_reference));
+
+ if (context.analyzer.get_current_symbol (expr) is Block
+ && (expr.operator == BinaryOperator.AND || expr.operator == BinaryOperator.OR)) {
+ var is_and = expr.operator == BinaryOperator.AND;
+ var result = b.add_temp_declaration (data_type ("bool"));
+ b.open_if (expr.left);
+ if (is_and) {
+ b.add_assignment (expression (result), expr.right);
+ } else {
+ b.add_expression (expression (@"$result = true"));
+ }
+ b.add_else ();
+ if (is_and) {
+ b.add_expression (expression (@"$result = false"));
+ } else {
+ b.add_assignment (expression (result), expr.right);
+ }
+ b.close ();
+ replacement = expression (result);
+ } else if (expr.operator == BinaryOperator.COALESCE) {
+ replacement = new ConditionalExpression (new BinaryExpression (BinaryOperator.EQUALITY, expr.left, new NullLiteral (expr.source_reference), expr.source_reference), expr.right, expr.left, expr.source_reference);
+ } else if (expr.operator == BinaryOperator.IN && !(expr.left.value_type.compatible (context.analyzer.int_type) && expr.right.value_type.compatible (context.analyzer.int_type)) && !(expr.right.value_type is ArrayType)) {
+ // neither enums nor array, it's contains()
+ var call = new MethodCall (new MemberAccess (expr.right, "contains", expr.source_reference), expr.source_reference);
+ call.add_argument (expr.left);
+ replacement = call;
+ }
+
+ if (replacement != null) {
+ replacement.target_type = target_type;
+ context.analyzer.replaced_nodes.add (expr);
+ old_parent_node.replace_expression (expr, replacement);
+ b.check (this);
+ pop_builder ();
+ check (replacement);
+ } else {
+ pop_builder ();
+ base.visit_binary_expression (expr);
+ }
+ }
}
diff --git a/codegen/valagvarianttransformer.vala b/codegen/valagvarianttransformer.vala
index 26a521a..ef3c2c2 100644
--- a/codegen/valagvarianttransformer.vala
+++ b/codegen/valagvarianttransformer.vala
@@ -533,6 +533,10 @@ public class Vala.GVariantTransformer : CCodeTransformer {
}
public override void visit_expression (Expression expr) {
+ if (expr in context.analyzer.replaced_nodes) {
+ return;
+ }
+
if (!(context.profile == Profile.GOBJECT && expr.target_type != null && is_gvariant_type (expr.target_type) && !(expr.value_type is NullType) && !is_gvariant_type (expr.value_type))) {
// no implicit gvariant boxing
base.visit_expression (expr);
diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala
index 0edefb9..d4684d2 100644
--- a/vala/valabinaryexpression.vala
+++ b/vala/valabinaryexpression.vala
@@ -148,89 +148,6 @@ public class Vala.BinaryExpression : Expression {
checked = true;
- var insert_block = context.analyzer.get_current_block (this);
-
- // some expressions are not in a block,
- // for example, expressions in method contracts
- if (context.analyzer.get_current_symbol (this) is Block
- && (operator == BinaryOperator.AND || operator == BinaryOperator.OR)) {
- // convert conditional expression into if statement
- // required for flow analysis and exception handling
-
- var local = new LocalVariable (context.analyzer.bool_type.copy (), get_temp_name (), null, source_reference);
- var decl = new DeclarationStatement (local, source_reference);
-
- var right_stmt = new ExpressionStatement (new Assignment (new MemberAccess.simple (local.name, right.source_reference), right, AssignmentOperator.SIMPLE, right.source_reference), right.source_reference);
-
- var stmt = new ExpressionStatement (new Assignment (new MemberAccess.simple (local.name, left.source_reference), new BooleanLiteral ((operator == BinaryOperator.OR), left.source_reference), AssignmentOperator.SIMPLE, left.source_reference), left.source_reference);
-
- var true_block = new Block (source_reference);
- var false_block = new Block (source_reference);
-
- if (operator == BinaryOperator.AND) {
- true_block.add_statement (right_stmt);
- false_block.add_statement (stmt);
- } else {
- true_block.add_statement (stmt);
- false_block.add_statement (right_stmt);
- }
-
- var if_stmt = new IfStatement (left, true_block, false_block, source_reference);
-
- insert_statement (insert_block, decl);
- insert_statement (insert_block, if_stmt);
-
- decl.check (context);
-
- if (!if_stmt.check (context)) {
- error = true;
- return false;
- }
-
- var ma = new MemberAccess.simple (local.name, source_reference);
- ma.target_type = target_type;
-
- parent_node.replace_expression (this, ma);
-
- ma.check (context);
-
- return true;
- }
-
- if (operator == BinaryOperator.COALESCE) {
- var local = new LocalVariable (null, get_temp_name (), left, source_reference);
- var decl = new DeclarationStatement (local, source_reference);
-
- var right_stmt = new ExpressionStatement (new Assignment (new MemberAccess.simple (local.name, right.source_reference), right, AssignmentOperator.SIMPLE, right.source_reference), right.source_reference);
-
- var true_block = new Block (source_reference);
-
- true_block.add_statement (right_stmt);
-
- var cond = new BinaryExpression (BinaryOperator.EQUALITY, new MemberAccess.simple (local.name, left.source_reference), new NullLiteral (source_reference), source_reference);
-
- var if_stmt = new IfStatement (cond, true_block, null, source_reference);
-
- insert_statement (insert_block, decl);
- insert_statement (insert_block, if_stmt);
-
- decl.check (context);
-
- if (!if_stmt.check (context)) {
- error = true;
- return false;
- }
-
- var ma = new MemberAccess.simple (local.name, source_reference);
- ma.target_type = target_type;
-
- parent_node.replace_expression (this, ma);
-
- ma.check (context);
-
- return true;
- }
-
if (!left.check (context) || !right.check (context)) {
/* if there were any errors in inner expressions, skip type check */
error = true;
@@ -254,7 +171,11 @@ public class Vala.BinaryExpression : Expression {
right.target_type = right.value_type.copy ();
right.target_type.value_owned = false;
- if (left.value_type.data_type == context.analyzer.string_type.data_type
+ if (operator == BinaryOperator.COALESCE) {
+ left.target_type.nullable = true;
+ right.target_type = left.target_type.copy ();
+ value_type = left.target_type.copy ();
+ } else if (left.value_type.data_type == context.analyzer.string_type.data_type
&& operator == BinaryOperator.PLUS) {
// string concatenation
@@ -488,15 +409,9 @@ public class Vala.BinaryExpression : Expression {
error = true;
return false;
}
-
- var contains_call = new MethodCall (new MemberAccess (right, "contains", source_reference), source_reference);
- contains_call.add_argument (left);
- parent_node.replace_expression (this, contains_call);
- return contains_call.check (context);
}
value_type = context.analyzer.bool_type;
-
} else {
assert_not_reached ();
}
diff --git a/vala/valaforeachstatement.vala b/vala/valaforeachstatement.vala
index 590a1b3..d2a0984 100644
--- a/vala/valaforeachstatement.vala
+++ b/vala/valaforeachstatement.vala
@@ -157,7 +157,7 @@ public class Vala.ForeachStatement : CodeNode, Statement {
array_type.inline_allocated = false;
foreach_iteration = ForeachIteration.ARRAY;
- error = !analyze_element_type (array_type.element_type);
+ error = !analyze_element_type (array_type.element_type, false);
} else if (context.profile == Profile.GOBJECT && (collection_type.compatible (context.analyzer.glist_type) || collection_type.compatible (context.analyzer.gslist_type))) {
if (collection_type.get_type_arguments ().size != 1) {
error = true;
@@ -166,10 +166,10 @@ public class Vala.ForeachStatement : CodeNode, Statement {
}
foreach_iteration = ForeachIteration.GLIST;
- error = !analyze_element_type (collection_type.get_type_arguments ().get (0));
+ error = !analyze_element_type (collection_type.get_type_arguments ().get (0), false);
} else if (context.profile == Profile.GOBJECT && collection_type.compatible (context.analyzer.gvaluearray_type)) {
foreach_iteration = ForeachIteration.GVALUE_ARRAY;
- error = !analyze_element_type (context.analyzer.gvalue_type);
+ error = !analyze_element_type (context.analyzer.gvalue_type, false);
} else {
error = !check_with_iterator (context, collection_type);
}
@@ -201,7 +201,7 @@ public class Vala.ForeachStatement : CodeNode, Statement {
return false;
}
- if (!analyze_element_type (element_type)) {
+ if (!analyze_element_type (element_type, element_type.value_owned)) {
return false;
}
@@ -252,7 +252,7 @@ public class Vala.ForeachStatement : CodeNode, Statement {
return false;
}
- if (!analyze_element_type (element_type)) {
+ if (!analyze_element_type (element_type, element_type.value_owned)) {
return false;
}
@@ -286,7 +286,7 @@ public class Vala.ForeachStatement : CodeNode, Statement {
return false;
}
- if (!analyze_element_type (element_type)) {
+ if (!analyze_element_type (element_type, element_type.value_owned)) {
return false;
}
@@ -296,7 +296,7 @@ public class Vala.ForeachStatement : CodeNode, Statement {
return true;
}
- bool analyze_element_type (DataType element_type) {
+ bool analyze_element_type (DataType element_type, bool get_owned) {
// analyze element type
if (type_reference == null) {
// var type
@@ -305,7 +305,7 @@ public class Vala.ForeachStatement : CodeNode, Statement {
error = true;
Report.error (source_reference, "Foreach: Cannot convert from `%s' to `%s'".printf (element_type.to_string (), type_reference.to_string ()));
return false;
- } else if (element_type.is_disposable () && element_type.value_owned && !type_reference.value_owned) {
+ } else if (get_owned && element_type.is_disposable () && element_type.value_owned && !type_reference.value_owned) {
error = true;
Report.error (source_reference, "Foreach: Invalid assignment from owned expression to unowned variable");
return false;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]