cgen: fix map_complex_high_order_fixed_array (#8329)
parent
965ae9cb91
commit
1c9950c84a
|
@ -61,10 +61,11 @@ mut:
|
||||||
is_assign_lhs bool // inside left part of assign expr (for array_set(), etc)
|
is_assign_lhs bool // inside left part of assign expr (for array_set(), etc)
|
||||||
is_assign_rhs bool // inside right part of assign after `=` (val expr)
|
is_assign_rhs bool // inside right part of assign after `=` (val expr)
|
||||||
is_array_set bool
|
is_array_set bool
|
||||||
is_amp bool // for `&Foo{}` to merge PrefixExpr `&` and StructInit `Foo{}`; also for `&byte(0)` etc
|
is_amp bool // for `&Foo{}` to merge PrefixExpr `&` and StructInit `Foo{}`; also for `&byte(0)` etc
|
||||||
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.writeln(';')
|
||||||
g.expr(left)
|
pos := g.out.len
|
||||||
g.write(')')
|
g.expr(left)
|
||||||
} else {
|
|
||||||
g.expr(left)
|
if g.is_array_set && g.array_set_pos > 0 {
|
||||||
}
|
g.out.go_back_to(g.array_set_pos)
|
||||||
if g.is_array_set {
|
g.write(', &$v_var)')
|
||||||
g.out.go_back(2)
|
g.is_array_set = false
|
||||||
} else {
|
g.array_set_pos = 0
|
||||||
g.write('[$j] = ')
|
|
||||||
}
|
|
||||||
g.expr(expr)
|
|
||||||
if g.is_array_set {
|
|
||||||
g.writeln(')')
|
|
||||||
g.is_array_set = false
|
|
||||||
} else {
|
|
||||||
g.writeln(';')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
fixed_array := right_sym.info as table.ArrayFixed
|
g.out.go_back_to(pos)
|
||||||
for j in 0 .. fixed_array.size {
|
is_var_mut := !is_decl && left is ast.Ident
|
||||||
if !is_decl && left is ast.Ident
|
&& g.for_in_mul_val_name == (left as ast.Ident).name
|
||||||
&& g.for_in_mul_val_name == (left as ast.Ident).name {
|
addr := if is_var_mut { '' } else { '&' }
|
||||||
g.write('(*')
|
g.writeln('')
|
||||||
g.expr(left)
|
g.write('memcpy($addr')
|
||||||
g.write(')')
|
g.expr(left)
|
||||||
} else {
|
g.writeln(', &$v_var, sizeof($arr_typ));')
|
||||||
g.expr(left)
|
|
||||||
}
|
|
||||||
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
|
|
||||||
} else {
|
|
||||||
g.writeln(';')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
g.is_assign_lhs = false
|
g.is_assign_lhs = false
|
||||||
} else {
|
} else {
|
||||||
|
@ -2142,7 +2114,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||||
if is_fixed_array_copy {
|
if is_fixed_array_copy {
|
||||||
i_var := g.new_tmp_var()
|
i_var := g.new_tmp_var()
|
||||||
fixed_array := right_sym.info as table.ArrayFixed
|
fixed_array := right_sym.info as table.ArrayFixed
|
||||||
g.write('for(int $i_var=0; $i_var<$fixed_array.size; $i_var++) {')
|
g.write('for (int $i_var=0; $i_var<$fixed_array.size; $i_var++) {')
|
||||||
g.expr(left)
|
g.expr(left)
|
||||||
g.write('[$i_var] = ')
|
g.write('[$i_var] = ')
|
||||||
g.expr(val)
|
g.expr(val)
|
||||||
|
@ -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 {
|
||||||
|
|
|
@ -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}]]}"
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue