cgen: fix for_in map of fixed_array (#9133)

pull/8667/head^2
yuyi 2021-03-07 17:41:08 +08:00 committed by GitHub
parent ba95995a51
commit 82085b0140
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 22 deletions

View File

@ -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 < ')

View File

@ -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]'
}