mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: implement option fixed array (#17400)
This commit is contained in:
parent
2836544978
commit
9a8f3025f5
@ -346,37 +346,43 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
||||
} else if node.op == .assign && !g.pref.translated
|
||||
&& (is_fixed_array_init || (right_sym.kind == .array_fixed && val is ast.Ident)) {
|
||||
// Fixed arrays
|
||||
mut v_var := ''
|
||||
arr_typ := styp.trim('*')
|
||||
if is_fixed_array_init {
|
||||
right := val as ast.ArrayInit
|
||||
v_var = g.new_tmp_var()
|
||||
g.write('${arr_typ} ${v_var} = ')
|
||||
g.expr(right)
|
||||
g.writeln(';')
|
||||
} else {
|
||||
right := val as ast.Ident
|
||||
v_var = right.name
|
||||
}
|
||||
pos := g.out.len
|
||||
g.expr(left)
|
||||
|
||||
if g.is_arraymap_set && g.arraymap_set_pos > 0 {
|
||||
g.go_back_to(g.arraymap_set_pos)
|
||||
g.write(', &${v_var})')
|
||||
g.is_arraymap_set = false
|
||||
g.arraymap_set_pos = 0
|
||||
} else {
|
||||
g.go_back_to(pos)
|
||||
is_var_mut := !is_decl && left.is_auto_deref_var()
|
||||
addr_left := if is_var_mut { '' } else { '&' }
|
||||
g.writeln('')
|
||||
g.write('memcpy(${addr_left}')
|
||||
if is_fixed_array_init && var_type.has_flag(.option) {
|
||||
g.expr(left)
|
||||
addr_val := if is_fixed_array_var { '' } else { '&' }
|
||||
g.writeln(', ${addr_val}${v_var}, sizeof(${arr_typ}));')
|
||||
g.write(' = ')
|
||||
g.expr_with_opt(val, val_type, var_type)
|
||||
} else {
|
||||
mut v_var := ''
|
||||
arr_typ := styp.trim('*')
|
||||
if is_fixed_array_init {
|
||||
right := val as ast.ArrayInit
|
||||
v_var = g.new_tmp_var()
|
||||
g.write('${arr_typ} ${v_var} = ')
|
||||
g.expr(right)
|
||||
g.writeln(';')
|
||||
} else {
|
||||
right := val as ast.Ident
|
||||
v_var = right.name
|
||||
}
|
||||
pos := g.out.len
|
||||
g.expr(left)
|
||||
|
||||
if g.is_arraymap_set && g.arraymap_set_pos > 0 {
|
||||
g.go_back_to(g.arraymap_set_pos)
|
||||
g.write(', &${v_var})')
|
||||
g.is_arraymap_set = false
|
||||
g.arraymap_set_pos = 0
|
||||
} else {
|
||||
g.go_back_to(pos)
|
||||
is_var_mut := !is_decl && left.is_auto_deref_var()
|
||||
addr_left := if is_var_mut { '' } else { '&' }
|
||||
g.writeln('')
|
||||
g.write('memcpy(${addr_left}')
|
||||
g.expr(left)
|
||||
addr_val := if is_fixed_array_var { '' } else { '&' }
|
||||
g.writeln(', ${addr_val}${v_var}, sizeof(${arr_typ}));')
|
||||
}
|
||||
g.is_assign_lhs = false
|
||||
}
|
||||
g.is_assign_lhs = false
|
||||
} else {
|
||||
is_inside_ternary := g.inside_ternary != 0
|
||||
cur_line := if is_inside_ternary && is_decl {
|
||||
@ -565,11 +571,17 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
||||
} else {
|
||||
'(byte*)&'
|
||||
}
|
||||
g.write('memcpy(${final_typ_str}')
|
||||
g.expr(left)
|
||||
g.write(', ${final_ref_str}')
|
||||
g.expr(val)
|
||||
g.write(', sizeof(${typ_str}))')
|
||||
if val_type.has_flag(.option) {
|
||||
g.expr(left)
|
||||
g.write(' = ')
|
||||
g.expr(val)
|
||||
} else {
|
||||
g.write('memcpy(${final_typ_str}')
|
||||
g.expr(left)
|
||||
g.write(', ${final_ref_str}')
|
||||
g.expr(val)
|
||||
g.write(', sizeof(${typ_str}))')
|
||||
}
|
||||
} else if is_decl {
|
||||
g.is_shared = var_type.has_flag(.shared_f)
|
||||
if is_fixed_array_init && !has_val {
|
||||
|
@ -2543,13 +2543,18 @@ pub fn (mut p Parser) name_expr() ast.Expr {
|
||||
}
|
||||
}
|
||||
} else if p.peek_tok.kind == .lpar || is_generic_call || is_generic_cast
|
||||
|| (is_option && p.peek_token(2).kind == .lpar) || (is_option && p.peek_tok.kind == .lsbr
|
||||
|| (is_option && p.peek_token(2).kind == .lpar) || (is_option && ((p.peek_tok.kind == .lsbr
|
||||
&& p.peek_token(2).kind == .rsbr && p.peek_token(3).kind == .name
|
||||
&& p.peek_token(4).kind == .lpar) {
|
||||
&& p.peek_token(4).kind == .lpar) || (p.peek_tok.kind == .lsbr
|
||||
&& p.peek_token(2).kind == .number && p.peek_token(3).kind == .rsbr
|
||||
&& p.peek_token(4).kind == .name && p.peek_token(5).kind == .lpar))) {
|
||||
is_array := p.peek_tok.kind == .lsbr
|
||||
is_fixed_array := is_array && p.peek_token(2).kind == .number
|
||||
// foo(), foo<int>() or type() cast
|
||||
mut name := if is_option {
|
||||
if is_array { p.peek_token(3).lit } else { p.peek_tok.lit }
|
||||
if is_array { p.peek_token(if is_fixed_array { 4 } else { 3 }).lit
|
||||
} else { p.peek_tok.lit
|
||||
}
|
||||
} else {
|
||||
p.tok.lit
|
||||
}
|
||||
|
59
vlib/v/tests/option_fixed_array_test.v
Normal file
59
vlib/v/tests/option_fixed_array_test.v
Normal file
@ -0,0 +1,59 @@
|
||||
fn f_test(args ?[2]int) ? {
|
||||
println(args)
|
||||
assert args?.len == 2
|
||||
}
|
||||
|
||||
fn f_arr(args ?[3]f64) ?[]f64 {
|
||||
mut ret := ?[]f64(none)
|
||||
ret = [-6.0]
|
||||
ret?.pop()
|
||||
ret? << args?[0]
|
||||
ret? << args?[1]
|
||||
ret? << args?[2]
|
||||
return ret
|
||||
}
|
||||
|
||||
fn f_arr2(args ?[3]f64) ?[]f64 {
|
||||
arr := args?
|
||||
mut ret := []f64{}
|
||||
ret << arr[0]
|
||||
ret << arr[1]
|
||||
ret << arr[2]
|
||||
return ret
|
||||
}
|
||||
|
||||
fn test_simple() {
|
||||
mut arr := ?[3]int(none)
|
||||
println(arr) // Option(error: none)
|
||||
}
|
||||
|
||||
fn test_simple_assign() {
|
||||
mut arr := ?[3]int(none)
|
||||
assert arr == none
|
||||
|
||||
arr = [1, 2, 3]!
|
||||
assert arr != none
|
||||
|
||||
println(arr) // Option([1, 2, 3])
|
||||
}
|
||||
|
||||
fn test_array_fixed_param() {
|
||||
f_test([1, 2]!)
|
||||
}
|
||||
|
||||
fn test_assign() {
|
||||
mut a := ?[2]string(none)
|
||||
assert a == none
|
||||
a = ['a', 'b']!
|
||||
assert a != none
|
||||
a = none
|
||||
assert a == none
|
||||
}
|
||||
|
||||
fn test_fn_call() {
|
||||
assert f_arr([0.0, 1.2, 2.3]!)?.len == 3
|
||||
}
|
||||
|
||||
fn test_fn_unwrap_call() {
|
||||
assert f_arr2([0.0, 1.2, 2.3]!)?.len == 3
|
||||
}
|
Loading…
Reference in New Issue
Block a user