diff options
author | Mark Lee <marklee@src.gnome.org> | 2009-07-15 23:33:39 -0700 |
---|---|---|
committer | Jürg Billeter <j@bitron.ch> | 2009-07-28 16:03:33 +0200 |
commit | 3e2f5122592151a81079ccc7e410864c99edfecc (patch) | |
tree | e2065f91a4109f569573f17dbfdb63df5224b2a3 /codegen/valaccodecontrolflowmodule.vala | |
parent | 3ae7deee30862c281ec43e947a9bc99e861cbd4f (diff) | |
download | vala-3e2f5122592151a81079ccc7e410864c99edfecc.tar.gz |
Add support for iterating over GValueArrays via foreach
Implements working support for using ValueArrays in foreach statements. Both
owned and unowned Value element types are implemented, including a testcase.
Example:
void print_array (ValueArray array) {
foreach (Value value in array) {
message ("Value: %s", value.strdup_contents ());
}
}
Fixes bug 588742.
Diffstat (limited to 'codegen/valaccodecontrolflowmodule.vala')
-rw-r--r-- | codegen/valaccodecontrolflowmodule.vala | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/codegen/valaccodecontrolflowmodule.vala b/codegen/valaccodecontrolflowmodule.vala index 86a98e3db..19a30a058 100644 --- a/codegen/valaccodecontrolflowmodule.vala +++ b/codegen/valaccodecontrolflowmodule.vala @@ -402,6 +402,60 @@ internal class Vala.CCodeControlFlowModule : CCodeMethodModule { cfor.add_iterator (new CCodeAssignment (get_variable_cexpression (it_name), new CCodeMemberAccess.pointer (get_variable_cexpression (it_name), "next"))); cblock.add_statement (cfor); + } else if (stmt.collection.value_type.compatible (new ObjectType (gvaluearray_type))) { + // iterating over a GValueArray + + var arr_index = "%s_index".printf (stmt.variable_name); + + if (current_method != null && current_method.coroutine) { + closure_struct.add_field (uint_type.get_cname (), arr_index); + } else { + var citdecl = new CCodeDeclaration (uint_type.get_cname ()); + var citvardecl = new CCodeVariableDeclarator (arr_index); + citvardecl.line = cblock.line; + citdecl.add_declarator (citvardecl); + cblock.add_statement (citdecl); + } + + var cbody = new CCodeBlock (); + + var get_item = new CCodeFunctionCall (new CCodeIdentifier ("g_value_array_get_nth")); + get_item.add_argument (get_variable_cexpression (collection_backup.name)); + get_item.add_argument (get_variable_cexpression (arr_index)); + + CCodeExpression element_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_item); + + if (stmt.type_reference.value_owned) { + element_expr = get_ref_cexpression (stmt.type_reference, element_expr, null, new StructValueType (gvalue_type)); + } + + cfrag = new CCodeFragment (); + append_temp_decl (cfrag, temp_vars); + cbody.add_statement (cfrag); + temp_vars.clear (); + + if (current_method != null && current_method.coroutine) { + closure_struct.add_field (stmt.type_reference.get_cname (), stmt.variable_name); + cbody.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (stmt.variable_name), element_expr))); + } else { + var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ()); + var cvardecl = new CCodeVariableDeclarator (stmt.variable_name, element_expr); + cvardecl.line = cblock.line; + cdecl.add_declarator (cvardecl); + cbody.add_statement (cdecl); + } + + cbody.add_statement (stmt.body.ccodenode); + + var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (arr_index), new CCodeMemberAccess.pointer (get_variable_cexpression (collection_backup.name), "n_values")); + + var cfor = new CCodeForStatement (ccond, cbody); + + cfor.add_initializer (new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeConstant ("0"))); + + cfor.add_iterator (new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (arr_index), new CCodeConstant ("1")))); + + cblock.add_statement (cfor); } foreach (LocalVariable local in stmt.get_local_variables ()) { |