From 968d2b4654d3e548a9a9970ce82dbeb7ffbb7549 Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 2 May 2022 07:00:45 +0800 Subject: [PATCH] cgen: fix fixed array init with `it` (#14251) --- vlib/v/gen/c/array.v | 60 ++++++++++++++++++++----------- vlib/v/gen/c/assign.v | 8 +++-- vlib/v/gen/c/cgen.v | 2 +- vlib/v/tests/array_with_it_test.v | 11 ++++++ 4 files changed, 57 insertions(+), 24 deletions(-) diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index fa32b168e3..34a7446b87 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -5,7 +5,7 @@ module c import strings 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) mut array_styp := '' elem_type := g.unwrap(node.elem_type) @@ -24,10 +24,10 @@ fn (mut g Gen) array_init(node ast.ArrayInit) { } len := node.exprs.len 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 { // `[]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 { // `[1, 2, 3]` 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 { g.inside_lambda = true - tmp := g.new_tmp_var() - mut s := g.go_before_stmt(0) + mut tmp := g.new_tmp_var() + 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 = s.trim_space() ret_typ := g.typ(node.typ) elem_typ := g.typ(node.elem_type) g.empty_line = true - g.write('$ret_typ $tmp =') + if var_name.len == 0 { + g.write('$ret_typ $tmp =') + } g.write('{') if node.has_val { 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.indent-- g.writeln('}') - if s_ends_with_ln { - g.writeln(s) - } else { - g.write(s) + if var_name.len == 0 { + if s_ends_with_ln { + g.writeln(s) + } else { + g.write(s) + } + g.write(tmp) } - g.write(tmp) g.inside_lambda = false 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}` -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) noscan := g.check_noscan(elem_type.typ) is_default_array := elem_type.unaliased_sym.kind == .array && 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 g.inside_lambda = true - tmp := g.new_tmp_var() - mut s := g.go_before_stmt(0) + mut tmp := g.new_tmp_var() + 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 = s.trim_space() ret_typ := g.typ(node.typ) elem_typ := g.typ(node.elem_type) g.empty_line = true - g.write('$ret_typ $tmp =') + if var_name.len == 0 { + g.write('$ret_typ $tmp =') + } if is_default_array { g.write('__new_array_with_array_default${noscan}(') } 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.indent-- g.writeln('}') - if s_ends_with_ln { - g.writeln(s) - } else { - g.write(s) + if var_name.len == 0 { + if s_ends_with_ln { + g.writeln(s) + } else { + g.write(s) + } + g.write(tmp) } - g.write(tmp) g.inside_lambda = false return } diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 1a3a678dab..990e89d75e 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -440,7 +440,7 @@ fn (mut g Gen) gen_assign_stmt(node_ ast.AssignStmt) { } else if is_decl { if is_fixed_array_init && !has_val { if val is ast.ArrayInit { - g.array_init(val) + g.array_init(val, ident.name) } else { g.write('{0}') } @@ -451,7 +451,11 @@ fn (mut g Gen) gen_assign_stmt(node_ ast.AssignStmt) { if val.is_auto_deref_var() { g.write('*') } - g.expr(val) + if val is ast.ArrayInit { + g.array_init(val, ident.name) + } else { + g.expr(val) + } if is_auto_heap { g.write('))') } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index aad76ad199..6558fba644 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -2879,7 +2879,7 @@ fn (mut g Gen) expr(node_ ast.Expr) { g.expr(node.expr) } ast.ArrayInit { - g.array_init(node) + g.array_init(node, '') } ast.AsCast { g.as_cast(node) diff --git a/vlib/v/tests/array_with_it_test.v b/vlib/v/tests/array_with_it_test.v index d8de5f3799..3e7e53dd93 100644 --- a/vlib/v/tests/array_with_it_test.v +++ b/vlib/v/tests/array_with_it_test.v @@ -1,6 +1,17 @@ fn test_array_with_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} + 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} + 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} + a4 := []int{len: 5, init: 5 - it} + assert a4 == [5, 4, 3, 2, 1] }