1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

cgen: fix array filter with an inline closure (fix #16770) (#16772)

This commit is contained in:
yuyi 2022-12-26 22:14:28 +08:00 committed by GitHub
parent 3d545ee0cd
commit 3a1e7b71ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 8 deletions

View File

@ -331,6 +331,19 @@ fn (mut g Gen) array_init_with_fields(node ast.ArrayInit, elem_type Type, is_amp
}
}
fn (mut g Gen) write_closure_fn(mut expr ast.AnonFn) {
var := g.new_tmp_var()
line := g.go_before_stmt(0).trim_space()
g.empty_line = true
fn_ptr_name := g.fn_var_signature(expr.decl.return_type, expr.decl.params.map(it.typ),
var)
g.write('${fn_ptr_name} = ')
g.gen_anon_fn(mut expr)
g.writeln(';')
g.write(line)
g.write('${var}(it)')
}
// `nums.map(it % 2 == 0)`
fn (mut g Gen) gen_array_map(node ast.CallExpr) {
g.inside_lambda = true
@ -364,8 +377,12 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
match mut expr {
ast.AnonFn {
g.write('${ret_elem_type} ti = ')
g.gen_anon_fn_decl(mut expr)
g.write('${expr.decl.name}(it)')
if expr.inherited_vars.len > 0 {
g.write_closure_fn(mut expr)
} else {
g.gen_anon_fn_decl(mut expr)
g.write('${expr.decl.name}(it)')
}
}
ast.Ident {
g.write('${ret_elem_type} ti = ')
@ -559,8 +576,12 @@ fn (mut g Gen) gen_array_filter(node ast.CallExpr) {
match mut expr {
ast.AnonFn {
g.write('if (')
g.gen_anon_fn_decl(mut expr)
g.write('${expr.decl.name}(it)')
if expr.inherited_vars.len > 0 {
g.write_closure_fn(mut expr)
} else {
g.gen_anon_fn_decl(mut expr)
g.write('${expr.decl.name}(it)')
}
}
ast.Ident {
g.write('if (')
@ -918,8 +939,12 @@ fn (mut g Gen) gen_array_any(node ast.CallExpr) {
match mut expr {
ast.AnonFn {
g.write('if (')
g.gen_anon_fn_decl(mut expr)
g.write('${expr.decl.name}(it)')
if expr.inherited_vars.len > 0 {
g.write_closure_fn(mut expr)
} else {
g.gen_anon_fn_decl(mut expr)
g.write('${expr.decl.name}(it)')
}
}
ast.Ident {
g.write('if (')
@ -994,8 +1019,12 @@ fn (mut g Gen) gen_array_all(node ast.CallExpr) {
match mut expr {
ast.AnonFn {
g.write('if (!(')
g.gen_anon_fn_decl(mut expr)
g.write('${expr.decl.name}(it)')
if expr.inherited_vars.len > 0 {
g.write_closure_fn(mut expr)
} else {
g.gen_anon_fn_decl(mut expr)
g.write('${expr.decl.name}(it)')
}
}
ast.Ident {
g.write('if (!(')

View File

@ -0,0 +1,42 @@
struct File {
name string
typ string
is_dir bool
}
fn filter(all_files []File, interested_file File) []File {
println(interested_file)
return all_files.filter(fn [interested_file] (f File) bool {
println(interested_file)
return true
})
}
fn test_array_filter_using_direct_closure() {
filenames := ['one', 'two', 'three']
files := filenames.map(fn (f string) File {
return File{
name: f
typ: if f == 'one' {
'file'
} else {
'dir'
}
is_dir: if f == 'one' {
false
} else {
true
}
}
})
ret := filter(files, files[0])
println(ret)
assert ret.len == 3
assert ret[0].name == 'one'
assert ret[0].typ == 'file'
assert ret[1].name == 'two'
assert ret[1].typ == 'dir'
assert ret[2].name == 'three'
assert ret[2].typ == 'dir'
}