array: fix array of multi filter/map in one assignment (fix #7858) (#7976)

pull/8016/head
yuyi 2021-01-11 04:08:45 +08:00 committed by GitHub
parent c1b1ec9005
commit 39bb6f0491
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 4 deletions

View File

@ -1310,3 +1310,30 @@ fn test_multi_fixed_array_init() {
a := [3][3]int{} a := [3][3]int{}
assert '$a' == '[[0, 0, 0], [0, 0, 0], [0, 0, 0]]' assert '$a' == '[[0, 0, 0], [0, 0, 0], [0, 0, 0]]'
} }
struct Numbers {
odds []int
evens []int
}
fn test_array_of_multi_filter() {
arr := [1, 2, 3, 4, 5]
nums := Numbers{
odds: arr.filter(it % 2 == 1)
evens: arr.filter(it % 2 == 0)
}
println(nums)
assert nums.odds == [1, 3, 5]
assert nums.evens == [2, 4]
}
fn test_array_of_multi_map() {
arr := [1, 3, 5]
nums := Numbers{
odds: arr.map(it + 2)
evens: arr.map(it * 2)
}
println(nums)
assert nums.odds == [3, 5, 7]
assert nums.evens == [2, 6, 10]
}

View File

@ -149,15 +149,16 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
i := g.new_tmp_var() i := g.new_tmp_var()
g.writeln('for (int $i = 0; $i < ${tmp}_len; ++$i) {') g.writeln('for (int $i = 0; $i < ${tmp}_len; ++$i) {')
g.write('\t$inp_elem_type it = (($inp_elem_type*) ${tmp}_orig.data)[$i];') g.write('\t$inp_elem_type it = (($inp_elem_type*) ${tmp}_orig.data)[$i];')
g.stmt_path_pos << g.out.len mut is_embed_map_filter := false
g.write('\t$ret_elem_type ti = ')
expr := node.args[0].expr expr := node.args[0].expr
match expr { match expr {
ast.AnonFn { ast.AnonFn {
g.write('\t$ret_elem_type ti = ')
g.gen_anon_fn_decl(expr) g.gen_anon_fn_decl(expr)
g.write('${expr.decl.name}(it)') g.write('${expr.decl.name}(it)')
} }
ast.Ident { ast.Ident {
g.write('\t$ret_elem_type ti = ')
if expr.kind == .function { if expr.kind == .function {
g.write('${c_name(expr.name)}(it)') g.write('${c_name(expr.name)}(it)')
} else if expr.kind == .variable { } else if expr.kind == .variable {
@ -172,13 +173,25 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
g.expr(node.args[0].expr) g.expr(node.args[0].expr)
} }
} }
ast.CallExpr {
if expr.name in ['map', 'filter'] {
is_embed_map_filter = true
g.stmt_path_pos << g.out.len
}
g.write('\t$ret_elem_type ti = ')
g.expr(node.args[0].expr)
}
else { else {
g.write('\t$ret_elem_type ti = ')
g.expr(node.args[0].expr) g.expr(node.args[0].expr)
} }
} }
g.writeln(';') g.writeln(';')
g.writeln('\tarray_push(&$tmp, &ti);') g.writeln('\tarray_push(&$tmp, &ti);')
g.writeln('}') g.writeln('}')
if !is_embed_map_filter {
g.stmt_path_pos << g.out.len
}
g.write(s) g.write(s)
g.write(tmp) g.write(tmp)
g.inside_lambda = false g.inside_lambda = false
@ -303,15 +316,16 @@ fn (mut g Gen) gen_array_filter(node ast.CallExpr) {
i := g.new_tmp_var() i := g.new_tmp_var()
g.writeln('for (int $i = 0; $i < ${tmp}_len; ++$i) {') g.writeln('for (int $i = 0; $i < ${tmp}_len; ++$i) {')
g.writeln(' $elem_type_str it = (($elem_type_str*) ${tmp}_orig.data)[$i];') g.writeln(' $elem_type_str it = (($elem_type_str*) ${tmp}_orig.data)[$i];')
g.stmt_path_pos << g.out.len mut is_embed_map_filter := false
g.write('if (')
expr := node.args[0].expr expr := node.args[0].expr
match expr { match expr {
ast.AnonFn { ast.AnonFn {
g.write('if (')
g.gen_anon_fn_decl(expr) g.gen_anon_fn_decl(expr)
g.write('${expr.decl.name}(it)') g.write('${expr.decl.name}(it)')
} }
ast.Ident { ast.Ident {
g.write('if (')
if expr.kind == .function { if expr.kind == .function {
g.write('${c_name(expr.name)}(it)') g.write('${c_name(expr.name)}(it)')
} else if expr.kind == .variable { } else if expr.kind == .variable {
@ -326,11 +340,23 @@ fn (mut g Gen) gen_array_filter(node ast.CallExpr) {
g.expr(node.args[0].expr) g.expr(node.args[0].expr)
} }
} }
ast.CallExpr {
if expr.name in ['map', 'filter'] {
is_embed_map_filter = true
g.stmt_path_pos << g.out.len
}
g.write('if (')
g.expr(node.args[0].expr)
}
else { else {
g.write('if (')
g.expr(node.args[0].expr) g.expr(node.args[0].expr)
} }
} }
g.writeln(') array_push(&$tmp, &it); \n }') g.writeln(') array_push(&$tmp, &it); \n }')
if !is_embed_map_filter {
g.stmt_path_pos << g.out.len
}
g.write(s) g.write(s)
g.write(' ') g.write(' ')
g.write(tmp) g.write(tmp)