]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
test postfix and prefix expressions update support prefix and postfix
authorJürg Billeter <j@bitron.ch>
Mon, 26 Feb 2007 22:18:58 +0000 (22:18 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Mon, 26 Feb 2007 22:18:58 +0000 (22:18 +0000)
2007-02-26  Jürg Billeter  <j@bitron.ch>

* tests/test-027.vala, tests/test-027.out: test postfix and prefix
  expressions
* tests/Makefile.am: update
* vala/valasemanticanalyzer.vala, vala/valacodegenerator.vala: support
  prefix and postfix expressions for properties and parenthesized
  expressions

svn path=/trunk/; revision=199

vala/ChangeLog
vala/tests/Makefile.am
vala/tests/test-027.out [new file with mode: 0644]
vala/tests/test-027.vala [new file with mode: 0644]
vala/vala/valacodegenerator.vala
vala/vala/valasemanticanalyzer.vala

index 7bd8a3e31db7ae71725eb06ed21cccf61af56fbe..87d66345236b2b4504f691d408f5b03e69ac467e 100644 (file)
@@ -1,3 +1,12 @@
+2007-02-26  Jürg Billeter  <j@bitron.ch>
+
+       * tests/test-027.vala, tests/test-027.out: test postfix and prefix
+         expressions
+       * tests/Makefile.am: update
+       * vala/valasemanticanalyzer.vala, vala/valacodegenerator.vala: support
+         prefix and postfix expressions for properties and parenthesized
+         expressions
+
 2007-02-25  Jürg Billeter  <j@bitron.ch>
 
        * vala/valasemanticanalyzer.vala, vala/valacodegenerator.vala: improve
index 182b7121f2fc219c3a3f45219b4236a0e77d2e30..ca342fd685ead2dc1661db2559b6f6a34c6433cb 100644 (file)
@@ -29,6 +29,7 @@ TESTS = \
        test-024.vala \
        test-025.vala \
        test-026.vala \
+       test-027.vala \
        $(NULL)
 
 EXTRA_DIST = \
@@ -60,4 +61,5 @@ EXTRA_DIST = \
        test-024.out \
        test-025.out \
        test-026.out \
+       test-027.out \
        $(NULL)
diff --git a/vala/tests/test-027.out b/vala/tests/test-027.out
new file mode 100644 (file)
index 0000000..2d82880
--- /dev/null
@@ -0,0 +1 @@
+Postfix and Prefix Expression Test: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
diff --git a/vala/tests/test-027.vala b/vala/tests/test-027.vala
new file mode 100644 (file)
index 0000000..e01bdd4
--- /dev/null
@@ -0,0 +1,60 @@
+using GLib;
+
+class Maman.Bar {
+       public int foo { get; set; }
+
+       public void run () {
+               /* test with local variable */
+               int i = 1;
+               stdout.printf (" %d", ++i);
+
+               stdout.printf (" %d", i + 1);
+
+               i = 4;
+               stdout.printf (" %d", i++);
+               
+               stdout.printf (" %d", i);
+
+               i = 7;
+               stdout.printf (" %d", --(i));
+
+               stdout.printf (" %d", i + 1);
+
+               i = 8;
+               stdout.printf (" %d", (i)--);
+
+               stdout.printf (" %d", i + 2);
+
+               /* test with field */
+               foo = 9;
+               stdout.printf (" %d", ++foo);
+
+               stdout.printf (" %d", foo + 1);
+
+               foo = 12;
+               stdout.printf (" %d", foo++);
+               
+               stdout.printf (" %d", foo);
+
+               foo = 15;
+               stdout.printf (" %d", --(foo));
+
+               stdout.printf (" %d", foo + 1);
+
+               foo = 16;
+               stdout.printf (" %d", (foo)--);
+
+               stdout.printf (" %d", foo + 2);
+       }
+
+       static int main (string[] args) {
+               stdout.printf ("Postfix and Prefix Expression Test: 1");
+               
+               var bar = new Bar ();
+               bar.run ();
+
+               stdout.printf (" 18\n");
+               
+               return 0;
+       }
+}
index 6ea39a3d1414b0c986a9c6f08b2c381b3dc62264..198d4e51d52f494dee91293c878e1f7362284333 100644 (file)
@@ -3025,6 +3025,31 @@ public class Vala.CodeGenerator : CodeVisitor {
        }
 
        public override void visit_postfix_expression (PostfixExpression! expr) {
+               MemberAccess ma = find_property_access (expr.inner);
+               if (ma != null) {
+                       // property postfix expression
+                       var prop = (Property) ma.symbol_reference.node;
+                       
+                       var ccomma = new CCodeCommaExpression ();
+                       
+                       // assign current value to temp variable
+                       var temp_decl = get_temp_variable_declarator (prop.type_reference);
+                       temp_vars.prepend (temp_decl);
+                       ccomma.append_expression (new CCodeAssignment (new CCodeIdentifier (temp_decl.name), (CCodeExpression) expr.inner.ccodenode));
+                       
+                       // increment/decrement property
+                       var op = expr.increment ? CCodeBinaryOperator.PLUS : CCodeBinaryOperator.MINUS;
+                       var cexpr = new CCodeBinaryExpression (op, new CCodeIdentifier (temp_decl.name), new CCodeConstant ("1"));
+                       var ccall = get_property_set_call (prop, ma, cexpr);
+                       ccomma.append_expression (ccall);
+                       
+                       // return previous value
+                       ccomma.append_expression (new CCodeIdentifier (temp_decl.name));
+                       
+                       expr.ccodenode = ccomma;
+                       return;
+               }
+       
                var op = expr.increment ? CCodeUnaryOperator.POSTFIX_INCREMENT : CCodeUnaryOperator.POSTFIX_DECREMENT;
        
                expr.ccodenode = new CCodeUnaryExpression (op, (CCodeExpression) expr.inner.ccodenode);
@@ -3032,6 +3057,24 @@ public class Vala.CodeGenerator : CodeVisitor {
                visit_expression (expr);
        }
        
+       private MemberAccess find_property_access (Expression! expr) {
+               if (expr is ParenthesizedExpression) {
+                       var pe = (ParenthesizedExpression) expr;
+                       return find_property_access (pe.inner);
+               }
+       
+               if (!(expr is MemberAccess)) {
+                       return null;
+               }
+               
+               var ma = (MemberAccess) expr;
+               if (ma.symbol_reference.node is Property) {
+                       return ma;
+               }
+               
+               return null;
+       }
+       
        private ref CCodeExpression get_ref_expression (Expression! expr) {
                /* (temp = expr, temp == NULL ? NULL : ref (temp))
                 *
@@ -3324,7 +3367,6 @@ public class Vala.CodeGenerator : CodeVisitor {
 
                if (a.left.symbol_reference != null && a.left.symbol_reference.node is Property) {
                        var prop = (Property) a.left.symbol_reference.node;
-                       var cl = (Class) prop.symbol.parent_symbol.node;
                        
                        if (ma.inner == null && a.parent_node is Statement &&
                            ((Statement) a.parent_node).construction) {
@@ -3356,43 +3398,10 @@ public class Vala.CodeGenerator : CodeVisitor {
                                
                                a.ccodenode = ccomma;
                        } else {
-                               var set_func = "g_object_set";
-                               
-                               if (!prop.no_accessor_method) {
-                                       set_func = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
-                               }
-                               
-                               var ccall = new CCodeFunctionCall (new CCodeIdentifier (set_func));
-
-                               /* target instance is first argument */
-                               ref CCodeExpression instance;
-                               var req_cast = false;
-
-                               if (ma.inner == null) {
-                                       instance = new CCodeIdentifier ("self");
-                                       /* require casts for inherited properties */
-                                       req_cast = (prop.symbol.parent_symbol != current_type_symbol);
-                               } else {
-                                       instance = (CCodeExpression) ma.inner.ccodenode;
-                                       /* require casts if the type of the used instance is
-                                        * different than the type which declared the property */
-                                       req_cast = prop.symbol.parent_symbol.node != ma.inner.static_type.data_type;
-                               }
-                               
-                               if (req_cast && ((DataType) prop.symbol.parent_symbol.node).is_reference_type ()) {
-                                       var ccast = new CCodeFunctionCall (new CCodeIdentifier (((DataType) prop.symbol.parent_symbol.node).get_upper_case_cname (null)));
-                                       ccast.add_argument (instance);
-                                       instance = ccast;
-                               }
-
-                               ccall.add_argument (instance);
-                                       
                                ref CCodeExpression cexpr = (CCodeExpression) a.right.ccodenode;
                                
-                               if (prop.no_accessor_method) {
-                                       /* property name is second argument of g_object_set */
-                                       ccall.add_argument (prop.get_canonical_cconstant ());
-                               } else if (prop.type_reference.data_type != null
+                               if (!prop.no_accessor_method
+                                   && prop.type_reference.data_type != null
                                    && prop.type_reference.data_type.is_reference_type ()
                                    && a.right.static_type.data_type != null
                                    && prop.type_reference.data_type != a.right.static_type.data_type) {
@@ -3427,14 +3436,15 @@ public class Vala.CodeGenerator : CodeVisitor {
                                        }
                                        cexpr = new CCodeBinaryExpression (cop, (CCodeExpression) a.left.ccodenode, new CCodeParenthesizedExpression (cexpr));
                                }
-                                       
-                               ccall.add_argument (cexpr);
                                
-                               if (prop.no_accessor_method) {
-                                       ccall.add_argument (new CCodeConstant ("NULL"));
-                               }
+                               var ccall = get_property_set_call (prop, ma, cexpr);
+                               
+                               // assignments are expressions, so return the current property value
+                               var ccomma = new CCodeCommaExpression ();
+                               ccomma.append_expression (ccall); // update property
+                               ccomma.append_expression ((CCodeExpression) ma.ccodenode); // current property value
                                
-                               a.ccodenode = ccall;
+                               a.ccodenode = ccomma;
                        }
                } else if (a.left.symbol_reference != null && a.left.symbol_reference.node is Signal) {
                        var sig = (Signal) a.left.symbol_reference.node;
@@ -3543,4 +3553,51 @@ public class Vala.CodeGenerator : CodeVisitor {
                        a.ccodenode = new CCodeAssignment ((CCodeExpression) a.left.ccodenode, rhs, cop);
                }
        }
+       
+       private ref CCodeFunctionCall get_property_set_call (Property! prop, MemberAccess! ma, CCodeExpression! cexpr) {
+               var cl = (Class) prop.symbol.parent_symbol.node;
+               var set_func = "g_object_set";
+               
+               if (!prop.no_accessor_method) {
+                       set_func = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
+               }
+               
+               var ccall = new CCodeFunctionCall (new CCodeIdentifier (set_func));
+
+               /* target instance is first argument */
+               ref CCodeExpression instance;
+               var req_cast = false;
+
+               if (ma.inner == null) {
+                       instance = new CCodeIdentifier ("self");
+                       /* require casts for inherited properties */
+                       req_cast = (prop.symbol.parent_symbol != current_type_symbol);
+               } else {
+                       instance = (CCodeExpression) ma.inner.ccodenode;
+                       /* require casts if the type of the used instance is
+                        * different than the type which declared the property */
+                       req_cast = prop.symbol.parent_symbol.node != ma.inner.static_type.data_type;
+               }
+               
+               if (req_cast && ((DataType) prop.symbol.parent_symbol.node).is_reference_type ()) {
+                       var ccast = new CCodeFunctionCall (new CCodeIdentifier (((DataType) prop.symbol.parent_symbol.node).get_upper_case_cname (null)));
+                       ccast.add_argument (instance);
+                       instance = ccast;
+               }
+
+               ccall.add_argument (instance);
+
+               if (prop.no_accessor_method) {
+                       /* property name is second argument of g_object_set */
+                       ccall.add_argument (prop.get_canonical_cconstant ());
+               }
+                       
+               ccall.add_argument (cexpr);
+               
+               if (prop.no_accessor_method) {
+                       ccall.add_argument (new CCodeConstant ("NULL"));
+               }
+
+               return ccall;
+       }
 }
index 0057a6ef0dd4cc8dd8fbed53ff2990590900c928..5d32d39ea8d1536cbca75143447a35f9ae858a5f 100644 (file)
@@ -1255,18 +1255,17 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                                return;
                        }
                        
