mirror of
https://github.com/vlang/v.git
synced 2025-09-09 07:15:50 -04:00
checker: support lambda expressions in array methods like a.map(|x|x*10)
too (#19424)
This commit is contained in:
parent
9954f89e3f
commit
a685088fbd
35
vlib/builtin/lambda_expr_array_test.v
Normal file
35
vlib/builtin/lambda_expr_array_test.v
Normal file
@ -0,0 +1,35 @@
|
||||
const a = [4, 5, 1, 2, 5, 9]
|
||||
|
||||
fn test_map() {
|
||||
assert a.map(it) == a
|
||||
assert a.map(it * 10) == [40, 50, 10, 20, 50, 90]
|
||||
//
|
||||
assert a.map(|x| x) == a
|
||||
assert a.map(|x| x * 10) == [40, 50, 10, 20, 50, 90]
|
||||
assert a.map(|x| 'x: ${x}') == ['x: 4', 'x: 5', 'x: 1', 'x: 2', 'x: 5', 'x: 9']
|
||||
assert a.map(|x| f64(x) * 10.0) == [40.0, 50.0, 10.0, 20.0, 50.0, 90.0]
|
||||
}
|
||||
|
||||
fn test_filter() {
|
||||
assert a.filter(it > 4) == [5, 5, 9]
|
||||
assert a.filter(it < 4) == [1, 2]
|
||||
//
|
||||
assert a.filter(|x| x > 4) == [5, 5, 9]
|
||||
assert a.filter(|x| x < 4) == [1, 2]
|
||||
}
|
||||
|
||||
fn test_any() {
|
||||
assert a.any(it > 4)
|
||||
assert !a.any(it > 40)
|
||||
|
||||
assert a.any(|x| x > 4)
|
||||
assert !a.any(|x| x > 40)
|
||||
}
|
||||
|
||||
fn test_all() {
|
||||
assert !a.all(it > 4)
|
||||
assert a.all(it < 40)
|
||||
|
||||
assert !a.all(|x| x > 4)
|
||||
assert a.all(|x| x < 40)
|
||||
}
|
@ -1786,9 +1786,9 @@ pub:
|
||||
|
||||
pub struct LambdaExpr {
|
||||
pub:
|
||||
pos token.Pos
|
||||
params []Ident
|
||||
pos token.Pos
|
||||
pub mut:
|
||||
params []Ident
|
||||
pos_expr token.Pos
|
||||
expr Expr
|
||||
pos_end token.Pos
|
||||
|
@ -2587,6 +2587,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
|
||||
mut elem_typ := ast.void_type
|
||||
if method_name == 'slice' && !c.is_builtin_mod {
|
||||
c.error('.slice() is a private method, use `x[start..end]` instead', node.pos)
|
||||
return ast.void_type
|
||||
}
|
||||
array_info := if left_sym.info is ast.Array {
|
||||
left_sym.info as ast.Array
|
||||
@ -2595,10 +2596,27 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
|
||||
}
|
||||
elem_typ = array_info.elem_type
|
||||
if method_name in ['filter', 'map', 'any', 'all'] {
|
||||
// position of `it` doesn't matter
|
||||
scope_register_it(mut node.scope, node.pos, elem_typ)
|
||||
if node.args.len > 0 && mut node.args[0].expr is ast.LambdaExpr {
|
||||
if node.args[0].expr.params.len != 1 {
|
||||
c.error('lambda expressions used in the builtin array methods require exactly 1 parameter',
|
||||
node.args[0].expr.pos)
|
||||
return ast.void_type
|
||||
}
|
||||
if method_name == 'map' {
|
||||
c.lambda_expr_fix_type_of_param(mut node.args[0].expr, mut node.args[0].expr.params[0],
|
||||
elem_typ)
|
||||
le_type := c.expr(mut node.args[0].expr.expr)
|
||||
// eprintln('>>>>> node.args[0].expr: ${ast.Expr(node.args[0].expr)} | elem_typ: ${elem_typ} | etype: ${le_type}')
|
||||
c.support_lambda_expr_one_param(elem_typ, le_type, mut node.args[0].expr)
|
||||
} else {
|
||||
c.support_lambda_expr_one_param(elem_typ, ast.bool_type, mut node.args[0].expr)
|
||||
}
|
||||
} else {
|
||||
// position of `it` doesn't matter
|
||||
scope_register_it(mut node.scope, node.pos, elem_typ)
|
||||
}
|
||||
} else if method_name == 'sorted_with_compare' && node.args.len == 1 {
|
||||
if mut node.args[0].expr is ast.LambdaExpr {
|
||||
if node.args.len > 0 && mut node.args[0].expr is ast.LambdaExpr {
|
||||
c.support_lambda_expr_in_sort(elem_typ.ref(), ast.int_type, mut node.args[0].expr)
|
||||
}
|
||||
} else if method_name == 'sort' || method_name == 'sorted' {
|
||||
@ -2671,6 +2689,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
|
||||
arg_type = c.check_expr_opt_call(arg.expr, c.expr(mut arg.expr))
|
||||
}
|
||||
if method_name == 'map' {
|
||||
// eprintln('>>>>>>> map node.args[0].expr: ${node.args[0].expr}, left_type: ${left_type} | elem_typ: ${elem_typ} | arg_type: ${arg_type}')
|
||||
// check fn
|
||||
c.check_map_and_filter(true, elem_typ, node)
|
||||
arg_sym := c.table.sym(arg_type)
|
||||
@ -2777,25 +2796,19 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
|
||||
}
|
||||
|
||||
fn scope_register_it(mut s ast.Scope, pos token.Pos, typ ast.Type) {
|
||||
scope_register_var_name(mut s, pos, typ, 'it')
|
||||
}
|
||||
|
||||
fn scope_register_a_b(mut s ast.Scope, pos token.Pos, typ ast.Type) {
|
||||
scope_register_var_name(mut s, pos, typ.ref(), 'a')
|
||||
scope_register_var_name(mut s, pos, typ.ref(), 'b')
|
||||
}
|
||||
|
||||
fn scope_register_var_name(mut s ast.Scope, pos token.Pos, typ ast.Type, name string) {
|
||||
s.register(ast.Var{
|
||||
name: 'it'
|
||||
name: name
|
||||
pos: pos
|
||||
typ: typ
|
||||
is_used: true
|
||||
})
|
||||
}
|
||||
|
||||
fn scope_register_a_b(mut s ast.Scope, pos token.Pos, typ ast.Type) {
|
||||
s.register(ast.Var{
|
||||
name: 'a'
|
||||
pos: pos
|
||||
typ: typ.ref()
|
||||
is_used: true
|
||||
})
|
||||
s.register(ast.Var{
|
||||
name: 'b'
|
||||
pos: pos
|
||||
typ: typ.ref()
|
||||
is_used: true
|
||||
})
|
||||
}
|
||||
|
@ -33,17 +33,7 @@ pub fn (mut c Checker) lambda_expr(mut node ast.LambdaExpr, exp_typ ast.Type) as
|
||||
eparam := exp_sym.info.func.params[idx]
|
||||
eparam_type := eparam.typ
|
||||
eparam_auto_deref := eparam.typ.is_ptr()
|
||||
if mut v := node.scope.find(x.name) {
|
||||
if mut v is ast.Var {
|
||||
v.is_arg = true
|
||||
v.typ = eparam_type
|
||||
v.expr = ast.empty_expr
|
||||
v.is_auto_deref = eparam_auto_deref
|
||||
}
|
||||
}
|
||||
c.ident(mut x)
|
||||
x.obj.typ = eparam_type
|
||||
|
||||
c.lambda_expr_fix_type_of_param(mut node, mut x, eparam_type)
|
||||
params << ast.Param{
|
||||
pos: x.pos
|
||||
name: x.name
|
||||
@ -100,6 +90,19 @@ pub fn (mut c Checker) lambda_expr(mut node ast.LambdaExpr, exp_typ ast.Type) as
|
||||
return exp_typ
|
||||
}
|
||||
|
||||
pub fn (mut c Checker) lambda_expr_fix_type_of_param(mut node ast.LambdaExpr, mut pident ast.Ident, ptype ast.Type) {
|
||||
if mut v := node.scope.find(pident.name) {
|
||||
if mut v is ast.Var {
|
||||
v.is_arg = true
|
||||
v.typ = ptype
|
||||
v.is_auto_deref = ptype.is_ptr()
|
||||
v.expr = ast.empty_expr
|
||||
}
|
||||
}
|
||||
c.ident(mut pident)
|
||||
pident.obj.typ = ptype
|
||||
}
|
||||
|
||||
pub fn (mut c Checker) support_lambda_expr_in_sort(param_type ast.Type, return_type ast.Type, mut expr ast.LambdaExpr) {
|
||||
is_auto_rec := param_type.is_ptr()
|
||||
mut expected_fn := ast.Fn{
|
||||
@ -121,3 +124,19 @@ pub fn (mut c Checker) support_lambda_expr_in_sort(param_type ast.Type, return_t
|
||||
false))
|
||||
c.lambda_expr(mut expr, expected_fn_type)
|
||||
}
|
||||
|
||||
pub fn (mut c Checker) support_lambda_expr_one_param(param_type ast.Type, return_type ast.Type, mut expr ast.LambdaExpr) {
|
||||
mut expected_fn := ast.Fn{
|
||||
params: [
|
||||
ast.Param{
|
||||
name: 'xx'
|
||||
typ: param_type
|
||||
is_auto_rec: param_type.is_ptr()
|
||||
},
|
||||
]
|
||||
return_type: return_type
|
||||
}
|
||||
cb_type := c.table.find_or_register_fn_type(expected_fn, true, false)
|
||||
expected_fn_type := ast.new_type(cb_type)
|
||||
c.lambda_expr(mut expr, expected_fn_type)
|
||||
}
|
||||
|
12
vlib/v/checker/tests/lambda_expression_in_map.out
Normal file
12
vlib/v/checker/tests/lambda_expression_in_map.out
Normal file
@ -0,0 +1,12 @@
|
||||
vlib/v/checker/tests/lambda_expression_in_map.vv:3:12: error: lambda expressions used in the builtin array methods require exactly 1 parameter
|
||||
1 | a := [4, 5]
|
||||
2 | dump(a.map(it))
|
||||
3 | dump(a.map(|| 5))
|
||||
| ~~
|
||||
4 | dump(a.map(|x| 5 * x))
|
||||
5 | dump(a.map(|x| x))
|
||||
vlib/v/checker/tests/lambda_expression_in_map.vv:6:12: error: lambda expressions used in the builtin array methods require exactly 1 parameter
|
||||
4 | dump(a.map(|x| 5 * x))
|
||||
5 | dump(a.map(|x| x))
|
||||
6 | dump(a.map(|x, y| x))
|
||||
| ^
|
6
vlib/v/checker/tests/lambda_expression_in_map.vv
Normal file
6
vlib/v/checker/tests/lambda_expression_in_map.vv
Normal file
@ -0,0 +1,6 @@
|
||||
a := [4, 5]
|
||||
dump(a.map(it))
|
||||
dump(a.map(|| 5))
|
||||
dump(a.map(|x| 5 * x))
|
||||
dump(a.map(|x| x))
|
||||
dump(a.map(|x, y| x))
|
@ -455,7 +455,7 @@ 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) {
|
||||
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)
|
||||
@ -463,7 +463,7 @@ fn (mut g Gen) write_closure_fn(mut expr ast.AnonFn) {
|
||||
g.gen_anon_fn(mut expr)
|
||||
g.writeln(';')
|
||||
g.past_tmp_var_done(past)
|
||||
g.write('(it)')
|
||||
g.write('(${var_name})') // usually `it`
|
||||
}
|
||||
|
||||
// `nums.map(it % 2 == 0)`
|
||||
@ -490,14 +490,16 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
|
||||
verror('map() requires an array')
|
||||
}
|
||||
|
||||
mut expr := node.args[0].expr
|
||||
mut closure_var_decl := ''
|
||||
if node.args[0].expr is ast.SelectorExpr {
|
||||
if node.args[0].expr.typ != ast.void_type {
|
||||
var_sym := g.table.sym(node.args[0].expr.typ)
|
||||
tmp_map_expr_result_name := g.new_tmp_var()
|
||||
if mut expr is ast.SelectorExpr {
|
||||
if expr.typ != ast.void_type {
|
||||
var_sym := g.table.sym(expr.typ)
|
||||
if var_sym.info is ast.FnType {
|
||||
ret_elem_type = 'voidptr'
|
||||
closure_var_decl = g.fn_var_signature(var_sym.info.func.return_type, var_sym.info.func.params.map(it.typ),
|
||||
'ti')
|
||||
tmp_map_expr_result_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -508,34 +510,34 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
|
||||
i := g.new_tmp_var()
|
||||
g.writeln('for (int ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {')
|
||||
g.indent++
|
||||
g.write_prepared_it(inp_info, inp_elem_type, past.tmp_var, i)
|
||||
var_name := g.get_array_expr_param_name(mut expr)
|
||||
g.write_prepared_var(var_name, inp_info, inp_elem_type, past.tmp_var, i)
|
||||
g.set_current_pos_as_last_stmt_pos()
|
||||
mut is_embed_map_filter := false
|
||||
mut expr := node.args[0].expr
|
||||
match mut expr {
|
||||
ast.AnonFn {
|
||||
g.write('${ret_elem_type} ti = ')
|
||||
g.write('${ret_elem_type} ${tmp_map_expr_result_name} = ')
|
||||
if expr.inherited_vars.len > 0 {
|
||||
g.write_closure_fn(mut expr)
|
||||
g.write_closure_fn(mut expr, var_name)
|
||||
} else {
|
||||
g.gen_anon_fn_decl(mut expr)
|
||||
g.write('${expr.decl.name}(it)')
|
||||
g.write('${expr.decl.name}(${var_name})')
|
||||
}
|
||||
}
|
||||
ast.Ident {
|
||||
g.write('${ret_elem_type} ti = ')
|
||||
g.write('${ret_elem_type} ${tmp_map_expr_result_name} = ')
|
||||
if expr.kind == .function {
|
||||
g.write('${c_name(expr.name)}(it)')
|
||||
g.write('${c_name(expr.name)}(${var_name})')
|
||||
} else if expr.kind == .variable {
|
||||
var_info := expr.var_info()
|
||||
sym := g.table.sym(var_info.typ)
|
||||
if sym.kind == .function {
|
||||
g.write('${c_name(expr.name)}(it)')
|
||||
g.write('${c_name(expr.name)}(${var_name})')
|
||||
} else {
|
||||
g.expr(node.args[0].expr)
|
||||
g.expr(expr)
|
||||
}
|
||||
} else {
|
||||
g.expr(node.args[0].expr)
|
||||
g.expr(expr)
|
||||
}
|
||||
}
|
||||
ast.CallExpr {
|
||||
@ -543,8 +545,8 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
|
||||
is_embed_map_filter = true
|
||||
g.set_current_pos_as_last_stmt_pos()
|
||||
}
|
||||
g.write('${ret_elem_type} ti = ')
|
||||
g.expr(node.args[0].expr)
|
||||
g.write('${ret_elem_type} ${tmp_map_expr_result_name} = ')
|
||||
g.expr(expr)
|
||||
}
|
||||
ast.CastExpr {
|
||||
// value.map(Type(it)) when `value` is a comptime var
|
||||
@ -554,20 +556,24 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
|
||||
expr.expr_type = g.table.value_type(ctyp)
|
||||
}
|
||||
}
|
||||
g.write('${ret_elem_type} ti = ')
|
||||
g.expr(node.args[0].expr)
|
||||
g.write('${ret_elem_type} ${tmp_map_expr_result_name} = ')
|
||||
g.expr(expr)
|
||||
}
|
||||
ast.LambdaExpr {
|
||||
g.write('${ret_elem_type} ${tmp_map_expr_result_name} = ')
|
||||
g.expr(expr.expr)
|
||||
}
|
||||
else {
|
||||
if closure_var_decl != '' {
|
||||
g.write('${closure_var_decl} = ')
|
||||
} else {
|
||||
g.write('${ret_elem_type} ti = ')
|
||||
g.write('${ret_elem_type} ${tmp_map_expr_result_name} = ')
|
||||
}
|
||||
g.expr(node.args[0].expr)
|
||||
g.expr(expr)
|
||||
}
|
||||
}
|
||||
g.writeln(';')
|
||||
g.writeln('array_push${noscan}((array*)&${past.tmp_var}, &ti);')
|
||||
g.writeln('array_push${noscan}((array*)&${past.tmp_var}, &${tmp_map_expr_result_name});')
|
||||
g.indent--
|
||||
g.writeln('}')
|
||||
if !is_embed_map_filter {
|
||||
@ -742,34 +748,35 @@ fn (mut g Gen) gen_array_filter(node ast.CallExpr) {
|
||||
i := g.new_tmp_var()
|
||||
g.writeln('for (int ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {')
|
||||
g.indent++
|
||||
g.write_prepared_it(info, elem_type_str, past.tmp_var, i)
|
||||
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
|
||||
mut expr := node.args[0].expr
|
||||
match mut expr {
|
||||
ast.AnonFn {
|
||||
g.write('if (')
|
||||
if expr.inherited_vars.len > 0 {
|
||||
g.write_closure_fn(mut expr)
|
||||
g.write_closure_fn(mut expr, var_name)
|
||||
} else {
|
||||
g.gen_anon_fn_decl(mut expr)
|
||||
g.write('${expr.decl.name}(it)')
|
||||
g.write('${expr.decl.name}(${var_name})')
|
||||
}
|
||||
}
|
||||
ast.Ident {
|
||||
g.write('if (')
|
||||
if expr.kind == .function {
|
||||
g.write('${c_name(expr.name)}(it)')
|
||||
g.write('${c_name(expr.name)}(${var_name})')
|
||||
} else if expr.kind == .variable {
|
||||
var_info := expr.var_info()
|
||||
sym_t := g.table.sym(var_info.typ)
|
||||
if sym_t.kind == .function {
|
||||
g.write('${c_name(expr.name)}(it)')
|
||||
g.write('${c_name(expr.name)}(${var_name})')
|
||||
} else {
|
||||
g.expr(node.args[0].expr)
|
||||
g.expr(expr)
|
||||
}
|
||||
} else {
|
||||
g.expr(node.args[0].expr)
|
||||
g.expr(expr)
|
||||
}
|
||||
}
|
||||
ast.CallExpr {
|
||||
@ -778,15 +785,19 @@ fn (mut g Gen) gen_array_filter(node ast.CallExpr) {
|
||||
g.set_current_pos_as_last_stmt_pos()
|
||||
}
|
||||
g.write('if (')
|
||||
g.expr(node.args[0].expr)
|
||||
g.expr(expr)
|
||||
}
|
||||
ast.LambdaExpr {
|
||||
g.write('if (')
|
||||
g.expr(expr.expr)
|
||||
}
|
||||
else {
|
||||
g.write('if (')
|
||||
g.expr(node.args[0].expr)
|
||||
g.expr(expr)
|
||||
}
|
||||
}
|
||||
g.writeln(') {')
|
||||
g.writeln('\tarray_push${noscan}((array*)&${past.tmp_var}, &it);')
|
||||
g.writeln('\tarray_push${noscan}((array*)&${past.tmp_var}, &${var_name});')
|
||||
g.writeln('}')
|
||||
g.indent--
|
||||
g.writeln('}')
|
||||
@ -1127,34 +1138,35 @@ fn (mut g Gen) gen_array_any(node ast.CallExpr) {
|
||||
i := g.new_tmp_var()
|
||||
g.writeln('for (int ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {')
|
||||
g.indent++
|
||||
g.write_prepared_it(info, elem_type_str, past.tmp_var, i)
|
||||
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
|
||||
mut expr := node.args[0].expr
|
||||
match mut expr {
|
||||
ast.AnonFn {
|
||||
g.write('if (')
|
||||
if expr.inherited_vars.len > 0 {
|
||||
g.write_closure_fn(mut expr)
|
||||
g.write_closure_fn(mut expr, var_name)
|
||||
} else {
|
||||
g.gen_anon_fn_decl(mut expr)
|
||||
g.write('${expr.decl.name}(it)')
|
||||
g.write('${expr.decl.name}(${var_name})')
|
||||
}
|
||||
}
|
||||
ast.Ident {
|
||||
g.write('if (')
|
||||
if expr.kind == .function {
|
||||
g.write('${c_name(expr.name)}(it)')
|
||||
g.write('${c_name(expr.name)}(${var_name})')
|
||||
} else if expr.kind == .variable {
|
||||
var_info := expr.var_info()
|
||||
sym_t := g.table.sym(var_info.typ)
|
||||
if sym_t.kind == .function {
|
||||
g.write('${c_name(expr.name)}(it)')
|
||||
g.write('${c_name(expr.name)}(${var_name})')
|
||||
} else {
|
||||
g.expr(node.args[0].expr)
|
||||
g.expr(expr)
|
||||
}
|
||||
} else {
|
||||
g.expr(node.args[0].expr)
|
||||
g.expr(expr)
|
||||
}
|
||||
}
|
||||
ast.CallExpr {
|
||||
@ -1163,11 +1175,15 @@ fn (mut g Gen) gen_array_any(node ast.CallExpr) {
|
||||
g.set_current_pos_as_last_stmt_pos()
|
||||
}
|
||||
g.write('if (')
|
||||
g.expr(node.args[0].expr)
|
||||
g.expr(expr)
|
||||
}
|
||||
ast.LambdaExpr {
|
||||
g.write('if (')
|
||||
g.expr(expr.expr)
|
||||
}
|
||||
else {
|
||||
g.write('if (')
|
||||
g.expr(node.args[0].expr)
|
||||
g.expr(expr)
|
||||
}
|
||||
}
|
||||
g.writeln(') {')
|
||||
@ -1202,35 +1218,36 @@ fn (mut g Gen) gen_array_all(node ast.CallExpr) {
|
||||
i := g.new_tmp_var()
|
||||
g.writeln('for (int ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {')
|
||||
g.indent++
|
||||
g.write_prepared_it(info, elem_type_str, past.tmp_var, i)
|
||||
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.empty_line = true
|
||||
g.set_current_pos_as_last_stmt_pos()
|
||||
mut is_embed_map_filter := false
|
||||
mut expr := node.args[0].expr
|
||||
match mut expr {
|
||||
ast.AnonFn {
|
||||
g.write('if (!(')
|
||||
if expr.inherited_vars.len > 0 {
|
||||
g.write_closure_fn(mut expr)
|
||||
g.write_closure_fn(mut expr, var_name)
|
||||
} else {
|
||||
g.gen_anon_fn_decl(mut expr)
|
||||
g.write('${expr.decl.name}(it)')
|
||||
g.write('${expr.decl.name}(${var_name})')
|
||||
}
|
||||
}
|
||||
ast.Ident {
|
||||
g.write('if (!(')
|
||||
if expr.kind == .function {
|
||||
g.write('${c_name(expr.name)}(it)')
|
||||
g.write('${c_name(expr.name)}(${var_name})')
|
||||
} else if expr.kind == .variable {
|
||||
var_info := expr.var_info()
|
||||
sym_t := g.table.sym(var_info.typ)
|
||||
if sym_t.kind == .function {
|
||||
g.write('${c_name(expr.name)}(it)')
|
||||
g.write('${c_name(expr.name)}(${var_name})')
|
||||
} else {
|
||||
g.expr(node.args[0].expr)
|
||||
g.expr(expr)
|
||||
}
|
||||
} else {
|
||||
g.expr(node.args[0].expr)
|
||||
g.expr(expr)
|
||||
}
|
||||
}
|
||||
ast.CallExpr {
|
||||
@ -1239,11 +1256,15 @@ fn (mut g Gen) gen_array_all(node ast.CallExpr) {
|
||||
g.set_current_pos_as_last_stmt_pos()
|
||||
}
|
||||
g.write('if (!(')
|
||||
g.expr(node.args[0].expr)
|
||||
g.expr(expr)
|
||||
}
|
||||
ast.LambdaExpr {
|
||||
g.write('if (!(')
|
||||
g.expr(expr.expr)
|
||||
}
|
||||
else {
|
||||
g.write('if (!(')
|
||||
g.expr(node.args[0].expr)
|
||||
g.expr(expr)
|
||||
}
|
||||
}
|
||||
g.writeln(')) {')
|
||||
@ -1290,12 +1311,12 @@ fn (mut g Gen) write_prepared_tmp_value(tmp string, node &ast.CallExpr, tmp_styp
|
||||
return has_infix_left_var_name
|
||||
}
|
||||
|
||||
fn (mut g Gen) write_prepared_it(inp_info ast.Array, inp_elem_type string, tmp string, i string) {
|
||||
fn (mut g Gen) write_prepared_var(var_name string, inp_info ast.Array, inp_elem_type string, tmp string, i string) {
|
||||
if g.table.sym(inp_info.elem_type).kind == .array_fixed {
|
||||
g.writeln('${inp_elem_type} it;')
|
||||
g.writeln('memcpy(&it, ((${inp_elem_type}*) ${tmp}_orig.data)[${i}], sizeof(${inp_elem_type}));')
|
||||
g.writeln('${inp_elem_type} ${var_name};')
|
||||
g.writeln('memcpy(&${var_name}, ((${inp_elem_type}*) ${tmp}_orig.data)[${i}], sizeof(${inp_elem_type}));')
|
||||
} else {
|
||||
g.writeln('${inp_elem_type} it = ((${inp_elem_type}*) ${tmp}_orig.data)[${i}];')
|
||||
g.writeln('${inp_elem_type} ${var_name} = ((${inp_elem_type}*) ${tmp}_orig.data)[${i}];')
|
||||
}
|
||||
}
|
||||
|
||||
@ -1313,3 +1334,11 @@ fn (mut g Gen) fixed_array_var_init(expr ast.Expr, size int) {
|
||||
}
|
||||
g.write('}')
|
||||
}
|
||||
|
||||
fn (mut g Gen) get_array_expr_param_name(mut expr ast.Expr) string {
|
||||
return if mut expr is ast.LambdaExpr {
|
||||
expr.params[0].name
|
||||
} else {
|
||||
'it'
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user