--- /dev/null
+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;
+ }
+}
}
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);
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))
*
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) {
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) {
}
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;
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;
+ }
}
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;
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) {