Skip to content

Commit 1c992de

Browse files
authored
cgen: fix array of fns index call with embeded array index (fix #17381) (#22198)
1 parent 62ab1be commit 1c992de

File tree

2 files changed

+68
-3
lines changed

2 files changed

+68
-3
lines changed

vlib/v/gen/c/index.v

+4-3
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym ast.TypeSymbol) {
234234
}
235235
} else {
236236
is_direct_array_access := g.is_direct_array_access || node.is_direct
237+
is_fn_index_call := g.is_fn_index_call && elem_sym.info is ast.FnType
237238
// do not clone inside `opt_ok(opt_ok(&(string[]) {..})` before returns
238239
needs_clone := info.elem_type == ast.string_type_idx && g.is_autofree && !(g.inside_return
239240
&& g.fn_decl != unsafe { nil } && g.fn_decl.return_type.has_flag(.option))
@@ -257,7 +258,7 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym ast.TypeSymbol) {
257258
if needs_clone {
258259
g.write('/*2*/string_clone(')
259260
}
260-
if g.is_fn_index_call {
261+
if is_fn_index_call {
261262
if elem_sym.info is ast.FnType {
262263
g.write('((')
263264
g.write_fn_ptr_decl(&elem_sym.info, '')
@@ -297,13 +298,13 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym ast.TypeSymbol) {
297298
g.write('data)[')
298299
g.expr(node.index)
299300
g.write(']')
300-
if g.is_fn_index_call {
301+
if is_fn_index_call {
301302
g.write(')')
302303
}
303304
} else {
304305
g.write(', ')
305306
g.expr(node.index)
306-
if g.is_fn_index_call {
307+
if is_fn_index_call {
307308
g.write(')))')
308309
} else {
309310
g.write('))')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
fn max_speed(functions []fn (int) int, g fn (int) int, end_time int) int {
2+
mut s := [0]
3+
mut gears := []int{len: end_time, init: 0}
4+
5+
for t in 0 .. end_time {
6+
stay_in_gear_speed := if t - 1 >= 0 { functions[gears[t - 1]](s[t - 1]) } else { 0 }
7+
shift_gear_speed := if t - 2 >= 0 { functions[gears[t - 2] + 1](g(s[t - 2])) } else { 0 }
8+
if stay_in_gear_speed > shift_gear_speed {
9+
gears[t] = if t - 1 >= 0 { gears[t - 1] } else { 0 }
10+
s << stay_in_gear_speed
11+
} else {
12+
gears[t] = if t - 2 >= 0 { gears[t - 2] } else { 0 } + 1
13+
s << shift_gear_speed
14+
}
15+
}
16+
return s[end_time]
17+
}
18+
19+
@[direct_array_access]
20+
fn max_speed_direct_access(functions []fn (int) int, g fn (int) int, end_time int) int {
21+
mut s := [0]
22+
mut gears := []int{len: end_time, init: 0}
23+
24+
for t in 0 .. end_time {
25+
stay_in_gear_speed := if t - 1 >= 0 { functions[gears[t - 1]](s[t - 1]) } else { 0 }
26+
shift_gear_speed := if t - 2 >= 0 { functions[gears[t - 2] + 1](g(s[t - 2])) } else { 0 }
27+
if stay_in_gear_speed > shift_gear_speed {
28+
gears[t] = if t - 1 >= 0 { gears[t - 1] } else { 0 }
29+
s << stay_in_gear_speed
30+
} else {
31+
gears[t] = if t - 2 >= 0 { gears[t - 2] } else { 0 } + 1
32+
s << shift_gear_speed
33+
}
34+
}
35+
return s[end_time]
36+
}
37+
38+
fn first_gear(speed int) int {
39+
return speed + 1
40+
}
41+
42+
fn second_gear(speed int) int {
43+
return speed + 1
44+
}
45+
46+
fn third_gear(speed int) int {
47+
return speed + 1
48+
}
49+
50+
fn decelerate(speed int) int {
51+
return speed - 3
52+
}
53+
54+
fn test_array_of_fns_index_call_with_embeded_array_call() {
55+
funcs := [first_gear, second_gear, third_gear]
56+
57+
speed1 := max_speed(funcs, decelerate, 3)
58+
println(speed1)
59+
assert speed1 == 1
60+
61+
speed2 := max_speed_direct_access(funcs, decelerate, 3)
62+
println(speed2)
63+
assert speed2 == 1
64+
}

0 commit comments

Comments
 (0)