cgen: fix map_complex_high_order_fixed_array (#8329)

pull/8338/head
yuyi 2021-01-25 20:40:53 +08:00 committed by GitHub
parent 965ae9cb91
commit 1c9950c84a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 55 deletions

View File

@ -65,6 +65,7 @@ mut:
is_sql bool // Inside `sql db{}` statement, generating sql instead of C (e.g. `and` instead of `&&` etc) is_sql bool // Inside `sql db{}` statement, generating sql instead of C (e.g. `and` instead of `&&` etc)
is_shared bool // for initialization of hidden mutex in `[rw]shared` literals is_shared bool // for initialization of hidden mutex in `[rw]shared` literals
is_vlines_enabled bool // is it safe to generate #line directives when -g is passed is_vlines_enabled bool // is it safe to generate #line directives when -g is passed
array_set_pos int
vlines_path string // set to the proper path for generating #line directives vlines_path string // set to the proper path for generating #line directives
optionals []string // to avoid duplicates TODO perf, use map optionals []string // to avoid duplicates TODO perf, use map
chan_pop_optionals []string // types for `x := <-ch or {...}` chan_pop_optionals []string // types for `x := <-ch or {...}`
@ -1976,57 +1977,28 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
} }
} else if is_fixed_array_init && assign_stmt.op == .assign { } else if is_fixed_array_init && assign_stmt.op == .assign {
right := val as ast.ArrayInit right := val as ast.ArrayInit
if right.has_val { v_var := g.new_tmp_var()
for j, expr in right.exprs { arr_typ := styp.trim('*')
if !is_decl && left is ast.Ident g.write('$arr_typ $v_var = ')
&& g.for_in_mul_val_name == (left as ast.Ident).name { g.expr(right)
g.write('(*')
g.expr(left)
g.write(')')
} else {
g.expr(left)
}
if g.is_array_set {
g.out.go_back(2)
} else {
g.write('[$j] = ')
}
g.expr(expr)
if g.is_array_set {
g.writeln(')')
g.is_array_set = false
} else {
g.writeln(';') g.writeln(';')
} pos := g.out.len
}
} else {
fixed_array := right_sym.info as table.ArrayFixed
for j in 0 .. fixed_array.size {
if !is_decl && left is ast.Ident
&& g.for_in_mul_val_name == (left as ast.Ident).name {
g.write('(*')
g.expr(left) g.expr(left)
g.write(')')
} else { if g.is_array_set && g.array_set_pos > 0 {
g.expr(left) g.out.go_back_to(g.array_set_pos)
} g.write(', &$v_var)')
if g.is_array_set {
g.out.go_back(2)
} else {
g.write('[$j] = ')
}
if right.has_default {
g.expr(right.default_expr)
} else {
g.write(g.type_default(right.elem_type))
}
if g.is_array_set {
g.writeln(')')
g.is_array_set = false g.is_array_set = false
g.array_set_pos = 0
} else { } else {
g.writeln(';') g.out.go_back_to(pos)
} is_var_mut := !is_decl && left is ast.Ident
} && g.for_in_mul_val_name == (left as ast.Ident).name
addr := if is_var_mut { '' } else { '&' }
g.writeln('')
g.write('memcpy($addr')
g.expr(left)
g.writeln(', &$v_var, sizeof($arr_typ));')
} }
g.is_assign_lhs = false g.is_assign_lhs = false
} else { } else {
@ -4271,6 +4243,7 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
if elem_typ.kind == .function { if elem_typ.kind == .function {
g.write(', &(voidptr[]) { ') g.write(', &(voidptr[]) { ')
} else { } else {
g.array_set_pos = g.out.len
g.write(', &($elem_type_str[]) { ') g.write(', &($elem_type_str[]) { ')
} }
if g.assign_op != .assign && info.value_type != table.string_type { if g.assign_op != .assign && info.value_type != table.string_type {

View File

@ -17,3 +17,12 @@ fn test_innermost_value_of_map_fixed_array() {
assert m['foo'][0][0]['bar'] == 1 assert m['foo'][0][0]['bar'] == 1
assert '${m['foo'][0][0]['bar']}' == '1' assert '${m['foo'][0][0]['bar']}' == '1'
} }
fn test_complex_map_high_order_fixed_array() {
mut m := {'foo': [[{'a': 1}]!]!, 'bar': [[{'b': 2}]!]!}
for _, mut j in m {
j = [[{'c': 3}]!]!
}
println(m)
assert '$m' == "{'foo': [[{'c': 3}]], 'bar': [[{'c': 3}]]}"
}