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,6 +346,11 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
} else if node.op == .assign && !g.pref.translated } else if node.op == .assign && !g.pref.translated
&& (is_fixed_array_init || (right_sym.kind == .array_fixed && val is ast.Ident)) { && (is_fixed_array_init || (right_sym.kind == .array_fixed && val is ast.Ident)) {
// Fixed arrays // Fixed arrays
if is_fixed_array_init && var_type.has_flag(.option) {
g.expr(left)
g.write(' = ')
g.expr_with_opt(val, val_type, var_type)
} else {
mut v_var := '' mut v_var := ''
arr_typ := styp.trim('*') arr_typ := styp.trim('*')
if is_fixed_array_init { if is_fixed_array_init {
@ -377,6 +382,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
g.writeln(', ${addr_val}${v_var}, sizeof(${arr_typ}));') g.writeln(', ${addr_val}${v_var}, sizeof(${arr_typ}));')
} }
g.is_assign_lhs = false g.is_assign_lhs = false
}
} else { } else {
is_inside_ternary := g.inside_ternary != 0 is_inside_ternary := g.inside_ternary != 0
cur_line := if is_inside_ternary && is_decl { cur_line := if is_inside_ternary && is_decl {
@ -565,11 +571,17 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
} else { } else {
'(byte*)&' '(byte*)&'
} }
if val_type.has_flag(.option) {
g.expr(left)
g.write(' = ')
g.expr(val)
} else {
g.write('memcpy(${final_typ_str}') g.write('memcpy(${final_typ_str}')
g.expr(left) g.expr(left)
g.write(', ${final_ref_str}') g.write(', ${final_ref_str}')
g.expr(val) g.expr(val)
g.write(', sizeof(${typ_str}))') g.write(', sizeof(${typ_str}))')
}
} else if is_decl { } else if is_decl {
g.is_shared = var_type.has_flag(.shared_f) g.is_shared = var_type.has_flag(.shared_f)
if is_fixed_array_init && !has_val { 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 } 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(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_array := p.peek_tok.kind == .lsbr
is_fixed_array := is_array && p.peek_token(2).kind == .number
// foo(), foo<int>() or type() cast // foo(), foo<int>() or type() cast
mut name := if is_option { 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 { } else {
p.tok.lit 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
}