@@ -1308,22 +1308,33 @@ fn (mut g Gen) gen_array_contains(left_type ast.Type, left ast.Expr, right_type
13081308 g.write (')' )
13091309}
13101310
1311- fn (mut g Gen) get_array_index_method (typ ast.Type) string {
1311+ fn (mut g Gen) get_array_index_method (typ ast.Type, is_last_index bool ) string {
13121312 t := g.unwrap_generic (typ).set_nr_muls (0 )
1313- g.array_index_types << t
1314- return g.styp (t) + '_index'
1313+ return if is_last_index {
1314+ g.array_last_index_types << t
1315+ g.styp (t) + '_last_index'
1316+ } else {
1317+ g.array_index_types << t
1318+ g.styp (t) + '_index'
1319+ }
13151320}
13161321
1317- fn (mut g Gen) gen_array_index_methods () {
1322+ fn (mut g Gen) gen_array_index_methods (is_last_index bool ) {
13181323 mut done := []ast.Type{}
1319- for t in g.array_index_types {
1320- if t in done || g.table.sym (t).has_method ('index' ) {
1324+ indxe_types := if is_last_index { g.array_last_index_types } else { g.array_index_types }
1325+ for t in indxe_types {
1326+ if t in done || (is_last_index && g.table.sym (t).has_method ('last_index' ))
1327+ || (! is_last_index && g.table.sym (t).has_method ('index' )) {
13211328 continue
13221329 }
13231330 done << t
13241331 final_left_sym := g.table.final_sym (t)
13251332 mut left_type_str := g.styp (t)
1326- fn_name := '${left_type_str }_index'
1333+ fn_name := if is_last_index {
1334+ '${left_type_str }_last_index'
1335+ } else {
1336+ '${left_type_str }_index'
1337+ }
13271338 mut fn_builder := strings.new_builder (512 )
13281339
13291340 if final_left_sym.kind == .array {
@@ -1336,8 +1347,14 @@ fn (mut g Gen) gen_array_index_methods() {
13361347 }
13371348 g.type_definitions.writeln ('${g .static_non_parallel }${ast .int_type_name } ${fn_name }(${left_type_str } a, ${elem_type_str } v);' )
13381349 fn_builder.writeln ('${g .static_non_parallel }${ast .int_type_name } ${fn_name }(${left_type_str } a, ${elem_type_str } v) {' )
1339- fn_builder.writeln ('\t ${elem_type_str }* pelem = a.data;' )
1340- fn_builder.writeln ('\t for (${ast .int_type_name } i = 0; i < a.len; ++i, ++pelem) {' )
1350+ if is_last_index {
1351+ fn_builder.writeln ('\t if (a.len == 0) return -1;' )
1352+ fn_builder.writeln ('\t ${elem_type_str }* pelem = (${elem_type_str }*)((byte*)a.data + (a.len-1)*a.element_size);' )
1353+ fn_builder.writeln ('\t for (${ast .int_type_name } i = a.len-1; i >= 0; --i, --pelem) {' )
1354+ } else {
1355+ fn_builder.writeln ('\t ${elem_type_str }* pelem = a.data;' )
1356+ fn_builder.writeln ('\t for (${ast .int_type_name } i = 0; i < a.len; ++i, ++pelem) {' )
1357+ }
13411358 if elem_sym.kind == .string {
13421359 fn_builder.writeln ('\t\t if (builtin__fast_string_eq(*pelem, v)) {' )
13431360 } else if elem_sym.kind in [.array, .array_fixed] && ! info.elem_type.is_ptr () {
@@ -1425,8 +1442,9 @@ fn (mut g Gen) gen_array_index_methods() {
14251442}
14261443
14271444// `nums.index(2)`
1428- fn (mut g Gen) gen_array_index (node ast.CallExpr) {
1429- fn_name := g.get_array_index_method (node.left_type)
1445+ // `nums.last_index(2)`
1446+ fn (mut g Gen) gen_array_index (node ast.CallExpr, is_last_index bool ) {
1447+ fn_name := g.get_array_index_method (node.left_type, is_last_index)
14301448 left_sym := g.table.final_sym (node.left_type)
14311449 g.write ('${fn_name }(' )
14321450 if node.left_type.is_ptr () {
0 commit comments