diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index 92c8a3a8aad981..5fcec57f09a1ad 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -463,15 +463,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_name string) { - past := g.past_tmp_var_new() - fn_ptr_name := g.fn_var_signature(expr.decl.return_type, expr.decl.params.map(it.typ), - past.tmp_var) - g.write('${fn_ptr_name} = ') - g.gen_anon_fn(mut expr) - g.writeln(';') - g.past_tmp_var_done(past) - g.write('(${var_name})') // usually `it` +fn (mut g Gen) write_closure_fn(mut expr ast.AnonFn, var_name string, declared_var string) { + if declared_var == '' { + past := g.past_tmp_var_new() + fn_ptr_name := g.fn_var_signature(expr.decl.return_type, expr.decl.params.map(it.typ), + past.tmp_var) + g.write('${fn_ptr_name} = ') + g.gen_anon_fn(mut expr) + g.writeln(';') + g.past_tmp_var_done(past) + g.write('(${var_name})') // usually `it` + } else { + g.write('${declared_var}(${var_name})') + } } // `nums.map(it % 2 == 0)` @@ -515,6 +519,19 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) { has_infix_left_var_name := g.write_prepared_tmp_value(past.tmp_var, node, ret_typ, '{0}') g.writeln('${past.tmp_var} = __new_array${noscan}(0, ${past.tmp_var}_len, sizeof(${ret_elem_type}));\n') + + mut closure_var := '' + if mut expr is ast.AnonFn { + if expr.inherited_vars.len > 0 { + closure_var = g.new_tmp_var() + fn_ptr_name := g.fn_var_signature(expr.decl.return_type, expr.decl.params.map(it.typ), + closure_var) + g.write('${fn_ptr_name} = ') + g.gen_anon_fn(mut expr) + g.writeln(';') + } + } + i := g.new_tmp_var() g.writeln('for (int ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {') g.indent++ @@ -526,7 +543,7 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) { ast.AnonFn { g.write('${ret_elem_type} ${tmp_map_expr_result_name} = ') if expr.inherited_vars.len > 0 { - g.write_closure_fn(mut expr, var_name) + g.write_closure_fn(mut expr, var_name, closure_var) } else { g.gen_anon_fn_decl(mut expr) g.write('${expr.decl.name}(${var_name})') @@ -769,11 +786,25 @@ fn (mut g Gen) gen_array_filter(node ast.CallExpr) { noscan := g.check_noscan(info.elem_type) has_infix_left_var_name := g.write_prepared_tmp_value(past.tmp_var, node, styp, '{0}') g.writeln('${past.tmp_var} = __new_array${noscan}(0, ${past.tmp_var}_len, sizeof(${elem_type_str}));\n') + + mut expr := node.args[0].expr + var_name := g.get_array_expr_param_name(mut expr) + + mut closure_var := '' + if mut expr is ast.AnonFn { + if expr.inherited_vars.len > 0 { + closure_var = g.new_tmp_var() + fn_ptr_name := g.fn_var_signature(expr.decl.return_type, expr.decl.params.map(it.typ), + closure_var) + g.write('${fn_ptr_name} = ') + g.gen_anon_fn(mut expr) + g.writeln(';') + } + } + i := g.new_tmp_var() g.writeln('for (int ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {') g.indent++ - mut expr := node.args[0].expr - var_name := g.get_array_expr_param_name(mut expr) g.write_prepared_var(var_name, info, elem_type_str, past.tmp_var, i) g.set_current_pos_as_last_stmt_pos() mut is_embed_map_filter := false @@ -781,7 +812,7 @@ fn (mut g Gen) gen_array_filter(node ast.CallExpr) { ast.AnonFn { g.write('if (') if expr.inherited_vars.len > 0 { - g.write_closure_fn(mut expr, var_name) + g.write_closure_fn(mut expr, var_name, closure_var) } else { g.gen_anon_fn_decl(mut expr) g.write('${expr.decl.name}(${var_name})') @@ -1163,11 +1194,25 @@ fn (mut g Gen) gen_array_any(node ast.CallExpr) { elem_type_str := g.typ(info.elem_type) has_infix_left_var_name := g.write_prepared_tmp_value(past.tmp_var, node, 'bool', 'false') + + mut expr := node.args[0].expr + var_name := g.get_array_expr_param_name(mut expr) + + mut closure_var := '' + if mut expr is ast.AnonFn { + if expr.inherited_vars.len > 0 { + closure_var = g.new_tmp_var() + fn_ptr_name := g.fn_var_signature(expr.decl.return_type, expr.decl.params.map(it.typ), + closure_var) + g.write('${fn_ptr_name} = ') + g.gen_anon_fn(mut expr) + g.writeln(';') + } + } i := g.new_tmp_var() g.writeln('for (int ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {') g.indent++ - mut expr := node.args[0].expr - var_name := g.get_array_expr_param_name(mut expr) + g.write_prepared_var(var_name, info, elem_type_str, past.tmp_var, i) g.set_current_pos_as_last_stmt_pos() mut is_embed_map_filter := false @@ -1175,7 +1220,7 @@ fn (mut g Gen) gen_array_any(node ast.CallExpr) { ast.AnonFn { g.write('if (') if expr.inherited_vars.len > 0 { - g.write_closure_fn(mut expr, var_name) + g.write_closure_fn(mut expr, var_name, closure_var) } else { g.gen_anon_fn_decl(mut expr) g.write('${expr.decl.name}(${var_name})') @@ -1244,10 +1289,24 @@ fn (mut g Gen) gen_array_all(node ast.CallExpr) { has_infix_left_var_name := g.write_prepared_tmp_value(past.tmp_var, node, 'bool', 'true') i := g.new_tmp_var() - g.writeln('for (int ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {') - g.indent++ + mut expr := node.args[0].expr var_name := g.get_array_expr_param_name(mut expr) + + mut closure_var := '' + if mut expr is ast.AnonFn { + if expr.inherited_vars.len > 0 { + closure_var = g.new_tmp_var() + fn_ptr_name := g.fn_var_signature(expr.decl.return_type, expr.decl.params.map(it.typ), + closure_var) + g.write('${fn_ptr_name} = ') + g.gen_anon_fn(mut expr) + g.writeln(';') + } + } + + g.writeln('for (int ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {') + g.indent++ g.write_prepared_var(var_name, info, elem_type_str, past.tmp_var, i) g.empty_line = true g.set_current_pos_as_last_stmt_pos() @@ -1256,7 +1315,7 @@ fn (mut g Gen) gen_array_all(node ast.CallExpr) { ast.AnonFn { g.write('if (!(') if expr.inherited_vars.len > 0 { - g.write_closure_fn(mut expr, var_name) + g.write_closure_fn(mut expr, var_name, closure_var) } else { g.gen_anon_fn_decl(mut expr) g.write('${expr.decl.name}(${var_name})')