From 0ce4ebb7a75a5ced63d8bed17181b0396d696f0d Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Mon, 25 Nov 2024 20:30:53 -0300 Subject: [PATCH] fix --- vlib/v/gen/c/array.v | 33 ++++++++++++++------- vlib/v/gen/c/cgen.v | 31 +++++++++++++++++-- vlib/v/gen/c/infix.v | 7 ++--- vlib/v/gen/c/struct.v | 27 +++++------------ vlib/v/tests/fixed_array_update_expr_test.v | 10 +++++-- 5 files changed, 69 insertions(+), 39 deletions(-) diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index 5fce57dc1d6065..793ffcfb8e1215 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -135,7 +135,7 @@ fn (mut g Gen) fixed_array_init(node ast.ArrayInit, array_type Type, var_name st g.set_current_pos_as_last_stmt_pos() return } - if g.inside_struct_init && g.inside_cast { + if g.inside_struct_init && g.inside_cast && !g.inside_memset { ret_typ_str := g.styp(node.typ) g.write('(${ret_typ_str})') } @@ -158,7 +158,7 @@ fn (mut g Gen) fixed_array_init(node ast.ArrayInit, array_type Type, var_name st } else if elem_sym.kind == .array_fixed && expr is ast.CallExpr && g.table.final_sym(expr.return_type).kind == .array_fixed { elem_info := elem_sym.array_fixed_info() - tmp_var := g.expr_with_var(expr, node.expr_types[i]) + tmp_var := g.expr_with_var(expr, node.expr_types[i], false) g.fixed_array_var_init(tmp_var, false, elem_info.elem_type, elem_info.size) } else { if expr.is_auto_deref_var() { @@ -1650,6 +1650,7 @@ fn (mut g Gen) fixed_array_init_with_cast(expr ast.ArrayInit, typ ast.Type) { } fn (mut g Gen) fixed_array_update_expr_field(expr_str string, field_type ast.Type, field_name string, is_auto_deref bool, elem_type ast.Type, size int) { + elem_sym := g.table.sym(elem_type) if !g.inside_array_fixed_struct { g.write('{') defer { @@ -1657,15 +1658,27 @@ fn (mut g Gen) fixed_array_update_expr_field(expr_str string, field_type ast.Typ } } for i in 0 .. size { - g.write(expr_str) - if field_type.is_ptr() { - g.write('->') + if elem_sym.info is ast.ArrayFixed { + init_str := if g.inside_array_fixed_struct { + '${expr_str}' + } else { + '${expr_str}->${c_name(field_name)}[${i}]' + } + g.fixed_array_update_expr_field(init_str, field_type, field_name, is_auto_deref, + elem_sym.info.elem_type, elem_sym.info.size) } else { - g.write('.') - } - g.write(c_name(field_name)) - if !expr_str.starts_with('(') && !expr_str.starts_with('{') { - g.write('[${i}]') + g.write(expr_str) + if !expr_str.ends_with(']') { + if field_type.is_ptr() { + g.write('->') + } else { + g.write('.') + } + g.write(c_name(field_name)) + } + if !expr_str.starts_with('(') && !expr_str.starts_with('{') { + g.write('[${i}]') + } } if i != size - 1 { g.write(', ') diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 9b5346fdb8c99c..bf8fac81cd8e86 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -154,6 +154,7 @@ mut: inside_for_c_stmt bool inside_cast_in_heap int // inside cast to interface type in heap (resolve recursive calls) inside_cast bool + inside_memset bool inside_const bool inside_array_item bool inside_const_opt_or_res bool @@ -1626,6 +1627,7 @@ static inline void __${sym.cname}_pushval(${sym.cname} ch, ${push_arg} val) { } pub fn (mut g Gen) write_alias_typesymbol_declaration(sym ast.TypeSymbol) { + mut levels := 0 parent := g.table.type_symbols[sym.parent_idx] is_c_parent := parent.name.len > 2 && parent.name[0] == `C` && parent.name[1] == `.` mut is_fixed_array_of_non_builtin := false @@ -1639,10 +1641,30 @@ pub fn (mut g Gen) write_alias_typesymbol_declaration(sym ast.TypeSymbol) { parent_styp = g.styp(sym.info.parent_type) parent_sym := g.table.sym(sym.info.parent_type) if parent_sym.info is ast.ArrayFixed { - elem_sym := g.table.sym(parent_sym.info.elem_type) + mut elem_sym := g.table.sym(parent_sym.info.elem_type) if !elem_sym.is_builtin() { is_fixed_array_of_non_builtin = true } + + mut parent_elem_info := parent_sym.info as ast.ArrayFixed + mut parent_elem_styp := g.styp(sym.info.parent_type) + mut out := '' + for { + if mut elem_sym.info is ast.ArrayFixed { + out = + 'typedef ${elem_sym.cname} ${parent_elem_styp} [${parent_elem_info.size}]; //\n' + + out + parent_elem_styp = elem_sym.cname + parent_elem_info = elem_sym.info as ast.ArrayFixed + elem_sym = g.table.sym(elem_sym.info.elem_type) + levels++ + } else { + break + } + } + if out != '' { + g.type_definitions.writeln(out) + } } } } @@ -1650,7 +1672,7 @@ pub fn (mut g Gen) write_alias_typesymbol_declaration(sym ast.TypeSymbol) { // TODO: remove this check; it is here just to fix V rebuilding in -cstrict mode with clang-12 return } - if is_fixed_array_of_non_builtin { + if is_fixed_array_of_non_builtin && levels == 0 { g.alias_definitions.writeln('typedef ${parent_styp} ${sym.cname};') } else { g.type_definitions.writeln('typedef ${parent_styp} ${sym.cname};') @@ -2557,7 +2579,7 @@ fn (mut g Gen) call_cfn_for_casting_expr(fname string, expr ast.Expr, exp_is_ptr } // use instead of expr() when you need a var to use as reference -fn (mut g Gen) expr_with_var(expr ast.Expr, expected_type ast.Type) string { +fn (mut g Gen) expr_with_var(expr ast.Expr, expected_type ast.Type, do_cast bool) string { stmt_str := g.go_before_last_stmt().trim_space() g.empty_line = true tmp_var := g.new_tmp_var() @@ -2565,6 +2587,9 @@ fn (mut g Gen) expr_with_var(expr ast.Expr, expected_type ast.Type) string { g.writeln('${styp} ${tmp_var};') g.write('memcpy(&${tmp_var}, ') + if do_cast { + g.write('(${styp})') + } g.expr(expr) g.writeln(', sizeof(${styp}));') g.write(stmt_str) diff --git a/vlib/v/gen/c/infix.v b/vlib/v/gen/c/infix.v index 7a911ddb0eb9ec..bc4d0b28817f4f 100644 --- a/vlib/v/gen/c/infix.v +++ b/vlib/v/gen/c/infix.v @@ -1029,11 +1029,10 @@ fn (mut g Gen) infix_expr_left_shift_op(node ast.InfixExpr) { } if node.right is ast.CastExpr && node.right.expr is ast.ArrayInit { g.expr(node.right.expr) - } else if elem_sym.kind == .array_fixed + } else if elem_sym.info is ast.ArrayFixed && node.right in [ast.CallExpr, ast.DumpExpr] { - info := elem_sym.info as ast.ArrayFixed - tmpvar := g.expr_with_var(node.right, array_info.elem_type) - g.fixed_array_var_init(tmpvar, false, info.elem_type, info.size) + tmpvar := g.expr_with_var(node.right, array_info.elem_type, false) + g.fixed_array_var_init(tmpvar, false, elem_sym.info.elem_type, elem_sym.info.size) } else { g.expr_with_cast(node.right, right.typ, array_info.elem_type) } diff --git a/vlib/v/gen/c/struct.v b/vlib/v/gen/c/struct.v index 297431e0ea3bee..e4be451c79608d 100644 --- a/vlib/v/gen/c/struct.v +++ b/vlib/v/gen/c/struct.v @@ -471,23 +471,11 @@ fn (mut g Gen) zero_struct_field(field ast.StructField) bool { tmp_var) return true } else if final_sym.info is ast.ArrayFixed && field.default_expr !is ast.ArrayInit { - tmp_var := g.new_tmp_var() - s := g.go_before_last_stmt() - g.empty_line = true - styp := g.styp(field.typ) - g.writeln('${styp} ${tmp_var} = {0};') - g.write('memcpy(${tmp_var}, ') - g.expr(field.default_expr) - g.writeln(', sizeof(${styp}));') - g.empty_line = false - g.write2(s, '{') - for i in 0 .. final_sym.info.size { - g.write('${tmp_var}[${i}]') - if i != final_sym.info.size - 1 { - g.write(', ') - } - } - g.write('}') + old_inside_memset := g.inside_memset + g.inside_memset = true + tmp_var := g.expr_with_var(field.default_expr, field.default_expr_typ, true) + g.fixed_array_var_init(tmp_var, false, final_sym.info.elem_type, final_sym.info.size) + g.inside_memset = old_inside_memset return true } g.expr(field.default_expr) @@ -696,13 +684,14 @@ fn (mut g Gen) struct_init_field(sfield ast.StructInitField, language ast.Langua field_unwrap_sym.info.elem_type, field_unwrap_sym.info.size) } ast.CastExpr, ast.CallExpr { - tmp_var := g.expr_with_var(sfield.expr, sfield.expected_type) + tmp_var := g.expr_with_var(sfield.expr, sfield.expected_type, false) 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.expected_type) + tmp_var := g.expr_with_var(sfield.expr, sfield.expected_type, + false) g.fixed_array_var_init(tmp_var, false, field_unwrap_sym.info.elem_type, field_unwrap_sym.info.size) } else if sfield.expr.has_callexpr { diff --git a/vlib/v/tests/fixed_array_update_expr_test.v b/vlib/v/tests/fixed_array_update_expr_test.v index 8a16d9fb72f4e8..1ce4fb16e33543 100644 --- a/vlib/v/tests/fixed_array_update_expr_test.v +++ b/vlib/v/tests/fixed_array_update_expr_test.v @@ -1,6 +1,7 @@ module main -type Mat4 = [3]f32 +type Mat22 = [2][2]f32 +type Mat4 = [4]f32 @[heap] struct Game { @@ -11,7 +12,8 @@ mut: @[heap] struct GameObject { mut: - transform Mat4 = Mat4([f32(1), 2, 3]!) + transform Mat22 = Mat22([[f32(1), 2]!, [f32(3), 4]!]!) + transform2 Mat4 = Mat4([f32(1), 2, 3, 4]!) } fn (mut gameobject GameObject) instance() &GameObject { @@ -23,5 +25,7 @@ fn (mut gameobject GameObject) instance() &GameObject { fn test_main() { mut v := GameObject{} mut v2 := v.instance() - assert v2.transform == Mat4([f32(1), 2, 3]!) + dump(v) + assert v2.transform == Mat22([[f32(1), 2]!, [f32(3), 4]!]!) + assert v2.transform2 == Mat4([f32(1), 2, 3, 4]!) }