builtin, cgen: fix array of map init with default value (#12885)
							parent
							
								
									50d988ebc7
								
							
						
					
					
						commit
						7c255f0ff2
					
				|  | @ -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 } | ||||
|  |  | |||
|  | @ -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])') | ||||
|  |  | |||
|  | @ -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 | ||||
| } | ||||
		Loading…
	
		Reference in New Issue