diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index b6ea4d721f..3c5042ea3c 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -529,14 +529,7 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) { } fn (mut g Gen) gen_array_sort_call(node ast.CallExpr, compare_fn string) { - mut deref_field := if node.left_type.is_ptr() || node.left_type.is_pointer() { - '->' - } else { - '.' - } - if node.left_type.has_flag(.shared_f) { - deref_field += 'val.' - } + mut deref_field := g.dot_or_ptr(node.left_type) // eprintln('> qsort: pointer $node.left_type | deref_field: `$deref_field`') g.empty_line = true g.write('qsort(') diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 5bca367df7..2f917a0bb0 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -121,12 +121,10 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { } if mut left.obj is ast.Var { if val is ast.ComptimeSelector { - if val.field_expr is ast.SelectorExpr { - if val.field_expr.expr is ast.Ident { - key_str := '${val.field_expr.expr.name}.typ' - var_type = g.comptime_var_type_map[key_str] or { var_type } - left.obj.typ = var_type - } + key_str := g.get_comptime_selector_key_type(val) + if key_str != '' { + var_type = g.comptime_var_type_map[key_str] or { var_type } + left.obj.typ = var_type } } else if val is ast.ComptimeCall { key_str := '${val.method_name}.return_type' @@ -733,14 +731,7 @@ fn (mut g Gen) gen_cross_var_assign(node &ast.AssignStmt) { styp := g.typ(left.typ) g.write('${styp} _var_${left.pos.pos} = ') g.expr(left.expr) - mut sel := '.' - if left.expr_type.is_ptr() { - if left.expr_type.has_flag(.shared_f) { - sel = '->val.' - } else { - sel = '->' - } - } + sel := g.dot_or_ptr(left.expr_type) g.writeln('${sel}${left.field_name};') } else {} diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 0285cfa877..328f707461 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3556,11 +3556,9 @@ fn (mut g Gen) typeof_expr(node ast.TypeOf) { fn (mut g Gen) comptime_typeof(node ast.TypeOf, default_type ast.Type) ast.Type { if node.expr is ast.ComptimeSelector { - if node.expr.field_expr is ast.SelectorExpr { - if node.expr.field_expr.expr is ast.Ident { - key_str := '${node.expr.field_expr.expr.name}.typ' - return g.comptime_var_type_map[key_str] or { default_type } - } + key_str := g.get_comptime_selector_key_type(node.expr) + if key_str != '' { + return g.comptime_var_type_map[key_str] or { default_type } } } else if g.inside_comptime_for_field && node.expr is ast.Ident && (node.expr as ast.Ident).obj is ast.Var && ((node.expr as ast.Ident).obj as ast.Var).is_comptime_field == true { diff --git a/vlib/v/gen/c/comptime.v b/vlib/v/gen/c/comptime.v index 49abc56a98..1d6f1585e5 100644 --- a/vlib/v/gen/c/comptime.v +++ b/vlib/v/gen/c/comptime.v @@ -8,6 +8,15 @@ import v.ast import v.util import v.pref +fn (mut g Gen) get_comptime_selector_key_type(val ast.ComptimeSelector) string { + if val.field_expr is ast.SelectorExpr { + if val.field_expr.expr is ast.Ident { + return '${val.field_expr.expr.name}.typ' + } + } + return '' +} + fn (mut g Gen) get_comptime_selector_var_type(node ast.ComptimeSelector) (ast.StructField, string) { field_name := g.comptime_for_field_value.name left_sym := g.table.sym(g.unwrap_generic(node.left_type)) diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index cf4d32b11f..5cd23578a8 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -757,6 +757,158 @@ fn (mut g Gen) conversion_function_call(prefix string, postfix string, node ast. g.write(')${dot}_typ )${postfix}') } +[inline] +fn (mut g Gen) gen_arg_from_type(node_type ast.Type, node ast.Expr) { + if node_type.has_flag(.shared_f) { + if node_type.is_ptr() { + g.write('&') + } + g.expr(node) + g.write('->val') + } else { + if node_type.is_ptr() { + g.expr(node) + } else { + g.write('&') + g.expr(node) + } + } +} + +fn (mut g Gen) gen_map_method_call(node ast.CallExpr, left_type ast.Type, left_sym ast.TypeSymbol) bool { + match node.name { + 'delete' { + left_info := left_sym.info as ast.Map + elem_type_str := g.typ(left_info.key_type) + g.write('map_delete(') + g.gen_arg_from_type(left_type, node.left) + g.write(', &(${elem_type_str}[]){') + g.expr(node.args[0].expr) + g.write('})') + return true + } + else {} + } + return false +} + +fn (mut g Gen) gen_array_method_call(node ast.CallExpr, left_type ast.Type) bool { + match node.name { + 'filter' { + g.gen_array_filter(node) + return true + } + 'sort' { + g.gen_array_sort(node) + return true + } + 'insert' { + g.gen_array_insert(node) + return true + } + 'map' { + g.gen_array_map(node) + return true + } + 'prepend' { + g.gen_array_prepend(node) + return true + } + 'contains' { + g.gen_array_contains(left_type, node.left, node.args[0].expr) + return true + } + 'index' { + g.gen_array_index(node) + return true + } + 'wait' { + g.gen_array_wait(node) + return true + } + 'any' { + g.gen_array_any(node) + return true + } + 'all' { + g.gen_array_all(node) + return true + } + 'delete', 'drop' { + g.write('array_${node.name}(') + g.gen_arg_from_type(left_type, node.left) + g.write(', ') + g.expr(node.args[0].expr) + g.write(')') + return true + } + else {} + } + return false +} + +fn (mut g Gen) gen_to_str_method_call(node ast.CallExpr) bool { + mut rec_type := node.receiver_type + if rec_type.has_flag(.shared_f) { + rec_type = rec_type.clear_flag(.shared_f).set_nr_muls(0) + } + if node.left is ast.ComptimeSelector { + key_str := g.get_comptime_selector_key_type(node.left) + if key_str != '' { + rec_type = g.comptime_var_type_map[key_str] or { rec_type } + g.gen_expr_to_string(node.left, rec_type) + return true + } + } else if node.left is ast.ComptimeCall { + if node.left.method_name == 'method' { + sym := g.table.sym(g.unwrap_generic(node.left.left_type)) + if m := sym.find_method(g.comptime_for_method) { + rec_type = m.return_type + g.gen_expr_to_string(node.left, rec_type) + return true + } + } + } else if node.left is ast.Ident { + if node.left.obj is ast.Var { + if g.comptime_var_type_map.len > 0 { + rec_type = node.left.obj.typ + g.gen_expr_to_string(node.left, rec_type) + return true + } else if node.left.obj.smartcasts.len > 0 { + rec_type = g.unwrap_generic(node.left.obj.smartcasts.last()) + cast_sym := g.table.sym(rec_type) + if cast_sym.info is ast.Aggregate { + rec_type = cast_sym.info.types[g.aggregate_type_idx] + } + g.gen_expr_to_string(node.left, rec_type) + return true + } + } + } else if node.left is ast.None { + g.gen_expr_to_string(node.left, ast.none_type) + return true + } + g.get_str_fn(rec_type) + return false +} + +fn (mut g Gen) change_comptime_args(mut node_ ast.CallExpr) []int { + mut comptime_args := []int{} + for i, mut call_arg in node_.args { + if mut call_arg.expr is ast.Ident { + if mut call_arg.expr.obj is ast.Var { + node_.args[i].typ = call_arg.expr.obj.typ + if call_arg.expr.obj.is_comptime_field { + comptime_args << i + } + } + } else if mut call_arg.expr is ast.ComptimeSelector { + comptime_args << i + } + } + return comptime_args +} + fn (mut g Gen) method_call(node ast.CallExpr) { // TODO: there are still due to unchecked exprs (opt/some fn arg) if node.left_type == 0 { @@ -767,7 +919,6 @@ fn (mut g Gen) method_call(node ast.CallExpr) { } left_type := g.unwrap_generic(node.left_type) mut unwrapped_rec_type := node.receiver_type - mut has_comptime_field := false mut for_in_any_var_type := ast.void_type mut comptime_args := []int{} if g.cur_fn != unsafe { nil } && g.cur_fn.generic_names.len > 0 { // in generic fn @@ -790,20 +941,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) { } if g.inside_comptime_for_field { mut node_ := unsafe { node } - for i, mut call_arg in node_.args { - if mut call_arg.expr is ast.Ident { - if mut call_arg.expr.obj is ast.Var { - node_.args[i].typ = call_arg.expr.obj.typ - if call_arg.expr.obj.is_comptime_field { - has_comptime_field = true - comptime_args << i - } - } - } else if mut call_arg.expr is ast.ComptimeSelector { - has_comptime_field = true - comptime_args << i - } - } + comptime_args = g.change_comptime_args(mut node_) } if g.inside_for_in_any_cond { for call_arg in node.args { @@ -836,7 +974,6 @@ fn (mut g Gen) method_call(node ast.CallExpr) { eprintln('>>> interface typ_sym.name: ${typ_sym.name} | receiver_type_name: ${receiver_type_name} | pos: ${node.pos}') } - left_is_shared := left_type.has_flag(.shared_f) left_cc_type := g.cc_type(g.table.unaliased_type(left_type), false) left_type_name := util.no_dots(left_cc_type) g.write('${c_name(left_type_name)}_name_table[') @@ -848,13 +985,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) { } else { g.expr(node.left) } - dot := if left_is_shared { - '->val.' - } else if left_type.is_ptr() { - '->' - } else { - '.' - } + dot := g.dot_or_ptr(left_type) mname := c_name(node.name) g.write('${dot}_typ]._method_${mname}(') if node.left.is_auto_deref_var() && left_type.nr_muls() > 1 { @@ -878,186 +1009,42 @@ fn (mut g Gen) method_call(node ast.CallExpr) { left_sym := g.table.sym(left_type) final_left_sym := g.table.final_sym(left_type) if left_sym.kind == .array { + if g.gen_array_method_call(node, left_type) { + return + } + } + + if final_left_sym.kind == .map { + if g.gen_map_method_call(node, left_type, final_left_sym) { + return + } + } + + if left_sym.kind in [.sum_type, .interface_] { + prefix_name := if left_sym.kind == .sum_type { 'sumtype' } else { 'interface' } match node.name { - 'filter' { - g.gen_array_filter(node) - return + 'type_name' { + if left_sym.kind in [.sum_type, .interface_] { + g.conversion_function_call('charptr_vstring_literal( /* ${left_sym.name} */ v_typeof_${prefix_name}_${typ_sym.cname}', + ')', node) + return + } } - 'sort' { - g.gen_array_sort(node) - return - } - 'insert' { - g.gen_array_insert(node) - return - } - 'map' { - g.gen_array_map(node) - return - } - 'prepend' { - g.gen_array_prepend(node) - return - } - 'contains' { - g.gen_array_contains(left_type, node.left, node.args[0].expr) - return - } - 'index' { - g.gen_array_index(node) - return - } - 'wait' { - g.gen_array_wait(node) - return - } - 'any' { - g.gen_array_any(node) - return - } - 'all' { - g.gen_array_all(node) - return + 'type_idx' { + if left_sym.kind in [.sum_type, .interface_] { + g.conversion_function_call('/* ${left_sym.name} */ v_typeof_${prefix_name}_idx_${typ_sym.cname}', + '', node) + return + } } else {} } } - if final_left_sym.kind == .map && node.name == 'delete' { - left_info := final_left_sym.info as ast.Map - elem_type_str := g.typ(left_info.key_type) - g.write('map_delete(') - if left_type.has_flag(.shared_f) { - if left_type.is_ptr() { - g.write('&') - } - g.expr(node.left) - g.write('->val') - } else { - if left_type.is_ptr() { - g.expr(node.left) - } else { - g.write('&') - g.expr(node.left) - } - } - g.write(', &(${elem_type_str}[]){') - g.expr(node.args[0].expr) - g.write('})') - return - } else if left_sym.kind == .array && node.name == 'delete' { - g.write('array_delete(') - if left_type.has_flag(.shared_f) { - if left_type.is_ptr() { - g.write('&') - } - g.expr(node.left) - g.write('->val') - } else { - if left_type.is_ptr() { - g.expr(node.left) - } else { - g.write('&') - g.expr(node.left) - } - } - g.write(', ') - g.expr(node.args[0].expr) - g.write(')') - return - } else if left_sym.kind == .array && node.name == 'drop' { - g.write('array_drop(') - if left_type.has_flag(.shared_f) { - if left_type.is_ptr() { - g.write('&') - } - g.expr(node.left) - g.write('->val') - } else { - if left_type.is_ptr() { - g.expr(node.left) - } else { - g.write('&') - g.expr(node.left) - } - } - g.write(', ') - g.expr(node.args[0].expr) - g.write(')') - return - } - - if left_sym.kind in [.sum_type, .interface_] { - if node.name == 'type_name' { - if left_sym.kind == .sum_type { - g.conversion_function_call('charptr_vstring_literal( /* ${left_sym.name} */ v_typeof_sumtype_${typ_sym.cname}', - ')', node) - return - } - if left_sym.kind == .interface_ { - g.conversion_function_call('charptr_vstring_literal( /* ${left_sym.name} */ v_typeof_interface_${typ_sym.cname}', - ')', node) - return - } - } - if node.name == 'type_idx' { - if left_sym.kind == .sum_type { - g.conversion_function_call('/* ${left_sym.name} */ v_typeof_sumtype_idx_${typ_sym.cname}', - '', node) - return - } - if left_sym.kind == .interface_ { - g.conversion_function_call('/* ${left_sym.name} */ v_typeof_interface_idx_${typ_sym.cname}', - '', node) - return - } - } - } - if node.name == 'str' { - mut rec_type := node.receiver_type - if rec_type.has_flag(.shared_f) { - rec_type = rec_type.clear_flag(.shared_f).set_nr_muls(0) - } - if node.left is ast.ComptimeSelector { - if node.left.field_expr is ast.SelectorExpr { - if node.left.field_expr.expr is ast.Ident { - key_str := '${node.left.field_expr.expr.name}.typ' - rec_type = g.comptime_var_type_map[key_str] or { rec_type } - g.gen_expr_to_string(node.left, rec_type) - return - } - } - } else if node.left is ast.ComptimeCall { - if node.left.method_name == 'method' { - sym := g.table.sym(g.unwrap_generic(node.left.left_type)) - if m := sym.find_method(g.comptime_for_method) { - rec_type = m.return_type - g.gen_expr_to_string(node.left, rec_type) - return - } - } - } else if node.left is ast.Ident { - if node.left.obj is ast.Var { - if g.comptime_var_type_map.len > 0 { - rec_type = node.left.obj.typ - g.gen_expr_to_string(node.left, rec_type) - return - } else if node.left.obj.smartcasts.len > 0 { - rec_type = g.unwrap_generic(node.left.obj.smartcasts.last()) - cast_sym := g.table.sym(rec_type) - if cast_sym.info is ast.Aggregate { - rec_type = cast_sym.info.types[g.aggregate_type_idx] - } - g.gen_expr_to_string(node.left, rec_type) - return - } - } - } else if node.left is ast.None { - g.gen_expr_to_string(node.left, ast.none_type) + if g.gen_to_str_method_call(node) { return } - g.get_str_fn(rec_type) } else if node.name == 'free' { mut rec_type := node.receiver_type if rec_type.has_flag(.shared_f) { @@ -1096,16 +1083,10 @@ fn (mut g Gen) method_call(node ast.CallExpr) { info := left_sym.info as ast.Array noscan = g.check_noscan(info.elem_type) } - } else if left_sym.kind == .chan { - if node.name in ['close', 'try_pop', 'try_push'] { - name = 'sync__Channel_${node.name}' - } - } else if final_left_sym.kind == .map { - if node.name == 'keys' { - name = 'map_keys' - } else if node.name == 'values' { - name = 'map_values' - } + } else if left_sym.kind == .chan && node.name in ['close', 'try_pop', 'try_push'] { + name = 'sync__Channel_${node.name}' + } else if final_left_sym.kind == .map && node.name in ['keys', 'values'] { + name = 'map_${node.name}' } if g.pref.obfuscate && g.cur_mod.name == 'main' && name.starts_with('main__') && node.name != 'str' { @@ -1132,7 +1113,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) { } } - if g.comptime_for_field_type != 0 && g.inside_comptime_for_field && has_comptime_field { + if g.comptime_for_field_type != 0 && g.inside_comptime_for_field && comptime_args.len > 0 { mut concrete_types := node.concrete_types.map(g.unwrap_generic(it)) arg_sym := g.table.sym(g.comptime_for_field_type) if m := g.table.find_method(g.table.sym(node.left_type), node.name) { @@ -1272,7 +1253,6 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { // will be `0` for `foo()` mut is_interface_call := false mut is_selector_call := false - mut has_comptime_field := false mut comptime_args := []int{} if node.left_type != 0 { left_sym := g.table.sym(node.left_type) @@ -1300,20 +1280,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { } if g.inside_comptime_for_field { mut node_ := unsafe { node } - for i, mut call_arg in node_.args { - if mut call_arg.expr is ast.Ident { - if mut call_arg.expr.obj is ast.Var { - node_.args[i].typ = call_arg.expr.obj.typ - if call_arg.expr.obj.is_comptime_field { - has_comptime_field = true - comptime_args << i - } - } - } else if mut call_arg.expr is ast.ComptimeSelector { - has_comptime_field = true - comptime_args << i - } - } + comptime_args = g.change_comptime_args(mut node_) } mut name := node.name is_print := name in ['print', 'println', 'eprint', 'eprintln', 'panic'] @@ -1403,7 +1370,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { if func := g.table.find_fn(node.name) { if func.generic_names.len > 0 { if g.comptime_for_field_type != 0 && g.inside_comptime_for_field - && has_comptime_field { + && comptime_args.len > 0 { mut concrete_types := node.concrete_types.map(g.unwrap_generic(it)) arg_sym := g.table.sym(g.comptime_for_field_type) for k in comptime_args { @@ -1459,11 +1426,9 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { } else { g.write('${c_name(print_method)}(') if expr is ast.ComptimeSelector { - if expr.field_expr is ast.SelectorExpr { - if expr.field_expr.expr is ast.Ident { - key_str := '${expr.field_expr.expr.name}.typ' - typ = g.comptime_var_type_map[key_str] or { typ } - } + key_str := g.get_comptime_selector_key_type(expr) + if key_str != '' { + typ = g.comptime_var_type_map[key_str] or { typ } } } else if expr is ast.ComptimeCall { if expr.method_name == 'method' { diff --git a/vlib/v/gen/c/for.v b/vlib/v/gen/c/for.v index 5ac7cd761b..944d81755e 100644 --- a/vlib/v/gen/c/for.v +++ b/vlib/v/gen/c/for.v @@ -190,9 +190,7 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) { g.writeln(';') } i := if node.key_var in ['', '_'] { g.new_tmp_var() } else { node.key_var } - field_accessor := if node.cond_type.is_ptr() { '->' } else { '.' } - share_accessor := if node.cond_type.share() == .shared_t { 'val.' } else { '' } - op_field := field_accessor + share_accessor + op_field := g.dot_or_ptr(node.cond_type) g.empty_line = true opt_expr := '(*(${g.typ(node.cond_type.clear_flag(.optional))}*)${cond_var}${op_field}data)' cond_expr := if node.cond_type.has_flag(.optional) { @@ -293,30 +291,27 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) { g.expr(node.cond) g.writeln(';') } - mut arw_or_pt := if node.cond_type.is_ptr() { '->' } else { '.' } - if node.cond_type.has_flag(.shared_f) { - arw_or_pt = '->val.' - } + dot_or_ptr := g.dot_or_ptr(node.cond_type) idx := g.new_tmp_var() map_len := g.new_tmp_var() g.empty_line = true - g.writeln('int ${map_len} = ${cond_var}${arw_or_pt}key_values.len;') + g.writeln('int ${map_len} = ${cond_var}${dot_or_ptr}key_values.len;') g.writeln('for (int ${idx} = 0; ${idx} < ${map_len}; ++${idx} ) {') // TODO: don't have this check when the map has no deleted elements g.indent++ diff := g.new_tmp_var() - g.writeln('int ${diff} = ${cond_var}${arw_or_pt}key_values.len - ${map_len};') - g.writeln('${map_len} = ${cond_var}${arw_or_pt}key_values.len;') + g.writeln('int ${diff} = ${cond_var}${dot_or_ptr}key_values.len - ${map_len};') + g.writeln('${map_len} = ${cond_var}${dot_or_ptr}key_values.len;') // TODO: optimize this g.writeln('if (${diff} < 0) {') g.writeln('\t${idx} = -1;') g.writeln('\tcontinue;') g.writeln('}') - g.writeln('if (!DenseArray_has_index(&${cond_var}${arw_or_pt}key_values, ${idx})) {continue;}') + g.writeln('if (!DenseArray_has_index(&${cond_var}${dot_or_ptr}key_values, ${idx})) {continue;}') if node.key_var != '_' { key_styp := g.typ(node.key_type) key := c_name(node.key_var) - g.writeln('${key_styp} ${key} = /*key*/ *(${key_styp}*)DenseArray_key(&${cond_var}${arw_or_pt}key_values, ${idx});') + g.writeln('${key_styp} ${key} = /*key*/ *(${key_styp}*)DenseArray_key(&${cond_var}${dot_or_ptr}key_values, ${idx});') // TODO: analyze whether node.key_type has a .clone() method and call .clone() for all types: if node.key_type == ast.string_type { g.writeln('${key} = string_clone(${key});') @@ -327,11 +322,11 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) { if val_sym.kind == .function { g.write_fn_ptr_decl(val_sym.info as ast.FnType, c_name(node.val_var)) g.write(' = (*(voidptr*)') - g.writeln('DenseArray_value(&${cond_var}${arw_or_pt}key_values, ${idx}));') + g.writeln('DenseArray_value(&${cond_var}${dot_or_ptr}key_values, ${idx}));') } else if val_sym.kind == .array_fixed && !node.val_is_mut { val_styp := g.typ(node.val_type) g.writeln('${val_styp} ${c_name(node.val_var)};') - g.writeln('memcpy(*(${val_styp}*)${c_name(node.val_var)}, (byte*)DenseArray_value(&${cond_var}${arw_or_pt}key_values, ${idx}), sizeof(${val_styp}));') + g.writeln('memcpy(*(${val_styp}*)${c_name(node.val_var)}, (byte*)DenseArray_value(&${cond_var}${dot_or_ptr}key_values, ${idx}), sizeof(${val_styp}));') } else { val_styp := g.typ(node.val_type) if node.val_type.is_ptr() { @@ -343,7 +338,7 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) { } else { g.write('${val_styp} ${c_name(node.val_var)} = (*(${val_styp}*)') } - g.writeln('DenseArray_value(&${cond_var}${arw_or_pt}key_values, ${idx}));') + g.writeln('DenseArray_value(&${cond_var}${dot_or_ptr}key_values, ${idx}));') } } g.indent-- diff --git a/vlib/v/gen/c/match.v b/vlib/v/gen/c/match.v index 82389b35ac..d58b2dac4f 100644 --- a/vlib/v/gen/c/match.v +++ b/vlib/v/gen/c/match.v @@ -151,7 +151,7 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) { } fn (mut g Gen) match_expr_sumtype(node ast.MatchExpr, is_expr bool, cond_var string, tmp_var string) { - dot_or_ptr := if node.cond_type.is_ptr() { '->' } else { '.' } + dot_or_ptr := g.dot_or_ptr(node.cond_type) use_ternary := is_expr && tmp_var.len == 0 cond_sym := g.table.sym(node.cond_type) for j, branch in node.branches { diff --git a/vlib/v/gen/c/utils.v b/vlib/v/gen/c/utils.v index bac579a438..abf2a52424 100644 --- a/vlib/v/gen/c/utils.v +++ b/vlib/v/gen/c/utils.v @@ -106,3 +106,14 @@ fn escape_quotes(val string) string { ]) return unescaped_val.replace_each(['\x01', '${bs}${bs}', "'", "${bs}'", '"', '${bs}"']) } + +[inline] +fn (mut g Gen) dot_or_ptr(val_type ast.Type) string { + return if val_type.has_flag(.shared_f) { + '->val.' + } else if val_type.is_ptr() { + '->' + } else { + '.' + } +}