cgen: fix fixed array init with `it` (#14251)

yuyi 2022-05-02 07:00:45 +08:00 committed by Jef Roosens
parent bf86fff9cc
commit 8d1cc6a817
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
4 changed files with 57 additions and 24 deletions

View File

@ -5,7 +5,7 @@ module c
import strings import strings
import v.ast import v.ast
fn (mut g Gen) array_init(node ast.ArrayInit) { fn (mut g Gen) array_init(node ast.ArrayInit, var_name string) {
array_type := g.unwrap(node.typ) array_type := g.unwrap(node.typ)
mut array_styp := '' mut array_styp := ''
elem_type := g.unwrap(node.elem_type) elem_type := g.unwrap(node.elem_type)
@ -24,10 +24,10 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
} }
len := node.exprs.len len := node.exprs.len
if array_type.unaliased_sym.kind == .array_fixed { if array_type.unaliased_sym.kind == .array_fixed {
g.fixed_array_init(node, array_type) g.fixed_array_init(node, array_type, var_name)
} else if len == 0 { } else if len == 0 {
// `[]int{len: 6, cap:10, init:22}` // `[]int{len: 6, cap:10, init:22}`
g.array_init_with_fields(node, elem_type, is_amp, shared_styp) g.array_init_with_fields(node, elem_type, is_amp, shared_styp, var_name)
} else { } else {
// `[1, 2, 3]` // `[1, 2, 3]`
elem_styp := g.typ(elem_type.typ) elem_styp := g.typ(elem_type.typ)
@ -70,17 +70,24 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
} }
} }
fn (mut g Gen) fixed_array_init(node ast.ArrayInit, array_type Type) { fn (mut g Gen) fixed_array_init(node ast.ArrayInit, array_type Type, var_name string) {
if node.has_it { if node.has_it {
g.inside_lambda = true g.inside_lambda = true
tmp := g.new_tmp_var() mut tmp := g.new_tmp_var()
mut s := g.go_before_stmt(0) mut s := ''
if var_name.len != 0 {
tmp = var_name
} else {
s = g.go_before_stmt(0)
}
s_ends_with_ln := s.ends_with('\n') s_ends_with_ln := s.ends_with('\n')
s = s.trim_space() s = s.trim_space()
ret_typ := g.typ(node.typ) ret_typ := g.typ(node.typ)
elem_typ := g.typ(node.elem_type) elem_typ := g.typ(node.elem_type)
g.empty_line = true g.empty_line = true
g.write('$ret_typ $tmp =') if var_name.len == 0 {
g.write('$ret_typ $tmp =')
}
g.write('{') g.write('{')
if node.has_val { if node.has_val {
for i, expr in node.exprs { for i, expr in node.exprs {
@ -117,12 +124,14 @@ fn (mut g Gen) fixed_array_init(node ast.ArrayInit, array_type Type) {
g.writeln('}') g.writeln('}')
g.indent-- g.indent--
g.writeln('}') g.writeln('}')
if s_ends_with_ln { if var_name.len == 0 {
g.writeln(s) if s_ends_with_ln {
} else { g.writeln(s)
g.write(s) } else {
g.write(s)
}
g.write(tmp)
} }
g.write(tmp)
g.inside_lambda = false g.inside_lambda = false
return return
} }
@ -166,21 +175,28 @@ fn (mut g Gen) fixed_array_init(node ast.ArrayInit, array_type Type) {
} }
// `[]int{len: 6, cap: 10, init: it * it}` // `[]int{len: 6, cap: 10, init: it * it}`
fn (mut g Gen) array_init_with_fields(node ast.ArrayInit, elem_type Type, is_amp bool, shared_styp string) { fn (mut g Gen) array_init_with_fields(node ast.ArrayInit, elem_type Type, is_amp bool, shared_styp string, var_name string) {
elem_styp := g.typ(elem_type.typ) elem_styp := g.typ(elem_type.typ)
noscan := g.check_noscan(elem_type.typ) noscan := g.check_noscan(elem_type.typ)
is_default_array := elem_type.unaliased_sym.kind == .array && node.has_default is_default_array := elem_type.unaliased_sym.kind == .array && node.has_default
is_default_map := elem_type.unaliased_sym.kind == .map && node.has_default is_default_map := elem_type.unaliased_sym.kind == .map && node.has_default
if node.has_it { // []int{len: 6, init: it * it} when variable it is used in init expression if node.has_it { // []int{len: 6, init: it * it} when variable it is used in init expression
g.inside_lambda = true g.inside_lambda = true
tmp := g.new_tmp_var() mut tmp := g.new_tmp_var()
mut s := g.go_before_stmt(0) mut s := ''
if var_name.len != 0 {
tmp = var_name
} else {
s = g.go_before_stmt(0)
}
s_ends_with_ln := s.ends_with('\n') s_ends_with_ln := s.ends_with('\n')
s = s.trim_space() s = s.trim_space()
ret_typ := g.typ(node.typ) ret_typ := g.typ(node.typ)
elem_typ := g.typ(node.elem_type) elem_typ := g.typ(node.elem_type)
g.empty_line = true g.empty_line = true
g.write('$ret_typ $tmp =') if var_name.len == 0 {
g.write('$ret_typ $tmp =')
}
if is_default_array { if is_default_array {
g.write('__new_array_with_array_default${noscan}(') g.write('__new_array_with_array_default${noscan}(')
} else if is_default_map { } else if is_default_map {
@ -238,12 +254,14 @@ fn (mut g Gen) array_init_with_fields(node ast.ArrayInit, elem_type Type, is_amp
g.writeln('}') g.writeln('}')
g.indent-- g.indent--
g.writeln('}') g.writeln('}')
if s_ends_with_ln { if var_name.len == 0 {
g.writeln(s) if s_ends_with_ln {
} else { g.writeln(s)
g.write(s) } else {
g.write(s)
}
g.write(tmp)
} }
g.write(tmp)
g.inside_lambda = false g.inside_lambda = false
return return
} }

View File

@ -440,7 +440,7 @@ fn (mut g Gen) gen_assign_stmt(node_ ast.AssignStmt) {
} else if is_decl { } else if is_decl {
if is_fixed_array_init && !has_val { if is_fixed_array_init && !has_val {
if val is ast.ArrayInit { if val is ast.ArrayInit {
g.array_init(val) g.array_init(val, ident.name)
} else { } else {
g.write('{0}') g.write('{0}')
} }
@ -451,7 +451,11 @@ fn (mut g Gen) gen_assign_stmt(node_ ast.AssignStmt) {
if val.is_auto_deref_var() { if val.is_auto_deref_var() {
g.write('*') g.write('*')
} }
g.expr(val) if val is ast.ArrayInit {
g.array_init(val, ident.name)
} else {
g.expr(val)
}
if is_auto_heap { if is_auto_heap {
g.write('))') g.write('))')
} }

View File

@ -2879,7 +2879,7 @@ fn (mut g Gen) expr(node_ ast.Expr) {
g.expr(node.expr) g.expr(node.expr)
} }
ast.ArrayInit { ast.ArrayInit {
g.array_init(node) g.array_init(node, '')
} }
ast.AsCast { ast.AsCast {
g.as_cast(node) g.as_cast(node)

View File

@ -1,6 +1,17 @@
fn test_array_with_it() { fn test_array_with_it() {
assert [0, 1, 2, 3, 4, 5]! == [6]int{init: it} assert [0, 1, 2, 3, 4, 5]! == [6]int{init: it}
a1 := [6]int{init: it}
assert a1 == [0, 1, 2, 3, 4, 5]!
assert [0, 1, 4, 9, 16, 25] == []int{len: 6, init: it * it} assert [0, 1, 4, 9, 16, 25] == []int{len: 6, init: it * it}
a2 := []int{len: 6, init: it * it}
assert a2 == [0, 1, 4, 9, 16, 25]
assert [1, 2, 3, 4, 5] == []int{len: 5, init: it + 1} assert [1, 2, 3, 4, 5] == []int{len: 5, init: it + 1}
a3 := []int{len: 5, init: it + 1}
assert a3 == [1, 2, 3, 4, 5]
assert [5, 4, 3, 2, 1] == []int{len: 5, init: 5 - it} assert [5, 4, 3, 2, 1] == []int{len: 5, init: 5 - it}
a4 := []int{len: 5, init: 5 - it}
assert a4 == [5, 4, 3, 2, 1]
} }