[vala] Add experimental support for chained relational expressions



commit 4f0216a58bcf0b37ed96d7b45f40cca3de2d083e
Author: Jürg Billeter <j bitron ch>
Date:   Sun Jan 24 13:37:49 2010 +0100

    Add experimental support for chained relational expressions
    
    Based on patch by Marc-André Lureau, fixes bug 606480.

 codegen/valaccodebasemodule.vala |   24 +++++++++++++++++++++++-
 vala/valabinaryexpression.vala   |   11 ++++++++++-
 vala/valaparser.vala             |   18 ++++++++++++++++++
 3 files changed, 51 insertions(+), 2 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index a6f2701..0c0e00b 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -4499,7 +4499,26 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 
 		var cleft = (CCodeExpression) expr.left.ccodenode;
 		var cright = (CCodeExpression) expr.right.ccodenode;
-		
+
+		CCodeExpression? left_chain = null;
+		if (expr.chained) {
+			var lbe = (BinaryExpression) expr.left;
+
+			var temp_decl = get_temp_variable (lbe.right.value_type, true, null, false);
+			temp_vars.insert (0, temp_decl);
+			var cvar = get_variable_cexpression (temp_decl.name);
+			var ccomma = new CCodeCommaExpression ();
+			var clbe = (CCodeBinaryExpression) lbe.ccodenode;
+			if (lbe.chained) {
+				clbe = (CCodeBinaryExpression) clbe.right;
+			}
+			ccomma.append_expression (new CCodeAssignment (cvar, (CCodeExpression)lbe.right.ccodenode));
+			clbe.right = get_variable_cexpression (temp_decl.name);
+			ccomma.append_expression (cleft);
+			cleft = cvar;
+			left_chain = ccomma;
+		}
+
 		CCodeBinaryOperator op;
 		if (expr.operator == BinaryOperator.PLUS) {
 			op = CCodeBinaryOperator.PLUS;
@@ -4670,6 +4689,9 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 		}
 
 		expr.ccodenode = new CCodeBinaryExpression (op, cleft, cright);
+		if (left_chain != null) {
+			expr.ccodenode = new CCodeBinaryExpression (CCodeBinaryOperator.AND, left_chain, (CCodeExpression) expr.ccodenode);
+		}
 	}
 
 	public string? get_type_check_function (TypeSymbol type) {
diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala
index f6f7b87..6b579b1 100644
--- a/vala/valabinaryexpression.vala
+++ b/vala/valabinaryexpression.vala
@@ -58,6 +58,8 @@ public class Vala.BinaryExpression : Expression {
 		}
 	}
 	
+	public bool chained;
+
 	private Expression _left;
 	private Expression _right;
 	
@@ -334,7 +336,14 @@ public class Vala.BinaryExpression : Expression {
 				} else if (left.value_type is PointerType && right.value_type is PointerType) {
 					// pointer arithmetic
 			} else {
-				var resulting_type = analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
+				DataType resulting_type;
+
+				if (chained) {
+					var lbe = (BinaryExpression) left;
+					resulting_type = analyzer.get_arithmetic_result_type (lbe.right.value_type, right.value_type);
+				} else {
+					resulting_type = analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
+				}
 
 				if (resulting_type == null) {
 					error = true;
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index e42286d..4de43ec 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -1118,6 +1118,8 @@ public class Vala.Parser : CodeVisitor {
 	Expression parse_relational_expression () throws ParseError {
 		var begin = get_location ();
 		var left = parse_shift_expression ();
+
+		bool first = true;
 		bool found = true;
 		while (found) {
 			var operator = get_binary_operator (current ());
@@ -1128,6 +1130,14 @@ public class Vala.Parser : CodeVisitor {
 				next ();
 				var right = parse_shift_expression ();
 				left = new BinaryExpression (operator, left, right, get_src (begin));
+				if (!first) {
+					var be = (BinaryExpression) left;
+					be.chained = true;
+					if (!context.experimental) {
+						Report.warning (left.source_reference, "chained relational expressions are experimental");
+					}
+				}
+				first = false;
 				break;
 			case BinaryOperator.GREATER_THAN:
 				next ();
@@ -1135,6 +1145,14 @@ public class Vala.Parser : CodeVisitor {
 				if (current () != TokenType.OP_GT && current () != TokenType.OP_GE) {
 					var right = parse_shift_expression ();
 					left = new BinaryExpression (operator, left, right, get_src (begin));
+					if (!first) {
+						var be = (BinaryExpression) left;
+						be.chained = true;
+						if (!context.experimental) {
+							Report.warning (left.source_reference, "chained relational expressions are experimental");
+						}
+					}
+					first = false;
 				} else {
 					prev ();
 					found = false;



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