-                       if (!(expr.inner is MemberAccess)) {
+                       var ma = find_member_access (expr.inner);
+                       if (ma == null) {
                                expr.error = true;
-                               Report.error (expr.source_reference, "Prefix operators currently not supported for this expression");
+                               Report.error (expr.source_reference, "Prefix operators not supported for this expression");
                                return;
                        }
                        
-                       var ma = (MemberAccess) expr.inner;
-                       
                        var old_value = new MemberAccess (ma.inner, ma.member_name);
                        var bin = new BinaryExpression (expr.operator == UnaryOperator.INCREMENT ? BinaryOperator.PLUS : BinaryOperator.MINUS, old_value, new LiteralExpression (new IntegerLiteral ("1")));
                        
-                       var assignment = new Assignment (expr.inner, bin);
+                       var assignment = new Assignment (ma, bin);
                        expr.parent_node.replace (expr, assignment);
                        assignment.accept (this);
                        return;
@@ -1284,6 +1283,19 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        return;
                }
        }
+       
+       private MemberAccess find_member_access (Expression! expr) {
+               if (expr is ParenthesizedExpression) {
+                       var pe = (ParenthesizedExpression) expr;
+                       return find_member_access (pe.inner);
+               }
+               
+               if (expr is MemberAccess) {
+                       return (MemberAccess) expr;
+               }
+               
+               return null;
+       }
 
        public override void visit_cast_expression (CastExpression! expr) {
                if (expr.type_reference.data_type == null) {