mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: minor refactor - reduce repeated code (#16886)
This commit is contained in:
parent
de2ed7497a
commit
7fa7fec304
@ -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(')
|
||||
|
@ -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 {}
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
|
@ -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' {
|
||||
|
@ -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--
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
'.'
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user