From 4f0216a58bcf0b37ed96d7b45f40cca3de2d083e Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=BCrg=20Billeter?= Date: Sun, 24 Jan 2010 13:37:49 +0100 Subject: [PATCH] Add experimental support for chained relational expressions MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 a6f2701ae..0c0e00be1 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 f6f7b87ec..6b579b1dd 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 e42286d77..4de43ec25 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; -- 2.47.3