]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Add experimental support for chained relational expressions
authorJürg Billeter <j@bitron.ch>
Sun, 24 Jan 2010 12:37:49 +0000 (13:37 +0100)
committerJürg Billeter <j@bitron.ch>
Sun, 21 Mar 2010 21:19:22 +0000 (22:19 +0100)
Based on patch by Marc-André Lureau, fixes bug 606480.

codegen/valaccodebasemodule.vala
vala/valabinaryexpression.vala
vala/valaparser.vala

index a6f2701ae9144effe6a1a7e06589ac499ed131b0..0c0e00be1d29615ddafa42311c2bcead6d46fd2a 100644 (file)
@@ -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) {
index f6f7b87eceb96191ff5bfb33553a5de8a8f36933..6b579b1dde4c386c5c02322aa8e0cec32dfe71d9 100644 (file)
@@ -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;
index e42286d77eb01f38010af4230b6abb3d85781c69..4de43ec25e29b0e9c8083c77166c24ed0d430a46 100644 (file)
@@ -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;