1
0
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:
Felipe Pena 2023-02-24 14:25:31 -03:00 committed by GitHub
parent 2836544978
commit 9a8f3025f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 113 additions and 37 deletions

View File

@ -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 {

View File

@ -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
}

View 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
}