cgen: fix `array.index()` of ref struct (#7652)

pull/7659/head
yuyi 2020-12-29 01:33:57 +08:00 committed by GitHub
parent 93262353d6
commit 9631eac9c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 38 deletions

View File

@ -1278,3 +1278,15 @@ fn test_array_struct_ref_contains() {
println(exists) println(exists)
assert exists == true assert exists == true
} }
fn test_array_struct_ref_index() {
mut coords := []&Coord{}
coord_1 := &Coord{
x: 1
y: 2
z: -1
}
coords << coord_1
println(coords.index(coord_1))
assert coords.index(coord_1) == 0
}

View File

@ -393,15 +393,15 @@ fn (mut g Gen) gen_array_prepend(node ast.CallExpr) {
fn (mut g Gen) gen_array_contains_method(left_type table.Type) string { fn (mut g Gen) gen_array_contains_method(left_type table.Type) string {
mut left_sym := g.table.get_type_symbol(left_type) mut left_sym := g.table.get_type_symbol(left_type)
mut left_type_str := g.typ(left_type).replace('*', '') mut left_type_str := g.typ(left_type).replace('*', '')
left_info := left_sym.info as table.Array
mut elem_type_str := g.typ(left_info.elem_type)
elem_sym := g.table.get_type_symbol(left_info.elem_type)
if elem_sym.kind == .function {
left_type_str = 'array_voidptr'
elem_type_str = 'voidptr'
}
fn_name := '${left_type_str}_contains' fn_name := '${left_type_str}_contains'
if !left_sym.has_method('contains') { if !left_sym.has_method('contains') {
left_info := left_sym.info as table.Array
mut elem_type_str := g.typ(left_info.elem_type)
elem_sym := g.table.get_type_symbol(left_info.elem_type)
if elem_sym.kind == .function {
left_type_str = 'array_voidptr'
elem_type_str = 'voidptr'
}
g.type_definitions.writeln('static bool ${fn_name}($left_type_str a, $elem_type_str v); // auto') g.type_definitions.writeln('static bool ${fn_name}($left_type_str a, $elem_type_str v); // auto')
mut fn_builder := strings.new_builder(512) mut fn_builder := strings.new_builder(512)
fn_builder.writeln('static bool ${fn_name}($left_type_str a, $elem_type_str v) {') fn_builder.writeln('static bool ${fn_name}($left_type_str a, $elem_type_str v) {')
@ -455,42 +455,35 @@ fn (mut g Gen) gen_array_contains(node ast.CallExpr) {
fn (mut g Gen) gen_array_index_method(left_type table.Type) string { fn (mut g Gen) gen_array_index_method(left_type table.Type) string {
mut left_sym := g.table.get_type_symbol(left_type) mut left_sym := g.table.get_type_symbol(left_type)
mut left_type_str := g.typ(left_type).replace('*', '') mut left_type_str := g.typ(left_type).trim('*')
left_info := left_sym.info as table.Array
mut elem_type_str := g.typ(left_info.elem_type)
elem_sym := g.table.get_type_symbol(left_info.elem_type)
if elem_sym.kind == .function {
left_type_str = 'array_voidptr'
elem_type_str = 'voidptr'
}
fn_name := '${left_type_str}_index' fn_name := '${left_type_str}_index'
if !left_sym.has_method('index') { if !left_sym.has_method('index') {
info := left_sym.info as table.Array
mut elem_type_str := g.typ(info.elem_type)
elem_sym := g.table.get_type_symbol(info.elem_type)
if elem_sym.kind == .function {
left_type_str = 'array_voidptr'
elem_type_str = 'voidptr'
}
g.type_definitions.writeln('static int ${fn_name}($left_type_str a, $elem_type_str v); // auto') g.type_definitions.writeln('static int ${fn_name}($left_type_str a, $elem_type_str v); // auto')
mut fn_builder := strings.new_builder(512) mut fn_builder := strings.new_builder(512)
fn_builder.writeln('static int ${fn_name}($left_type_str a, $elem_type_str v) {') fn_builder.writeln('static int ${fn_name}($left_type_str a, $elem_type_str v) {')
fn_builder.writeln('\tfor (int i = 0; i < a.len; ++i) {') fn_builder.writeln('\tfor (int i = 0; i < a.len; ++i) {')
match elem_sym.kind { if elem_sym.kind == .string {
.string { fn_builder.writeln('\t\tif (string_eq((*(string*)array_get(a, i)), v)) {')
fn_builder.writeln('\t\tif (string_eq((*(string*)array_get(a, i)), v)) {') } else if elem_sym.kind == .array && !info.elem_type.is_ptr() {
} ptr_typ := g.gen_array_equality_fn(info.elem_type)
.array { fn_builder.writeln('\t\tif (${ptr_typ}_arr_eq(*($elem_type_str*)array_get(a, i), v)) {')
ptr_typ := g.gen_array_equality_fn(left_info.elem_type) } else if elem_sym.kind == .function && !info.elem_type.is_ptr() {
fn_builder.writeln('\t\tif (${ptr_typ}_arr_eq(*($elem_type_str*)array_get(a, i), v)) {') fn_builder.writeln('\t\tif ((*(voidptr*)array_get(a, i)) == v) {')
} } else if elem_sym.kind == .map && !info.elem_type.is_ptr() {
.function { ptr_typ := g.gen_map_equality_fn(info.elem_type)
fn_builder.writeln('\t\tif ((*(voidptr*)array_get(a, i)) == v) {') fn_builder.writeln('\t\tif (${ptr_typ}_map_eq(*($elem_type_str*)array_get(a, i), v)) {')
} } else if elem_sym.kind == .struct_ && !info.elem_type.is_ptr() {
.map { ptr_typ := g.gen_struct_equality_fn(info.elem_type)
ptr_typ := g.gen_map_equality_fn(left_info.elem_type) fn_builder.writeln('\t\tif (${ptr_typ}_struct_eq(*($elem_type_str*)array_get(a, i), v)) {')
fn_builder.writeln('\t\tif (${ptr_typ}_map_eq(*($elem_type_str*)array_get(a, i), v)) {') } else {
} fn_builder.writeln('\t\tif ((*($elem_type_str*)array_get(a, i)) == v) {')
.struct_ {
ptr_typ := g.gen_struct_equality_fn(left_info.elem_type)
fn_builder.writeln('\t\tif (${ptr_typ}_struct_eq(*($elem_type_str*)array_get(a, i), v)) {')
}
else {
fn_builder.writeln('\t\tif ((*($elem_type_str*)array_get(a, i)) == v) {')
}
} }
fn_builder.writeln('\t\t\treturn i;') fn_builder.writeln('\t\t\treturn i;')
fn_builder.writeln('\t\t}') fn_builder.writeln('\t\t}')
@ -503,7 +496,7 @@ fn (mut g Gen) gen_array_index_method(left_type table.Type) string {
params: [table.Param{ params: [table.Param{
typ: left_type typ: left_type
}, table.Param{ }, table.Param{
typ: left_info.elem_type typ: info.elem_type
}] }]
}) })
} }