diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 5d62d7da01..1a7e36a5e3 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1414,37 +1414,52 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) { } } } else if node.kind == .array_fixed { - atmp := g.new_tmp_var() - atmp_type := g.typ(node.cond_type).trim('*') - if node.cond_type.is_ptr() || node.cond is ast.ArrayInit { + mut cond_var := '' + needs_tmp_var := node.cond_type.is_ptr() || node.cond is ast.ArrayInit + if needs_tmp_var { + cond_var = g.new_tmp_var() + cond_var_type := g.typ(node.cond_type).trim('*') if !node.cond.is_lvalue() { - g.write('$atmp_type *$atmp = (($atmp_type)') + g.write('$cond_var_type *$cond_var = (($cond_var_type)') } else { - g.write('$atmp_type *$atmp = (') + g.write('$cond_var_type *$cond_var = (') } g.expr(node.cond) g.writeln(');') + } else { + pos := g.out.len + g.expr(node.cond) + cond_var = g.out.after(pos) + g.out.go_back(cond_var.len) + cond_var = cond_var.trim_space() } - i := if node.key_var in ['', '_'] { g.new_tmp_var() } else { node.key_var } + idx := if node.key_var in ['', '_'] { g.new_tmp_var() } else { node.key_var } cond_sym := g.table.get_type_symbol(node.cond_type) info := cond_sym.info as table.ArrayFixed - g.writeln('for (int $i = 0; $i != $info.size; ++$i) {') + g.writeln('for (int $idx = 0; $idx != $info.size; ++$idx) {') if node.val_var != '_' { val_sym := g.table.get_type_symbol(node.val_type) + is_fixed_array := val_sym.kind == .array_fixed && !node.val_is_mut if val_sym.kind == .function { g.write('\t') g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(node.val_var)) + } else if is_fixed_array { + styp := g.typ(node.val_type) + g.writeln('\t$styp ${c_name(node.val_var)};') + g.writeln('\tmemcpy(*($styp*)${c_name(node.val_var)}, (byte*)$cond_var[$idx], sizeof($styp));') } else { styp := g.typ(node.val_type) g.write('\t$styp ${c_name(node.val_var)}') } - addr := if node.val_is_mut { '&' } else { '' } - if node.cond_type.is_ptr() || node.cond is ast.ArrayInit { - g.writeln(' = ${addr}(*$atmp)[$i];') - } else { - g.write(' = $addr') - g.expr(node.cond) - g.writeln('[$i];') + if !is_fixed_array { + addr := if node.val_is_mut { '&' } else { '' } + if needs_tmp_var { + g.writeln(' = ${addr}(*$cond_var)[$idx];') + } else { + g.write(' = $addr') + g.expr(node.cond) + g.writeln('[$idx];') + } } } } else if node.kind == .map { diff --git a/vlib/v/tests/for_in_containers_of_fixed_array_test.v b/vlib/v/tests/for_in_containers_of_fixed_array_test.v index 6c04b84fa8..57faff0746 100644 --- a/vlib/v/tests/for_in_containers_of_fixed_array_test.v +++ b/vlib/v/tests/for_in_containers_of_fixed_array_test.v @@ -1,4 +1,4 @@ -fn test_for_in_containers_of_fixed_array() { +fn test_for_in_array_of_fixed_array() { mut rets := []string{} arr := [][2]int{len: 3} @@ -11,7 +11,7 @@ fn test_for_in_containers_of_fixed_array() { assert rets[2] == '[0, 0]' } -fn test_for_mut_in_containers_of_fixed_array() { +fn test_for_mut_in_array_of_fixed_array() { mut rets := []string{} mut arr := [][2]int{len: 3} @@ -23,3 +23,29 @@ fn test_for_mut_in_containers_of_fixed_array() { assert rets[1] == '[0, 0]' assert rets[2] == '[0, 0]' } + +fn test_for_in_fixed_array_of_fixed_array() { + mut rets := []string{} + arr := [[1, 2]!, [3, 4]!, [5, 6]!]! + + for pair in arr { + println(pair) + rets << '$pair' + } + assert rets[0] == '[1, 2]' + assert rets[1] == '[3, 4]' + assert rets[2] == '[5, 6]' +} + +fn test_for_mut_in_fixed_array_of_fixed_array() { + mut rets := []string{} + mut arr := [[1, 2]!, [3, 4]!, [5, 6]!]! + + for mut pair in arr { + println(pair) + rets << '$pair' + } + assert rets[0] == '[1, 2]' + assert rets[1] == '[3, 4]' + assert rets[2] == '[5, 6]' +}