mirror of
https://github.com/vlang/v.git
synced 2025-09-08 23:07:19 -04:00
This commit is contained in:
parent
e234a2d37e
commit
864845bccd
@ -2559,6 +2559,7 @@ fn (mut g Gen) expr_with_var(expr ast.Expr, got_type_raw ast.Type, expected_type
|
||||
g.empty_line = true
|
||||
tmp_var := g.new_tmp_var()
|
||||
styp := g.styp(expected_type)
|
||||
|
||||
g.writeln('${styp} ${tmp_var};')
|
||||
g.write('memcpy(&${tmp_var}, ')
|
||||
g.expr(expr)
|
||||
@ -2567,6 +2568,24 @@ fn (mut g Gen) expr_with_var(expr ast.Expr, got_type_raw ast.Type, expected_type
|
||||
return tmp_var
|
||||
}
|
||||
|
||||
// expr_with_fixed_array generates code for fixed array initialization with expr which requires tmp var
|
||||
fn (mut g Gen) expr_with_fixed_array(expr ast.ArrayInit, got_type_raw ast.Type, expected_type ast.Type) string {
|
||||
stmt_str := g.go_before_last_stmt().trim_space()
|
||||
g.empty_line = true
|
||||
tmp_var := g.new_tmp_var()
|
||||
styp := g.styp(expected_type)
|
||||
g.writeln('${styp} ${tmp_var};')
|
||||
// [ foo(), foo() ]!
|
||||
val_typ := g.table.value_type(got_type_raw)
|
||||
for i, item_expr in expr.exprs {
|
||||
g.write('memcpy(${tmp_var}[${i}], ')
|
||||
g.expr(item_expr)
|
||||
g.writeln(', sizeof(${g.styp(val_typ)}));')
|
||||
}
|
||||
g.write(stmt_str)
|
||||
return tmp_var
|
||||
}
|
||||
|
||||
// use instead of expr() when you need to cast to a different type
|
||||
fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_type ast.Type) {
|
||||
got_type := ast.mktyp(got_type_raw)
|
||||
@ -2620,7 +2639,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
|
||||
// Do not allocate for `Interface(unsafe{nil})` casts
|
||||
is_nil_cast := expr is ast.UnsafeExpr && expr.expr is ast.Nil
|
||||
if is_nil_cast {
|
||||
g.write2('/*nili*/', '((void*)0)')
|
||||
g.write2('/*nil*/', '((void*)0)')
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -6901,7 +6920,7 @@ fn (mut g Gen) write_types(symbols []&ast.TypeSymbol) {
|
||||
base)};')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if !(elem_sym.info is ast.ArrayFixed && elem_sym.info.is_fn_ret) {
|
||||
g.type_definitions.writeln('typedef ${fixed_elem_name} ${styp} [${len}];')
|
||||
}
|
||||
}
|
||||
|
@ -680,33 +680,57 @@ fn (mut g Gen) struct_init_field(sfield ast.StructInitField, language ast.Langua
|
||||
|
||||
field_unwrap_typ := g.unwrap_generic(sfield.typ)
|
||||
field_unwrap_sym := g.table.final_sym(field_unwrap_typ)
|
||||
if field_unwrap_sym.kind == .array_fixed && sfield.expr in [ast.Ident, ast.SelectorExpr] {
|
||||
info := field_unwrap_sym.info as ast.ArrayFixed
|
||||
g.fixed_array_var_init(g.expr_string(sfield.expr), sfield.expr.is_auto_deref_var(),
|
||||
info.elem_type, info.size)
|
||||
} else if field_unwrap_sym.kind == .array_fixed && (sfield.expr is ast.CallExpr
|
||||
|| (sfield.expr is ast.ArrayInit && sfield.expr.has_index)) {
|
||||
info := field_unwrap_sym.info as ast.ArrayFixed
|
||||
tmp_var := g.expr_with_var(sfield.expr, sfield.typ, sfield.expected_type)
|
||||
g.fixed_array_var_init(tmp_var, false, info.elem_type, info.size)
|
||||
is_auto_deref_var := sfield.expr.is_auto_deref_var()
|
||||
if field_unwrap_sym.info is ast.ArrayFixed {
|
||||
match sfield.expr {
|
||||
ast.Ident, ast.SelectorExpr {
|
||||
g.fixed_array_var_init(g.expr_string(sfield.expr), is_auto_deref_var,
|
||||
field_unwrap_sym.info.elem_type, field_unwrap_sym.info.size)
|
||||
}
|
||||
ast.CallExpr {
|
||||
tmp_var := g.expr_with_var(sfield.expr, sfield.typ, sfield.expected_type)
|
||||
g.fixed_array_var_init(tmp_var, false, field_unwrap_sym.info.elem_type,
|
||||
field_unwrap_sym.info.size)
|
||||
}
|
||||
ast.ArrayInit {
|
||||
if sfield.expr.has_index {
|
||||
tmp_var := g.expr_with_var(sfield.expr, sfield.typ, sfield.expected_type)
|
||||
g.fixed_array_var_init(tmp_var, false, field_unwrap_sym.info.elem_type,
|
||||
field_unwrap_sym.info.size)
|
||||
} else if sfield.expr.exprs.len > 0 && sfield.expr.exprs.any(it is ast.CallExpr) {
|
||||
tmp_var := g.expr_with_fixed_array(sfield.expr, sfield.typ, sfield.expected_type)
|
||||
g.fixed_array_var_init(tmp_var, false, field_unwrap_sym.info.elem_type,
|
||||
field_unwrap_sym.info.size)
|
||||
} else {
|
||||
g.struct_init_field_default(field_unwrap_typ, sfield)
|
||||
}
|
||||
}
|
||||
else {
|
||||
g.struct_init_field_default(field_unwrap_typ, sfield)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if field_unwrap_typ != ast.voidptr_type && field_unwrap_typ != ast.nil_type
|
||||
&& (sfield.expected_type.is_ptr() && !sfield.expected_type.has_flag(.shared_f))
|
||||
&& !sfield.expected_type.has_flag(.option)
|
||||
&& !field_unwrap_typ.is_any_kind_of_pointer() && !field_unwrap_typ.is_number() {
|
||||
g.write('/* autoref */&')
|
||||
}
|
||||
|
||||
if (sfield.expected_type.has_flag(.option) && !field_unwrap_typ.has_flag(.option))
|
||||
|| (sfield.expected_type.has_flag(.result) && !field_unwrap_typ.has_flag(.result)) {
|
||||
g.expr_with_opt(sfield.expr, field_unwrap_typ, sfield.expected_type)
|
||||
} else if sfield.expr is ast.LambdaExpr && sfield.expected_type.has_flag(.option) {
|
||||
g.expr_opt_with_cast(sfield.expr, field_unwrap_typ, sfield.expected_type)
|
||||
} else {
|
||||
g.left_is_opt = true
|
||||
g.expr_with_cast(sfield.expr, field_unwrap_typ, sfield.expected_type)
|
||||
}
|
||||
g.struct_init_field_default(field_unwrap_typ, sfield)
|
||||
}
|
||||
g.inside_cast_in_heap = inside_cast_in_heap // restore value for further struct inits
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) struct_init_field_default(field_unwrap_typ ast.Type, sfield &ast.StructInitField) {
|
||||
if field_unwrap_typ != ast.voidptr_type && field_unwrap_typ != ast.nil_type
|
||||
&& (sfield.expected_type.is_ptr() && !sfield.expected_type.has_flag(.shared_f))
|
||||
&& !sfield.expected_type.has_flag(.option) && !field_unwrap_typ.is_any_kind_of_pointer()
|
||||
&& !field_unwrap_typ.is_number() {
|
||||
g.write('/* autoref */&')
|
||||
}
|
||||
|
||||
if (sfield.expected_type.has_flag(.option) && !field_unwrap_typ.has_flag(.option))
|
||||
|| (sfield.expected_type.has_flag(.result) && !field_unwrap_typ.has_flag(.result)) {
|
||||
g.expr_with_opt(sfield.expr, field_unwrap_typ, sfield.expected_type)
|
||||
} else if sfield.expr is ast.LambdaExpr && sfield.expected_type.has_flag(.option) {
|
||||
g.expr_opt_with_cast(sfield.expr, field_unwrap_typ, sfield.expected_type)
|
||||
} else {
|
||||
g.left_is_opt = true
|
||||
g.expr_with_cast(sfield.expr, field_unwrap_typ, sfield.expected_type)
|
||||
}
|
||||
}
|
||||
|
22
vlib/v/tests/fixed_array_2_dims_init_test.v
Normal file
22
vlib/v/tests/fixed_array_2_dims_init_test.v
Normal file
@ -0,0 +1,22 @@
|
||||
module main
|
||||
|
||||
struct Uniforms {
|
||||
lights [2][4]f32
|
||||
}
|
||||
|
||||
fn r() [4]f32 {
|
||||
return [f32(1.1), 1.2, 1.3, 1.4]!
|
||||
}
|
||||
|
||||
fn test_main() {
|
||||
v := Uniforms{
|
||||
lights: [
|
||||
r(),
|
||||
r(),
|
||||
]!
|
||||
}
|
||||
assert v.lights[0][0] == f32(1.1)
|
||||
assert v.lights[0][1] == f32(1.2)
|
||||
assert v.lights[0][2] == f32(1.3)
|
||||
assert v.lights[0][3] == f32(1.4)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user