summaryrefslogtreecommitdiff
path: root/codegen/valaccodecontrolflowmodule.vala
diff options
context:
space:
mode:
authorMark Lee <marklee@src.gnome.org>2009-07-15 23:33:39 -0700
committerJürg Billeter <j@bitron.ch>2009-07-28 16:03:33 +0200
commit3e2f5122592151a81079ccc7e410864c99edfecc (patch)
treee2065f91a4109f569573f17dbfdb63df5224b2a3 /codegen/valaccodecontrolflowmodule.vala
parent3ae7deee30862c281ec43e947a9bc99e861cbd4f (diff)
downloadvala-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.vala54
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 ()) {