cgen: fix for_in map of fixed_array (#9133)
parent
ba95995a51
commit
82085b0140
|
@ -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()
|
||||
arw_or_pt := if node.cond_type.is_ptr() { '->' } else { '.' }
|
||||
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(' $atmp = ')
|
||||
g.write(' $cond_var = ')
|
||||
g.expr(node.cond)
|
||||
g.writeln(';')
|
||||
g.writeln('for (int $idx = 0; $idx < $atmp${arw_or_pt}key_values.len; ++$idx) {')
|
||||
}
|
||||
arw_or_pt := if node.cond_type.is_ptr() { '->' } else { '.' }
|
||||
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 < ')
|
||||
|
|
|
@ -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]'
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue