builtin, cgen: fix array of map init with default value (#12885)

pull/12891/head
yuyi 2021-12-18 16:07:25 +08:00 committed by GitHub
parent 50d988ebc7
commit 7c255f0ff2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 1 deletions

View File

@ -72,6 +72,21 @@ fn __new_array_with_array_default(mylen int, cap int, elm_size int, val array) a
return arr
}
fn __new_array_with_map_default(mylen int, cap int, elm_size int, val map) array {
cap_ := if cap < mylen { mylen } else { cap }
mut arr := array{
element_size: elm_size
data: unsafe { malloc(cap_ * elm_size) }
len: mylen
cap: cap_
}
for i in 0 .. arr.len {
val_clone := unsafe { val.clone() }
unsafe { arr.set_unsafe(i, &val_clone) }
}
return arr
}
// Private function, used by V (`nums := [1, 2, 3]`)
fn new_array_from_c_array(len int, cap int, elm_size int, c_array voidptr) array {
cap_ := if cap < len { len } else { cap }

View File

@ -106,6 +106,7 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
noscan := g.check_noscan(elem_type.typ)
if node.exprs.len == 0 {
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()
@ -118,6 +119,8 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
g.write('$ret_typ $tmp =')
if is_default_array {
g.write('__new_array_with_array_default${noscan}(')
} else if is_default_map {
g.write('__new_array_with_map_default${noscan}(')
} else {
g.write('__new_array_with_default${noscan}(')
}
@ -182,6 +185,8 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
}
if is_default_array {
g.write('__new_array_with_array_default${noscan}(')
} else if is_default_map {
g.write('__new_array_with_map_default${noscan}(')
} else {
g.write('__new_array_with_default${noscan}(')
}
@ -202,7 +207,7 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
} else {
g.write('sizeof($elem_styp), ')
}
if is_default_array {
if is_default_array || is_default_map {
g.write('($elem_styp[]){')
g.expr(node.default_expr)
g.write('}[0])')

View File

@ -0,0 +1,42 @@
fn init_a(n_rows int) []map[int]int {
mut tally := []map[int]int{}
for _ in 0 .. n_rows {
tally << map[int]int{}
}
return tally
}
fn init_b(n_rows int) []map[int]int {
mut tally := []map[int]int{len: n_rows, init: map[int]int{}}
return tally
}
pub fn tallys_in_array(indexs []int, values [][]int, init fn (int) []map[int]int) []map[int]int {
mut tally := init(indexs.len)
for row in 0 .. values.len {
for i, index in indexs {
tally[i][values[row][index]]++
}
}
return tally
}
fn test_array_of_map_with_default() {
indexs := [0, 1]
values := [[1, 201], [1, 3], [1, 201], [1, 3]]
out1 := tallys_in_array(indexs, values, init_a)
println(out1)
out2 := tallys_in_array(indexs, values, init_b)
println(out2)
mut maps := []map[int]int{}
maps << map[int]int{}
maps << map[int]int{}
maps[0][1] = 4
maps[1][3] = 2
maps[1][201] = 2
assert out1 == maps
assert out2 == maps
}