diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 63b1620da8..98b09a015e 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1467,20 +1467,30 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) { } else if node.kind == .map { // `for key, val in map { g.writeln('// FOR IN map') - idx := g.new_tmp_var() - atmp := g.new_tmp_var() + mut cond_var := '' + if node.cond is ast.Ident { + 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() + } else { + cond_var = g.new_tmp_var() + g.write(g.typ(node.cond_type)) + g.write(' $cond_var = ') + g.expr(node.cond) + g.writeln(';') + } arw_or_pt := if node.cond_type.is_ptr() { '->' } else { '.' } - g.write(g.typ(node.cond_type)) - g.write(' $atmp = ') - g.expr(node.cond) - g.writeln(';') - g.writeln('for (int $idx = 0; $idx < $atmp${arw_or_pt}key_values.len; ++$idx) {') + idx := g.new_tmp_var() + g.empty_line = true + g.writeln('for (int $idx = 0; $idx < $cond_var${arw_or_pt}key_values.len; ++$idx) {') // TODO: don't have this check when the map has no deleted elements - g.writeln('\tif (!DenseArray_has_index(&$atmp${arw_or_pt}key_values, $idx)) {continue;}') + g.writeln('\tif (!DenseArray_has_index(&$cond_var${arw_or_pt}key_values, $idx)) {continue;}') if node.key_var != '_' { key_styp := g.typ(node.key_type) key := c_name(node.key_var) - g.writeln('\t$key_styp $key = /*key*/ *($key_styp*)DenseArray_key(&$atmp${arw_or_pt}key_values, $idx);') + g.writeln('\t$key_styp $key = /*key*/ *($key_styp*)DenseArray_key(&$cond_var${arw_or_pt}key_values, $idx);') // TODO: analyze whether node.key_type has a .clone() method and call .clone() for all types: if node.key_type == table.string_type { g.writeln('\t$key = string_clone($key);') @@ -1492,6 +1502,11 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) { g.write('\t') g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(node.val_var)) g.write(' = (*(voidptr*)') + g.writeln('DenseArray_value(&$cond_var${arw_or_pt}key_values, $idx));') + } else if val_sym.kind == .array_fixed && !node.val_is_mut { + val_styp := g.typ(node.val_type) + g.writeln('\t$val_styp ${c_name(node.val_var)};') + g.writeln('\tmemcpy(*($val_styp*)${c_name(node.val_var)}, (byte*)DenseArray_value(&$cond_var${arw_or_pt}key_values, $idx), sizeof($val_styp));') } else { val_styp := g.typ(node.val_type) if node.val_type.is_ptr() { @@ -1499,21 +1514,9 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) { } else { g.write('\t$val_styp ${c_name(node.val_var)} = (*($val_styp*)') } + g.writeln('DenseArray_value(&$cond_var${arw_or_pt}key_values, $idx));') } - g.writeln('DenseArray_value(&$atmp${arw_or_pt}key_values, $idx));') } - g.stmts(node.stmts) - if node.key_type == table.string_type && !g.is_builtin_mod { - // g.writeln('string_free(&$key);') - } - if node.label.len > 0 { - g.writeln('\t${node.label}__continue: {}') - } - g.writeln('}') - if node.label.len > 0 { - g.writeln('\t${node.label}__break: {}') - } - return } else if node.kind == .string { i := if node.key_var in ['', '_'] { g.new_tmp_var() } else { node.key_var } g.write('for (int $i = 0; $i < ') 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 57faff0746..9780b61a2c 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 @@ -49,3 +49,29 @@ fn test_for_mut_in_fixed_array_of_fixed_array() { assert rets[1] == '[3, 4]' assert rets[2] == '[5, 6]' } + +fn test_for_in_map_of_fixed_array() { + mut rets := []string{} + m := map{'aa': [1, 2]!, 'bb': [3, 4]!, 'cc': [5, 6]!} + + for k, v in m { + println('$k, $v') + rets << '$k, $v' + } + assert rets[0] == 'aa, [1, 2]' + assert rets[1] == 'bb, [3, 4]' + assert rets[2] == 'cc, [5, 6]' +} + +fn test_for_mut_in_map_of_fixed_array() { + mut rets := []string{} + mut m := map{'aa': [1, 2]!, 'bb': [3, 4]!, 'cc': [5, 6]!} + + for k, mut v in m { + println('$k, $v') + rets << '$k, $v' + } + assert rets[0] == 'aa, [1, 2]' + assert rets[1] == 'bb, [3, 4]' + assert rets[2] == 'cc, [5, 6]' +}