Skip to content

Commit 9a8f302

Browse files
authored
cgen: implement option fixed array (#17400)
1 parent 2836544 commit 9a8f302

File tree

3 files changed

+112
-36
lines changed

3 files changed

+112
-36
lines changed

vlib/v/gen/c/assign.v

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -346,37 +346,43 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
346346
} else if node.op == .assign && !g.pref.translated
347347
&& (is_fixed_array_init || (right_sym.kind == .array_fixed && val is ast.Ident)) {
348348
// Fixed arrays
349-
mut v_var := ''
350-
arr_typ := styp.trim('*')
351-
if is_fixed_array_init {
352-
right := val as ast.ArrayInit
353-
v_var = g.new_tmp_var()
354-
g.write('${arr_typ} ${v_var} = ')
355-
g.expr(right)
356-
g.writeln(';')
357-
} else {
358-
right := val as ast.Ident
359-
v_var = right.name
360-
}
361-
pos := g.out.len
362-
g.expr(left)
363-
364-
if g.is_arraymap_set && g.arraymap_set_pos > 0 {
365-
g.go_back_to(g.arraymap_set_pos)
366-
g.write(', &${v_var})')
367-
g.is_arraymap_set = false
368-
g.arraymap_set_pos = 0
349+
if is_fixed_array_init && var_type.has_flag(.option) {
350+
g.expr(left)
351+
g.write(' = ')
352+
g.expr_with_opt(val, val_type, var_type)
369353
} else {
370-
g.go_back_to(pos)
371-
is_var_mut := !is_decl && left.is_auto_deref_var()
372-
addr_left := if is_var_mut { '' } else { '&' }
373-
g.writeln('')
374-
g.write('memcpy(${addr_left}')
354+
mut v_var := ''
355+
arr_typ := styp.trim('*')
356+
if is_fixed_array_init {
357+
right := val as ast.ArrayInit
358+
v_var = g.new_tmp_var()
359+
g.write('${arr_typ} ${v_var} = ')
360+
g.expr(right)
361+
g.writeln(';')
362+
} else {
363+
right := val as ast.Ident
364+
v_var = right.name
365+
}
366+
pos := g.out.len
375367
g.expr(left)
376-
addr_val := if is_fixed_array_var { '' } else { '&' }
377-
g.writeln(', ${addr_val}${v_var}, sizeof(${arr_typ}));')
368+
369+
if g.is_arraymap_set && g.arraymap_set_pos > 0 {
370+
g.go_back_to(g.arraymap_set_pos)
371+
g.write(', &${v_var})')
372+
g.is_arraymap_set = false
373+
g.arraymap_set_pos = 0
374+
} else {
375+
g.go_back_to(pos)
376+
is_var_mut := !is_decl && left.is_auto_deref_var()
377+
addr_left := if is_var_mut { '' } else { '&' }
378+
g.writeln('')
379+
g.write('memcpy(${addr_left}')
380+
g.expr(left)
381+
addr_val := if is_fixed_array_var { '' } else { '&' }
382+
g.writeln(', ${addr_val}${v_var}, sizeof(${arr_typ}));')
383+
}
384+
g.is_assign_lhs = false
378385
}
379-
g.is_assign_lhs = false
380386
} else {
381387
is_inside_ternary := g.inside_ternary != 0
382388
cur_line := if is_inside_ternary && is_decl {
@@ -565,11 +571,17 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
565571
} else {
566572
'(byte*)&'
567573
}
568-
g.write('memcpy(${final_typ_str}')
569-
g.expr(left)
570-
g.write(', ${final_ref_str}')
571-
g.expr(val)
572-
g.write(', sizeof(${typ_str}))')
574+
if val_type.has_flag(.option) {
575+
g.expr(left)
576+
g.write(' = ')
577+
g.expr(val)
578+
} else {
579+
g.write('memcpy(${final_typ_str}')
580+
g.expr(left)
581+
g.write(', ${final_ref_str}')
582+
g.expr(val)
583+
g.write(', sizeof(${typ_str}))')
584+
}
573585
} else if is_decl {
574586
g.is_shared = var_type.has_flag(.shared_f)
575587
if is_fixed_array_init && !has_val {

vlib/v/parser/parser.v

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2543,13 +2543,18 @@ pub fn (mut p Parser) name_expr() ast.Expr {
25432543
}
25442544
}
25452545
} else if p.peek_tok.kind == .lpar || is_generic_call || is_generic_cast
2546-
|| (is_option && p.peek_token(2).kind == .lpar) || (is_option && p.peek_tok.kind == .lsbr
2546+
|| (is_option && p.peek_token(2).kind == .lpar) || (is_option && ((p.peek_tok.kind == .lsbr
25472547
&& p.peek_token(2).kind == .rsbr && p.peek_token(3).kind == .name
2548-
&& p.peek_token(4).kind == .lpar) {
2548+
&& p.peek_token(4).kind == .lpar) || (p.peek_tok.kind == .lsbr
2549+
&& p.peek_token(2).kind == .number && p.peek_token(3).kind == .rsbr
2550+
&& p.peek_token(4).kind == .name && p.peek_token(5).kind == .lpar))) {
25492551
is_array := p.peek_tok.kind == .lsbr
2552+
is_fixed_array := is_array && p.peek_token(2).kind == .number
25502553
// foo(), foo<int>() or type() cast
25512554
mut name := if is_option {
2552-
if is_array { p.peek_token(3).lit } else { p.peek_tok.lit }
2555+
if is_array { p.peek_token(if is_fixed_array { 4 } else { 3 }).lit
2556+
} else { p.peek_tok.lit
2557+
}
25532558
} else {
25542559
p.tok.lit
25552560
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
fn f_test(args ?[2]int) ? {
2+
println(args)
3+
assert args?.len == 2
4+
}
5+
6+
fn f_arr(args ?[3]f64) ?[]f64 {
7+
mut ret := ?[]f64(none)
8+
ret = [-6.0]
9+
ret?.pop()
10+
ret? << args?[0]
11+
ret? << args?[1]
12+
ret? << args?[2]
13+
return ret
14+
}
15+
16+
fn f_arr2(args ?[3]f64) ?[]f64 {
17+
arr := args?
18+
mut ret := []f64{}
19+
ret << arr[0]
20+
ret << arr[1]
21+
ret << arr[2]
22+
return ret
23+
}
24+
25+
fn test_simple() {
26+
mut arr := ?[3]int(none)
27+
println(arr) // Option(error: none)
28+
}
29+
30+
fn test_simple_assign() {
31+
mut arr := ?[3]int(none)
32+
assert arr == none
33+
34+
arr = [1, 2, 3]!
35+
assert arr != none
36+
37+
println(arr) // Option([1, 2, 3])
38+
}
39+
40+
fn test_array_fixed_param() {
41+
f_test([1, 2]!)
42+
}
43+
44+
fn test_assign() {
45+
mut a := ?[2]string(none)
46+
assert a == none
47+
a = ['a', 'b']!
48+
assert a != none
49+
a = none
50+
assert a == none
51+
}
52+
53+
fn test_fn_call() {
54+
assert f_arr([0.0, 1.2, 2.3]!)?.len == 3
55+
}
56+
57+
fn test_fn_unwrap_call() {
58+
assert f_arr2([0.0, 1.2, 2.3]!)?.len == 3
59+
}

0 commit comments

Comments
 (0)